}
} else if (o->chan && (o->chan == winner)) {
if (!ast_strlen_zero(o->chan->call_forward)) {
- char tmpchan[256];
+ char tmpchan[256]="";
+ char *stuff;
+ char *tech;
+ strncpy(tmpchan, o->chan->call_forward, sizeof(tmpchan) - 1);
+ if ((stuff = strchr(tmpchan, '/'))) {
+ *stuff = '\0';
+ stuff++;
+ tech = tmpchan;
+ } else {
+ snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
+ stuff = tmpchan;
+ tech = "Local";
+ }
/* Before processing channel, go ahead and check for forwarding */
if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s@%s' (thanks to %s)\n", in->name, o->chan->call_forward, o->chan->context, o->chan->name);
+ ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
/* Setup parameters */
- snprintf(tmpchan, sizeof(tmpchan),"%s@%s", o->chan->call_forward, o->chan->context);
ast_hangup(o->chan);
- o->chan = ast_request("Local", in->nativeformats, tmpchan);
+ o->chan = ast_request(tech, in->nativeformats, stuff);
if (!o->chan) {
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s'\n", tmpchan);
+ ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
o->stillgoing = 0;
numbusies++;
} else {
continue;
}
if (!ast_strlen_zero(tmp->chan->call_forward)) {
- char tmpchan[256];
+ char tmpchan[256]="";
+ char *stuff;
+ char *tech;
+ strncpy(tmpchan, o->chan->call_forward, sizeof(tmpchan) - 1);
+ if ((stuff = strchr(tmpchan, '/'))) {
+ *stuff = '\0';
+ stuff++;
+ tech = tmpchan;
+ } else {
+ snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
+ stuff = tmpchan;
+ tech = "Local";
+ }
+ /* Before processing channel, go ahead and check for forwarding */
if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Forwarding call to '%s@%s'\n", tmp->chan->call_forward, tmp->chan->context);
- snprintf(tmpchan, sizeof(tmpchan),"%s@%s", tmp->chan->call_forward, tmp->chan->context);
- ast_hangup(tmp->chan);
- tmp->chan = ast_request("Local", chan->nativeformats, tmpchan);
+ ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, tmp->chan->name);
+ /* Setup parameters */
+ ast_hangup(o->chan);
+ tmp->chan = ast_request(tech, in->nativeformats, stuff);
if (!tmp->chan) {
- ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s'\n", tmpchan);
+ ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
free(tmp);
cur = rest;
continue;
static int globaldtmfmode = SIP_DTMF_RFC2833; /* DTMF mode default */
static int recordhistory = 0;
+static int globalpromiscredir;
static char globalmusicclass[MAX_LANGUAGE] = ""; /* Global music on hold class */
static char global_realm[AST_MAX_EXTENSION] = "asterisk"; /* Default realm */
int subscribed;
int stateid;
int dialogver;
+ int promiscredir; /* Promiscuous redirection */
int trustrpid;
int incominglimit;
int outUse;
int outgoinglimit;
+ int promiscredir;
int restrictcid;
int trustrpid;
struct ast_ha *ha;
int canreinvite;
unsigned int callgroup;
unsigned int pickupgroup;
+ int promiscredir;
int dtmfmode;
int trustrpid;
struct sockaddr_in addr;
p->capability = capability;
p->nat = globalnat;
p->dtmfmode = globaldtmfmode;
+ p->promiscredir = globalpromiscredir;
p->insecure = 1;
p->expire = -1;
p->temponly = 1;
else
r->noncodeccapability &= ~AST_RTP_DTMF;
}
+ r->promiscredir = p->promiscredir;
strncpy(r->context, p->context,sizeof(r->context)-1);
if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
(!p->maxms || ((p->lastms > 0) && (p->lastms <= p->maxms)))) {
/* Assign default music on hold class */
strncpy(p->musicclass, globalmusicclass, sizeof(p->musicclass));
p->dtmfmode = globaldtmfmode;
+ p->promiscredir = globalpromiscredir;
p->trustrpid = globaltrustrpid;
p->rtptimeout = globalrtptimeout;
p->rtpholdtimeout = globalrtpholdtimeout;
p->restrictcid = user->restrictcid;
p->capability = user->capability;
p->jointcapability = user->capability;
+ p->promiscredir = user->promiscredir;
if (user->dtmfmode) {
p->dtmfmode = user->dtmfmode;
if (p->dtmfmode & SIP_DTMF_RFC2833)
p->pickupgroup = peer->pickupgroup;
p->capability = peer->capability;
p->jointcapability = peer->capability;
+ p->promiscredir = peer->promiscredir;
if (peer->dtmfmode) {
p->dtmfmode = peer->dtmfmode;
if (p->dtmfmode & SIP_DTMF_RFC2833)
ast_cli(fd, " Nat : %s\n", (peer->nat?"Yes":"No"));
ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No"));
ast_cli(fd, " CanReinvite : %s\n", (peer->canreinvite?"Yes":"No"));
+ ast_cli(fd, " PromiscRedir : %s\n", (peer->promiscredir?"Yes":"No"));
- /* DTMFmode is enumerated */
+ /* - is enumerated */
ast_cli(fd, " DTMFmode : ");
if (peer->dtmfmode == SIP_DTMF_RFC2833)
ast_cli(fd, "rfc2833 ");
ast_cli(fd, " Caller-ID: %s\n", cur->callerid);
ast_cli(fd, " Need Destroy: %d\n", cur->needdestroy);
ast_cli(fd, " Last Message: %s\n", cur->lastmsg);
+ ast_cli(fd, " Promiscuous Redir: %s\n", cur->promiscredir ? "Yes" : "No");
ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A");
strcpy(tmp, "");
if (cur->dtmfmode & SIP_DTMF_RFC2833)
char *s, *e;
strncpy(tmp, get_header(req, "Contact"), sizeof(tmp) - 1);
s = ditch_braces(tmp);
- e = strchr(tmp, '@');
- if (e)
- *e = '\0';
- if (!strncasecmp(s, "sip:", 4))
- s += 4;
- ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s);
- if (p->owner)
- strncpy(p->owner->call_forward, s, sizeof(p->owner->call_forward) - 1);
+ if (p->promiscredir) {
+ if (!strncasecmp(s, "sip:", 4))
+ s += 4;
+ e = strchr(s, '/');
+ if (e)
+ *e = '\0';
+ ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
+ if (p->owner)
+ snprintf(p->owner->call_forward, sizeof(p->owner->call_forward), "SIP/%s", s);
+ } else {
+ e = strchr(tmp, '@');
+ if (e)
+ *e = '\0';
+ e = strchr(tmp, '/');
+ if (e)
+ *e = '\0';
+ if (!strncasecmp(s, "sip:", 4))
+ s += 4;
+ ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s);
+ if (p->owner)
+ strncpy(p->owner->call_forward, s, sizeof(p->owner->call_forward) - 1);
+ }
}
static void check_pendings(struct sip_pvt *p)
strncpy(user->secret, v->value, sizeof(user->secret)-1);
} else if (!strcasecmp(v->name, "md5secret")) {
strncpy(user->md5secret, v->value, sizeof(user->secret)-1);
+ } else if (!strcasecmp(v->name, "promiscredir")) {
+ user->promiscredir = ast_true(v->value);
} else if (!strcasecmp(v->name, "dtmfmode")) {
if (!strcasecmp(v->value, "inband"))
user->dtmfmode=SIP_DTMF_INBAND;
/* Assume can reinvite */
peer->canreinvite = globalcanreinvite;
peer->dtmfmode = globaldtmfmode;
+ peer->promiscredir = globalpromiscredir;
peer->nat = globalnat;
peer->rtptimeout = globalrtptimeout;
peer->rtpholdtimeout = globalrtpholdtimeout;
peer->rtptimeout = globalrtptimeout;
peer->rtpholdtimeout = globalrtpholdtimeout;
peer->dtmfmode = 0;
+ peer->promiscredir = globalpromiscredir;
peer->trustrpid = globaltrustrpid;
while(v) {
if (!strcasecmp(v->name, "secret"))
strncpy(peer->context, v->value, sizeof(peer->context)-1);
else if (!strcasecmp(v->name, "fromdomain"))
strncpy(peer->fromdomain, v->value, sizeof(peer->fromdomain)-1);
+ else if (!strcasecmp(v->name, "promiscredir"))
+ peer->promiscredir = ast_true(v->value);
else if (!strcasecmp(v->name, "fromuser"))
strncpy(peer->fromuser, v->value, sizeof(peer->fromuser)-1);
else if (!strcasecmp(v->name, "dtmfmode")) {
int oldport = ntohs(bindaddr.sin_port);
globaldtmfmode = SIP_DTMF_RFC2833;
+ globalpromiscredir = 0;
if (gethostname(ourhost, sizeof(ourhost))) {
ast_log(LOG_WARNING, "Unable to get hostname, SIP disabled\n");
ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", useragent);
} else if (!strcasecmp(v->name, "relaxdtmf")) {
relaxdtmf = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "promiscredir")) {
+ globalpromiscredir = ast_true(v->value);
} else if (!strcasecmp(v->name, "dtmfmode")) {
if (!strcasecmp(v->value, "inband"))
globaldtmfmode=SIP_DTMF_INBAND;