mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-06 12:36:58 +00:00
Add promiscuous redirect option
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3254 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -210,16 +210,27 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
|
|||||||
}
|
}
|
||||||
} else if (o->chan && (o->chan == winner)) {
|
} else if (o->chan && (o->chan == winner)) {
|
||||||
if (!ast_strlen_zero(o->chan->call_forward)) {
|
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 */
|
/* Before processing channel, go ahead and check for forwarding */
|
||||||
if (option_verbose > 2)
|
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 */
|
/* Setup parameters */
|
||||||
snprintf(tmpchan, sizeof(tmpchan),"%s@%s", o->chan->call_forward, o->chan->context);
|
|
||||||
ast_hangup(o->chan);
|
ast_hangup(o->chan);
|
||||||
o->chan = ast_request("Local", in->nativeformats, tmpchan);
|
o->chan = ast_request(tech, in->nativeformats, stuff);
|
||||||
if (!o->chan) {
|
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;
|
o->stillgoing = 0;
|
||||||
numbusies++;
|
numbusies++;
|
||||||
} else {
|
} else {
|
||||||
@@ -699,14 +710,27 @@ static int dial_exec(struct ast_channel *chan, void *data)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!ast_strlen_zero(tmp->chan->call_forward)) {
|
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)
|
if (option_verbose > 2)
|
||||||
ast_verbose(VERBOSE_PREFIX_3 "Forwarding call to '%s@%s'\n", tmp->chan->call_forward, tmp->chan->context);
|
ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, tmp->chan->name);
|
||||||
snprintf(tmpchan, sizeof(tmpchan),"%s@%s", tmp->chan->call_forward, tmp->chan->context);
|
/* Setup parameters */
|
||||||
ast_hangup(tmp->chan);
|
ast_hangup(o->chan);
|
||||||
tmp->chan = ast_request("Local", chan->nativeformats, tmpchan);
|
tmp->chan = ast_request(tech, in->nativeformats, stuff);
|
||||||
if (!tmp->chan) {
|
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);
|
free(tmp);
|
||||||
cur = rest;
|
cur = rest;
|
||||||
continue;
|
continue;
|
||||||
|
@@ -191,6 +191,7 @@ static int videosupport = 0;
|
|||||||
|
|
||||||
static int globaldtmfmode = SIP_DTMF_RFC2833; /* DTMF mode default */
|
static int globaldtmfmode = SIP_DTMF_RFC2833; /* DTMF mode default */
|
||||||
static int recordhistory = 0;
|
static int recordhistory = 0;
|
||||||
|
static int globalpromiscredir;
|
||||||
|
|
||||||
static char globalmusicclass[MAX_LANGUAGE] = ""; /* Global music on hold class */
|
static char globalmusicclass[MAX_LANGUAGE] = ""; /* Global music on hold class */
|
||||||
static char global_realm[AST_MAX_EXTENSION] = "asterisk"; /* Default realm */
|
static char global_realm[AST_MAX_EXTENSION] = "asterisk"; /* Default realm */
|
||||||
@@ -327,6 +328,7 @@ static struct sip_pvt {
|
|||||||
int subscribed;
|
int subscribed;
|
||||||
int stateid;
|
int stateid;
|
||||||
int dialogver;
|
int dialogver;
|
||||||
|
int promiscredir; /* Promiscuous redirection */
|
||||||
|
|
||||||
int trustrpid;
|
int trustrpid;
|
||||||
|
|
||||||
@@ -382,6 +384,7 @@ struct sip_user {
|
|||||||
int incominglimit;
|
int incominglimit;
|
||||||
int outUse;
|
int outUse;
|
||||||
int outgoinglimit;
|
int outgoinglimit;
|
||||||
|
int promiscredir;
|
||||||
int restrictcid;
|
int restrictcid;
|
||||||
int trustrpid;
|
int trustrpid;
|
||||||
struct ast_ha *ha;
|
struct ast_ha *ha;
|
||||||
@@ -415,6 +418,7 @@ struct sip_peer {
|
|||||||
int canreinvite;
|
int canreinvite;
|
||||||
unsigned int callgroup;
|
unsigned int callgroup;
|
||||||
unsigned int pickupgroup;
|
unsigned int pickupgroup;
|
||||||
|
int promiscredir;
|
||||||
int dtmfmode;
|
int dtmfmode;
|
||||||
int trustrpid;
|
int trustrpid;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
@@ -978,6 +982,7 @@ static struct sip_peer *mysql_peer(char *peer, struct sockaddr_in *sin)
|
|||||||
p->capability = capability;
|
p->capability = capability;
|
||||||
p->nat = globalnat;
|
p->nat = globalnat;
|
||||||
p->dtmfmode = globaldtmfmode;
|
p->dtmfmode = globaldtmfmode;
|
||||||
|
p->promiscredir = globalpromiscredir;
|
||||||
p->insecure = 1;
|
p->insecure = 1;
|
||||||
p->expire = -1;
|
p->expire = -1;
|
||||||
p->temponly = 1;
|
p->temponly = 1;
|
||||||
@@ -1106,6 +1111,7 @@ static int create_addr(struct sip_pvt *r, char *peer)
|
|||||||
else
|
else
|
||||||
r->noncodeccapability &= ~AST_RTP_DTMF;
|
r->noncodeccapability &= ~AST_RTP_DTMF;
|
||||||
}
|
}
|
||||||
|
r->promiscredir = p->promiscredir;
|
||||||
strncpy(r->context, p->context,sizeof(r->context)-1);
|
strncpy(r->context, p->context,sizeof(r->context)-1);
|
||||||
if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
|
if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
|
||||||
(!p->maxms || ((p->lastms > 0) && (p->lastms <= p->maxms)))) {
|
(!p->maxms || ((p->lastms > 0) && (p->lastms <= p->maxms)))) {
|
||||||
@@ -2089,6 +2095,7 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg
|
|||||||
/* Assign default music on hold class */
|
/* Assign default music on hold class */
|
||||||
strncpy(p->musicclass, globalmusicclass, sizeof(p->musicclass));
|
strncpy(p->musicclass, globalmusicclass, sizeof(p->musicclass));
|
||||||
p->dtmfmode = globaldtmfmode;
|
p->dtmfmode = globaldtmfmode;
|
||||||
|
p->promiscredir = globalpromiscredir;
|
||||||
p->trustrpid = globaltrustrpid;
|
p->trustrpid = globaltrustrpid;
|
||||||
p->rtptimeout = globalrtptimeout;
|
p->rtptimeout = globalrtptimeout;
|
||||||
p->rtpholdtimeout = globalrtpholdtimeout;
|
p->rtpholdtimeout = globalrtpholdtimeout;
|
||||||
@@ -4886,6 +4893,7 @@ static int check_user(struct sip_pvt *p, struct sip_request *req, char *cmd, cha
|
|||||||
p->restrictcid = user->restrictcid;
|
p->restrictcid = user->restrictcid;
|
||||||
p->capability = user->capability;
|
p->capability = user->capability;
|
||||||
p->jointcapability = user->capability;
|
p->jointcapability = user->capability;
|
||||||
|
p->promiscredir = user->promiscredir;
|
||||||
if (user->dtmfmode) {
|
if (user->dtmfmode) {
|
||||||
p->dtmfmode = user->dtmfmode;
|
p->dtmfmode = user->dtmfmode;
|
||||||
if (p->dtmfmode & SIP_DTMF_RFC2833)
|
if (p->dtmfmode & SIP_DTMF_RFC2833)
|
||||||
@@ -4946,6 +4954,7 @@ static int check_user(struct sip_pvt *p, struct sip_request *req, char *cmd, cha
|
|||||||
p->pickupgroup = peer->pickupgroup;
|
p->pickupgroup = peer->pickupgroup;
|
||||||
p->capability = peer->capability;
|
p->capability = peer->capability;
|
||||||
p->jointcapability = peer->capability;
|
p->jointcapability = peer->capability;
|
||||||
|
p->promiscredir = peer->promiscredir;
|
||||||
if (peer->dtmfmode) {
|
if (peer->dtmfmode) {
|
||||||
p->dtmfmode = peer->dtmfmode;
|
p->dtmfmode = peer->dtmfmode;
|
||||||
if (p->dtmfmode & SIP_DTMF_RFC2833)
|
if (p->dtmfmode & SIP_DTMF_RFC2833)
|
||||||
@@ -5221,8 +5230,9 @@ static int sip_show_peer(int fd, int argc, char *argv[])
|
|||||||
ast_cli(fd, " Nat : %s\n", (peer->nat?"Yes":"No"));
|
ast_cli(fd, " Nat : %s\n", (peer->nat?"Yes":"No"));
|
||||||
ast_cli(fd, " ACL : %s\n", (peer->ha?"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, " 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 : ");
|
ast_cli(fd, " DTMFmode : ");
|
||||||
if (peer->dtmfmode == SIP_DTMF_RFC2833)
|
if (peer->dtmfmode == SIP_DTMF_RFC2833)
|
||||||
ast_cli(fd, "rfc2833 ");
|
ast_cli(fd, "rfc2833 ");
|
||||||
@@ -5431,6 +5441,7 @@ static int sip_show_channel(int fd, int argc, char *argv[])
|
|||||||
ast_cli(fd, " Caller-ID: %s\n", cur->callerid);
|
ast_cli(fd, " Caller-ID: %s\n", cur->callerid);
|
||||||
ast_cli(fd, " Need Destroy: %d\n", cur->needdestroy);
|
ast_cli(fd, " Need Destroy: %d\n", cur->needdestroy);
|
||||||
ast_cli(fd, " Last Message: %s\n", cur->lastmsg);
|
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");
|
ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A");
|
||||||
strcpy(tmp, "");
|
strcpy(tmp, "");
|
||||||
if (cur->dtmfmode & SIP_DTMF_RFC2833)
|
if (cur->dtmfmode & SIP_DTMF_RFC2833)
|
||||||
@@ -5953,14 +5964,28 @@ static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
|
|||||||
char *s, *e;
|
char *s, *e;
|
||||||
strncpy(tmp, get_header(req, "Contact"), sizeof(tmp) - 1);
|
strncpy(tmp, get_header(req, "Contact"), sizeof(tmp) - 1);
|
||||||
s = ditch_braces(tmp);
|
s = ditch_braces(tmp);
|
||||||
e = strchr(tmp, '@');
|
if (p->promiscredir) {
|
||||||
if (e)
|
if (!strncasecmp(s, "sip:", 4))
|
||||||
*e = '\0';
|
s += 4;
|
||||||
if (!strncasecmp(s, "sip:", 4))
|
e = strchr(s, '/');
|
||||||
s += 4;
|
if (e)
|
||||||
ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s);
|
*e = '\0';
|
||||||
if (p->owner)
|
ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
|
||||||
strncpy(p->owner->call_forward, s, sizeof(p->owner->call_forward) - 1);
|
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)
|
static void check_pendings(struct sip_pvt *p)
|
||||||
@@ -7329,6 +7354,8 @@ static struct sip_user *build_user(char *name, struct ast_variable *v)
|
|||||||
strncpy(user->secret, v->value, sizeof(user->secret)-1);
|
strncpy(user->secret, v->value, sizeof(user->secret)-1);
|
||||||
} else if (!strcasecmp(v->name, "md5secret")) {
|
} else if (!strcasecmp(v->name, "md5secret")) {
|
||||||
strncpy(user->md5secret, v->value, sizeof(user->secret)-1);
|
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")) {
|
} else if (!strcasecmp(v->name, "dtmfmode")) {
|
||||||
if (!strcasecmp(v->value, "inband"))
|
if (!strcasecmp(v->value, "inband"))
|
||||||
user->dtmfmode=SIP_DTMF_INBAND;
|
user->dtmfmode=SIP_DTMF_INBAND;
|
||||||
@@ -7424,6 +7451,7 @@ static struct sip_peer *temp_peer(char *name)
|
|||||||
/* Assume can reinvite */
|
/* Assume can reinvite */
|
||||||
peer->canreinvite = globalcanreinvite;
|
peer->canreinvite = globalcanreinvite;
|
||||||
peer->dtmfmode = globaldtmfmode;
|
peer->dtmfmode = globaldtmfmode;
|
||||||
|
peer->promiscredir = globalpromiscredir;
|
||||||
peer->nat = globalnat;
|
peer->nat = globalnat;
|
||||||
peer->rtptimeout = globalrtptimeout;
|
peer->rtptimeout = globalrtptimeout;
|
||||||
peer->rtpholdtimeout = globalrtpholdtimeout;
|
peer->rtpholdtimeout = globalrtpholdtimeout;
|
||||||
@@ -7489,6 +7517,7 @@ static struct sip_peer *build_peer(char *name, struct ast_variable *v)
|
|||||||
peer->rtptimeout = globalrtptimeout;
|
peer->rtptimeout = globalrtptimeout;
|
||||||
peer->rtpholdtimeout = globalrtpholdtimeout;
|
peer->rtpholdtimeout = globalrtpholdtimeout;
|
||||||
peer->dtmfmode = 0;
|
peer->dtmfmode = 0;
|
||||||
|
peer->promiscredir = globalpromiscredir;
|
||||||
peer->trustrpid = globaltrustrpid;
|
peer->trustrpid = globaltrustrpid;
|
||||||
while(v) {
|
while(v) {
|
||||||
if (!strcasecmp(v->name, "secret"))
|
if (!strcasecmp(v->name, "secret"))
|
||||||
@@ -7506,6 +7535,8 @@ static struct sip_peer *build_peer(char *name, struct ast_variable *v)
|
|||||||
strncpy(peer->context, v->value, sizeof(peer->context)-1);
|
strncpy(peer->context, v->value, sizeof(peer->context)-1);
|
||||||
else if (!strcasecmp(v->name, "fromdomain"))
|
else if (!strcasecmp(v->name, "fromdomain"))
|
||||||
strncpy(peer->fromdomain, v->value, sizeof(peer->fromdomain)-1);
|
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"))
|
else if (!strcasecmp(v->name, "fromuser"))
|
||||||
strncpy(peer->fromuser, v->value, sizeof(peer->fromuser)-1);
|
strncpy(peer->fromuser, v->value, sizeof(peer->fromuser)-1);
|
||||||
else if (!strcasecmp(v->name, "dtmfmode")) {
|
else if (!strcasecmp(v->name, "dtmfmode")) {
|
||||||
@@ -7645,6 +7676,7 @@ static int reload_config(void)
|
|||||||
int oldport = ntohs(bindaddr.sin_port);
|
int oldport = ntohs(bindaddr.sin_port);
|
||||||
|
|
||||||
globaldtmfmode = SIP_DTMF_RFC2833;
|
globaldtmfmode = SIP_DTMF_RFC2833;
|
||||||
|
globalpromiscredir = 0;
|
||||||
|
|
||||||
if (gethostname(ourhost, sizeof(ourhost))) {
|
if (gethostname(ourhost, sizeof(ourhost))) {
|
||||||
ast_log(LOG_WARNING, "Unable to get hostname, SIP disabled\n");
|
ast_log(LOG_WARNING, "Unable to get hostname, SIP disabled\n");
|
||||||
@@ -7689,6 +7721,8 @@ static int reload_config(void)
|
|||||||
ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", useragent);
|
ast_log(LOG_DEBUG, "Setting User Agent Name to %s\n", useragent);
|
||||||
} else if (!strcasecmp(v->name, "relaxdtmf")) {
|
} else if (!strcasecmp(v->name, "relaxdtmf")) {
|
||||||
relaxdtmf = ast_true(v->value);
|
relaxdtmf = ast_true(v->value);
|
||||||
|
} else if (!strcasecmp(v->name, "promiscredir")) {
|
||||||
|
globalpromiscredir = ast_true(v->value);
|
||||||
} else if (!strcasecmp(v->name, "dtmfmode")) {
|
} else if (!strcasecmp(v->name, "dtmfmode")) {
|
||||||
if (!strcasecmp(v->value, "inband"))
|
if (!strcasecmp(v->value, "inband"))
|
||||||
globaldtmfmode=SIP_DTMF_INBAND;
|
globaldtmfmode=SIP_DTMF_INBAND;
|
||||||
|
@@ -59,7 +59,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
|
|||||||
; when we're on hold (must be > rtptimeout)
|
; when we're on hold (must be > rtptimeout)
|
||||||
;trustrpid = no ; If Remote-Party-ID should be trusted
|
;trustrpid = no ; If Remote-Party-ID should be trusted
|
||||||
;useragent=Asterisk PBX ; Allows you to change the user agent string
|
;useragent=Asterisk PBX ; Allows you to change the user agent string
|
||||||
|
;promiscredir = no ; If yes, allows 302 or REDIR to non-local SIP address
|
||||||
; Asterisk can register as a SIP user agent to a SIP proxy (provider)
|
; Asterisk can register as a SIP user agent to a SIP proxy (provider)
|
||||||
; Format for the register statement is:
|
; Format for the register statement is:
|
||||||
; register => user[:secret[:authuser]]@host[:port][/extension]
|
; register => user[:secret[:authuser]]@host[:port][/extension]
|
||||||
@@ -123,6 +123,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
|
|||||||
; disallow disallow
|
; disallow disallow
|
||||||
; insecure insecure
|
; insecure insecure
|
||||||
; trustrpid trustrpid
|
; trustrpid trustrpid
|
||||||
|
; promiscredir promiscredir
|
||||||
; callerid
|
; callerid
|
||||||
; accountcode
|
; accountcode
|
||||||
; amaflags
|
; amaflags
|
||||||
|
Reference in New Issue
Block a user