mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 04:11:08 +00:00
do all sip registry parsing before transmit_register
This patch breaks up every part of the sip registry string during config parsing and removes all parsing from transmit_register(). Thanks to Nick_Lewis for contributing this patch! (closes issue #14331) Reported by: Nick_Lewis Patches: chan_sip.c-domparse.patch uploaded by Nick Lewis (license 657) chan_sip.c.patch uploaded by Nick Lewis (license 657) chan_sip.c.domainparse3.patch uploaded by Nick Lewis (license 657) chan_sip.c-domparse4.patch uploaded by Nick Lewis (license 657) chan_sip.c-domparse5.patch uploaded by Nick Lewis (license 657) nicklewispatch.diff uploaded by dvossel (license 671) Tested by: Nick_Lewis, dvossel Review: https://reviewboard.asterisk.org/r/628/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@266090 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -719,6 +719,7 @@ static char default_language[MAX_LANGUAGE]; /*!< Default language setting f
|
||||
static char default_callerid[AST_MAX_EXTENSION]; /*!< Default caller ID for sip messages */
|
||||
static char default_mwi_from[80]; /*!< Default caller ID for MWI updates */
|
||||
static char default_fromdomain[AST_MAX_EXTENSION]; /*!< Default domain on outound messages */
|
||||
static int default_fromdomainport; /*!< Default domain port on outbound messages */
|
||||
static char default_notifymime[AST_MAX_EXTENSION]; /*!< Default MIME media type for MWI notify messages */
|
||||
static char default_vmexten[AST_MAX_EXTENSION]; /*!< Default From Username on MWI updates */
|
||||
static int default_qualify; /*!< Default Qualify= setting */
|
||||
@@ -4813,8 +4814,9 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
|
||||
ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
|
||||
if (!dialog->portinuri)
|
||||
dialog->portinuri = peer->portinuri;
|
||||
|
||||
dialog->chanvars = copy_vars(peer->chanvars);
|
||||
if (peer->fromdomainport)
|
||||
dialog->fromdomainport = peer->fromdomainport;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -6280,11 +6282,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
|
||||
if (title) {
|
||||
my_name = title;
|
||||
} else {
|
||||
char *port = NULL;
|
||||
my_name = ast_strdupa(i->fromdomain);
|
||||
if ((port = strchr(i->fromdomain, ':'))) {
|
||||
*port = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
sip_pvt_unlock(i);
|
||||
@@ -6911,8 +6909,10 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
|
||||
do_setnat(p);
|
||||
}
|
||||
|
||||
if (p->method != SIP_REGISTER)
|
||||
if (p->method != SIP_REGISTER) {
|
||||
ast_string_field_set(p, fromdomain, default_fromdomain);
|
||||
p->fromdomainport = default_fromdomainport;
|
||||
}
|
||||
build_via(p);
|
||||
if (!callid)
|
||||
build_callid_pvt(p);
|
||||
@@ -9216,6 +9216,7 @@ static int transmit_response_using_temp(ast_string_field callid, struct sockaddr
|
||||
}
|
||||
|
||||
ast_string_field_set(p, fromdomain, default_fromdomain);
|
||||
p->fromdomainport = default_fromdomainport;
|
||||
build_via(p);
|
||||
ast_string_field_set(p, callid, callid);
|
||||
|
||||
@@ -9487,7 +9488,7 @@ static int add_rpid(struct sip_request *req, struct sip_pvt *p)
|
||||
return 0;
|
||||
if (ast_strlen_zero(lid_name))
|
||||
lid_name = lid_num;
|
||||
fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
|
||||
fromdomain = S_OR(p->fromdomain, ast_strdupa(ast_inet_ntoa(p->ourip.sin_addr)));
|
||||
|
||||
lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 1);
|
||||
|
||||
@@ -10485,8 +10486,8 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
|
||||
l = tmp_l;
|
||||
}
|
||||
|
||||
ourport = ntohs(p->ourip.sin_port);
|
||||
if (!sip_standard_port(p->socket.type, ourport) && ast_strlen_zero(p->fromdomain))
|
||||
ourport = (p->fromdomainport) ? p->fromdomainport : ntohs(p->ourip.sin_port);
|
||||
if (!sip_standard_port(p->socket.type, ourport))
|
||||
snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag);
|
||||
else
|
||||
snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag);
|
||||
@@ -11199,7 +11200,8 @@ static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs,
|
||||
{
|
||||
struct sip_request req;
|
||||
struct ast_str *out = ast_str_alloca(500);
|
||||
int ourport = ntohs(p->ourip.sin_port);
|
||||
int ourport = (p->fromdomainport) ? p->fromdomainport : ntohs(p->ourip.sin_port);
|
||||
const char *domain = S_OR(p->fromdomain,ast_inet_ntoa(p->ourip.sin_addr));
|
||||
const char *exten = S_OR(vmexten, default_vmexten);
|
||||
|
||||
initreqprep(&req, p, SIP_NOTIFY, NULL);
|
||||
@@ -11207,19 +11209,18 @@ static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs,
|
||||
add_header(&req, "Content-Type", default_notifymime);
|
||||
ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
|
||||
|
||||
if (!ast_strlen_zero(p->fromdomain)) {
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, p->fromdomain);
|
||||
} else if (!sip_standard_port(p->socket.type, ourport)) {
|
||||
|
||||
if (!sip_standard_port(p->socket.type, ourport)) {
|
||||
if (p->socket.type == SIP_TRANSPORT_UDP) {
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), ourport);
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport);
|
||||
} else {
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), ourport, get_transport(p->socket.type));
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, get_transport(p->socket.type));
|
||||
}
|
||||
} else {
|
||||
if (p->socket.type == SIP_TRANSPORT_UDP) {
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr));
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain);
|
||||
} else {
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), get_transport(p->socket.type));
|
||||
ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, get_transport(p->socket.type));
|
||||
}
|
||||
}
|
||||
/* Cisco has a bug in the SIP stack where it can't accept the
|
||||
@@ -11530,8 +11531,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
|
||||
struct sip_pvt *p;
|
||||
struct sip_peer *peer = NULL;
|
||||
int res;
|
||||
char *fromdomain;
|
||||
char *domainport = NULL;
|
||||
int portno = 0;
|
||||
|
||||
/* exit if we are already in process with this registrar ?*/
|
||||
if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) {
|
||||
@@ -11601,12 +11601,19 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
|
||||
|
||||
/* Copy back Call-ID in case create_addr changed it */
|
||||
ast_string_field_set(r, callid, p->callid);
|
||||
|
||||
if (!r->dnsmgr && r->portno) {
|
||||
p->sa.sin_port = htons(r->portno);
|
||||
p->recv.sin_port = htons(r->portno);
|
||||
} else { /* Set registry port to the port set from the peer definition/srv or default */
|
||||
r->portno = ntohs(p->sa.sin_port);
|
||||
}
|
||||
if (!ast_strlen_zero(p->fromdomain)) {
|
||||
portno = (p->fromdomainport) ? p->fromdomainport : STANDARD_SIP_PORT;
|
||||
} else if (!ast_strlen_zero(r->regdomain)) {
|
||||
portno = (r->regdomainport) ? r->regdomainport : STANDARD_SIP_PORT;
|
||||
} else {
|
||||
portno = ntohs(p->sa.sin_port);
|
||||
}
|
||||
|
||||
ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
|
||||
r->call = dialog_ref(p, "copying dialog into registry r->call"); /* Save pointer to SIP dialog */
|
||||
p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */
|
||||
@@ -11657,55 +11664,21 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
|
||||
ast_debug(1, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout);
|
||||
}
|
||||
|
||||
if ((fromdomain = strchr(r->username, '@'))) {
|
||||
/* the domain name is just behind '@' */
|
||||
fromdomain++ ;
|
||||
/* We have a domain in the username for registration */
|
||||
snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
|
||||
if (!ast_strlen_zero(p->theirtag))
|
||||
snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
|
||||
else
|
||||
snprintf(to, sizeof(to), "<sip:%s>", r->username);
|
||||
|
||||
/* If the registration username contains '@', then the domain should be used as
|
||||
the equivalent of "fromdomain" for the registration */
|
||||
if (ast_strlen_zero(p->fromdomain)) {
|
||||
ast_string_field_set(p, fromdomain, fromdomain);
|
||||
}
|
||||
snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain,p->tohost), p->tag);
|
||||
if (!ast_strlen_zero(p->theirtag)) {
|
||||
snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, S_OR(r->regdomain,p->tohost), p->theirtag);
|
||||
} else {
|
||||
snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
|
||||
if (!ast_strlen_zero(p->theirtag))
|
||||
snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
|
||||
else
|
||||
snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
|
||||
snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, S_OR(r->regdomain,p->tohost));
|
||||
}
|
||||
|
||||
/* Fromdomain is what we are registering to, regardless of actual
|
||||
host name from SRV */
|
||||
if (!ast_strlen_zero(p->fromdomain)) {
|
||||
domainport = strrchr(p->fromdomain, ':');
|
||||
if (domainport) {
|
||||
*domainport++ = '\0'; /* trim off domainport from p->fromdomain */
|
||||
if (ast_strlen_zero(domainport))
|
||||
domainport = NULL;
|
||||
}
|
||||
if (domainport) {
|
||||
if (atoi(domainport) != STANDARD_SIP_PORT)
|
||||
snprintf(addr, sizeof(addr), "sip:%s:%s", p->fromdomain, domainport);
|
||||
else
|
||||
snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
|
||||
if (portno && portno != STANDARD_SIP_PORT) {
|
||||
snprintf(addr, sizeof(addr), "sip:%s:%d", S_OR(p->fromdomain,S_OR(r->regdomain,r->hostname)), portno);
|
||||
} else {
|
||||
if (r->portno && r->portno != STANDARD_SIP_PORT)
|
||||
snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
|
||||
else
|
||||
snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
|
||||
}
|
||||
} else {
|
||||
if (r->portno && r->portno != STANDARD_SIP_PORT)
|
||||
snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
|
||||
else
|
||||
snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
|
||||
snprintf(addr, sizeof(addr), "sip:%s", S_OR(p->fromdomain,S_OR(r->regdomain,r->hostname)));
|
||||
}
|
||||
|
||||
ast_string_field_set(p, uri, addr);
|
||||
|
||||
p->branch ^= ast_random();
|
||||
@@ -11740,7 +11713,7 @@ static int transmit_register(struct sip_registry *r, int sipmethod, const char *
|
||||
ast_debug(1, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
|
||||
ast_string_field_set(p, realm, r->realm);
|
||||
ast_string_field_set(p, nonce, r->nonce);
|
||||
ast_string_field_set(p, domain, r->domain);
|
||||
ast_string_field_set(p, domain, r->authdomain);
|
||||
ast_string_field_set(p, opaque, r->opaque);
|
||||
ast_string_field_set(p, qop, r->qop);
|
||||
p->noncecount = ++r->noncecount;
|
||||
@@ -14631,11 +14604,21 @@ static int manager_show_registry(struct mansession *s, const struct message *m)
|
||||
"Host: %s\r\n"
|
||||
"Port: %d\r\n"
|
||||
"Username: %s\r\n"
|
||||
"Domain: %s\r\n"
|
||||
"DomainPort: %d\r\n"
|
||||
"Refresh: %d\r\n"
|
||||
"State: %s\r\n"
|
||||
"RegistrationTime: %ld\r\n"
|
||||
"\r\n", idtext, iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
|
||||
iterator->username, iterator->refresh, regstate2str(iterator->regstate), (long) iterator->regtime.tv_sec);
|
||||
"\r\n",
|
||||
idtext,
|
||||
iterator->hostname,
|
||||
iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
|
||||
iterator->username,
|
||||
S_OR(iterator->regdomain,iterator->hostname),
|
||||
iterator->regdomainport ? iterator->regdomainport : STANDARD_SIP_PORT,
|
||||
iterator->refresh,
|
||||
regstate2str(iterator->regstate),
|
||||
(long) iterator->regtime.tv_sec);
|
||||
ASTOBJ_UNLOCK(iterator);
|
||||
total++;
|
||||
} while(0));
|
||||
@@ -15454,7 +15437,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
|
||||
if (!ast_strlen_zero(peer->fromuser))
|
||||
ast_cli(fd, " FromUser : %s\n", peer->fromuser);
|
||||
if (!ast_strlen_zero(peer->fromdomain))
|
||||
ast_cli(fd, " FromDomain : %s\n", peer->fromdomain);
|
||||
ast_cli(fd, " FromDomain : %s Port %d\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
|
||||
ast_cli(fd, " Callgroup : ");
|
||||
print_group(fd, peer->callgroup, 0);
|
||||
ast_cli(fd, " Pickupgroup : ");
|
||||
@@ -15566,7 +15549,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
|
||||
if (!ast_strlen_zero(peer->fromuser))
|
||||
astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
|
||||
if (!ast_strlen_zero(peer->fromdomain))
|
||||
astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
|
||||
astman_append(s, "SIP-FromDomain: %s\r\nSip-FromDomain-Port: %d\r\n", peer->fromdomain, (peer->fromdomainport) ? peer->fromdomainport : STANDARD_SIP_PORT);
|
||||
astman_append(s, "Callgroup: ");
|
||||
astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup));
|
||||
astman_append(s, "Pickupgroup: ");
|
||||
@@ -15808,6 +15791,7 @@ static char *sip_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_
|
||||
#define FORMAT2 "%-30.30s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
|
||||
#define FORMAT "%-30.30s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"
|
||||
char host[80];
|
||||
char user[80];
|
||||
char tmpdat[256];
|
||||
struct ast_tm tm;
|
||||
int counter = 0;
|
||||
@@ -15830,12 +15814,19 @@ static char *sip_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_
|
||||
ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do {
|
||||
ASTOBJ_RDLOCK(iterator);
|
||||
snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
|
||||
snprintf(user, sizeof(user), "%s", iterator->username);
|
||||
if (!ast_strlen_zero(iterator->regdomain)) {
|
||||
snprintf(tmpdat, sizeof(tmpdat), "%s", user);
|
||||
snprintf(user, sizeof(user), "%s@%s", tmpdat, iterator->regdomain);}
|
||||
if (iterator->regdomainport) {
|
||||
snprintf(tmpdat, sizeof(tmpdat), "%s", user);
|
||||
snprintf(user, sizeof(user), "%s:%d", tmpdat, iterator->regdomainport);}
|
||||
if (iterator->regtime.tv_sec) {
|
||||
ast_localtime(&iterator->regtime, &tm, NULL);
|
||||
ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
|
||||
} else
|
||||
tmpdat[0] = '\0';
|
||||
ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
|
||||
ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", user, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
|
||||
ASTOBJ_UNLOCK(iterator);
|
||||
counter++;
|
||||
} while(0));
|
||||
@@ -16037,7 +16028,11 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
|
||||
ast_cli(a->fd, " Reg. context: %s\n", S_OR(sip_cfg.regcontext, "(not set)"));
|
||||
ast_cli(a->fd, " Regexten on Qualify: %s\n", AST_CLI_YESNO(sip_cfg.regextenonqualify));
|
||||
ast_cli(a->fd, " Caller ID: %s\n", default_callerid);
|
||||
if ((default_fromdomainport) && (default_fromdomainport != STANDARD_SIP_PORT)) {
|
||||
ast_cli(a->fd, " From: Domain: %s:%d\n", default_fromdomain, default_fromdomainport);
|
||||
} else {
|
||||
ast_cli(a->fd, " From: Domain: %s\n", default_fromdomain);
|
||||
}
|
||||
ast_cli(a->fd, " Record SIP history: %s\n", AST_CLI_ONOFF(recordhistory));
|
||||
ast_cli(a->fd, " Call Events: %s\n", AST_CLI_ONOFF(sip_cfg.callevents));
|
||||
ast_cli(a->fd, " Auth. Failure Events: %s\n", AST_CLI_ONOFF(global_authfailureevents));
|
||||
@@ -17166,7 +17161,7 @@ static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header
|
||||
if (strcmp(r->nonce, p->nonce)) {
|
||||
ast_string_field_set(r, realm, p->realm);
|
||||
ast_string_field_set(r, nonce, p->nonce);
|
||||
ast_string_field_set(r, domain, p->domain);
|
||||
ast_string_field_set(r, authdomain, p->domain);
|
||||
ast_string_field_set(r, opaque, p->opaque);
|
||||
ast_string_field_set(r, qop, p->qop);
|
||||
r->noncecount = 0;
|
||||
@@ -24999,7 +24994,16 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
|
||||
} else if (!strcasecmp(v->name, "subscribecontext")) {
|
||||
ast_string_field_set(peer, subscribecontext, v->value);
|
||||
} else if (!strcasecmp(v->name, "fromdomain")) {
|
||||
char *fromdomainport;
|
||||
ast_string_field_set(peer, fromdomain, v->value);
|
||||
if ((fromdomainport = strchr(peer->fromdomain, ':'))) {
|
||||
*fromdomainport++ = '\0';
|
||||
if (!(peer->fromdomainport = port_str2int(fromdomainport, 0))) {
|
||||
ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
|
||||
}
|
||||
} else {
|
||||
peer->fromdomainport = STANDARD_SIP_PORT;
|
||||
}
|
||||
} else if (!strcasecmp(v->name, "usereqphone")) {
|
||||
ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
|
||||
} else if (!strcasecmp(v->name, "fromuser")) {
|
||||
@@ -25663,6 +25667,7 @@ static int reload_config(enum channelreloadreason reason)
|
||||
sip_cfg.default_subscribecontext[0] = '\0';
|
||||
default_language[0] = '\0';
|
||||
default_fromdomain[0] = '\0';
|
||||
default_fromdomainport = 0;
|
||||
default_qualify = DEFAULT_QUALIFY;
|
||||
default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
|
||||
ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
|
||||
@@ -25870,7 +25875,16 @@ static int reload_config(enum channelreloadreason reason)
|
||||
} else if (!strcasecmp(v->name, "mwi_from")) {
|
||||
ast_copy_string(default_mwi_from, v->value, sizeof(default_mwi_from));
|
||||
} else if (!strcasecmp(v->name, "fromdomain")) {
|
||||
char *fromdomainport;
|
||||
ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
|
||||
if ((fromdomainport = strchr(default_fromdomain, ':'))) {
|
||||
*fromdomainport++ = '\0';
|
||||
if (!(default_fromdomainport = port_str2int(fromdomainport, 0))) {
|
||||
ast_log(LOG_NOTICE, "'%s' is not a valid port number for fromdomain.\n",fromdomainport);
|
||||
}
|
||||
} else {
|
||||
default_fromdomainport = STANDARD_SIP_PORT;
|
||||
}
|
||||
} else if (!strcasecmp(v->name, "outboundproxy")) {
|
||||
int portnum;
|
||||
char *tok, *proxyname;
|
||||
|
@@ -35,6 +35,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
int sip_parse_register_line(struct sip_registry *reg, int default_expiry, const char *value, int lineno)
|
||||
{
|
||||
int portnum = 0;
|
||||
int domainport = 0;
|
||||
enum sip_transport transport = SIP_TRANSPORT_UDP;
|
||||
char buf[256] = "";
|
||||
char *userpart = NULL, *hostpart = NULL;
|
||||
@@ -53,6 +54,14 @@ int sip_parse_register_line(struct sip_registry *reg, int default_expiry, const
|
||||
AST_APP_ARG(secret);
|
||||
AST_APP_ARG(authuser);
|
||||
);
|
||||
AST_DECLARE_APP_ARGS(user2,
|
||||
AST_APP_ARG(user);
|
||||
AST_APP_ARG(domain);
|
||||
);
|
||||
AST_DECLARE_APP_ARGS(user3,
|
||||
AST_APP_ARG(authuser);
|
||||
AST_APP_ARG(domainport);
|
||||
);
|
||||
AST_DECLARE_APP_ARGS(host1,
|
||||
AST_APP_ARG(hostpart);
|
||||
AST_APP_ARG(expiry);
|
||||
@@ -166,11 +175,54 @@ int sip_parse_register_line(struct sip_registry *reg, int default_expiry, const
|
||||
*/
|
||||
AST_NONSTANDARD_RAW_ARGS(host3, host2.hostpart, ':');
|
||||
|
||||
/*!
|
||||
* pre1.peer => peer
|
||||
* pre2.transport = transport
|
||||
* user2.user => user
|
||||
* user2.domain => domain
|
||||
* user1.secret => secret
|
||||
* user1.authuser => authuser
|
||||
* host3.host => host
|
||||
* host3.port => port
|
||||
* host2.extension => extension
|
||||
* host1.expiry => expiry
|
||||
*/
|
||||
AST_NONSTANDARD_RAW_ARGS(user2, user1.userpart, '@');
|
||||
|
||||
/*!
|
||||
* pre1.peer => peer
|
||||
* pre2.transport = transport
|
||||
* user2.user => user
|
||||
* user2.domain => domain
|
||||
* user1.secret => secret
|
||||
* user3.authuser => authuser
|
||||
* user3.domainport => domainport
|
||||
* host3.host => host
|
||||
* host3.port => port
|
||||
* host2.extension => extension
|
||||
* host1.expiry => expiry
|
||||
*/
|
||||
AST_NONSTANDARD_RAW_ARGS(user3, user1.authuser, ':');
|
||||
|
||||
/* Reordering needed due to fields being [(:secret[:username])|(:regdomainport:secret:username)]
|
||||
but parsing being [secret[:username[:regdomainport]]] */
|
||||
if (user3.argc == 2) {
|
||||
char *reorder = user3.domainport;
|
||||
user3.domainport = user1.secret;
|
||||
user1.secret = user3.authuser;
|
||||
user3.authuser = reorder;
|
||||
}
|
||||
|
||||
if (host3.port) {
|
||||
if (!(portnum = port_str2int(host3.port, 0))) {
|
||||
ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", host3.port, lineno);
|
||||
}
|
||||
}
|
||||
if (user3.domainport) {
|
||||
if (!(domainport = port_str2int(user3.domainport, 0))) {
|
||||
ast_log(LOG_NOTICE, "'%s' is not a valid domain port number on line %d of sip.conf. using default.\n", user3.domainport, lineno);
|
||||
}
|
||||
}
|
||||
|
||||
/* set transport type */
|
||||
if (!pre2.transport) {
|
||||
@@ -197,15 +249,17 @@ int sip_parse_register_line(struct sip_registry *reg, int default_expiry, const
|
||||
|
||||
/* copy into sip_registry object */
|
||||
ast_string_field_set(reg, callback, ast_strip_quoted(S_OR(host2.extension, "s"), "\"", "\""));
|
||||
ast_string_field_set(reg, username, ast_strip_quoted(S_OR(user1.userpart, ""), "\"", "\""));
|
||||
ast_string_field_set(reg, username, ast_strip_quoted(S_OR(user2.user, ""), "\"", "\""));
|
||||
ast_string_field_set(reg, hostname, ast_strip_quoted(S_OR(host3.host, ""), "\"", "\""));
|
||||
ast_string_field_set(reg, authuser, ast_strip_quoted(S_OR(user1.authuser, ""), "\"", "\""));
|
||||
ast_string_field_set(reg, authuser, ast_strip_quoted(S_OR(user3.authuser, ""), "\"", "\""));
|
||||
ast_string_field_set(reg, secret, ast_strip_quoted(S_OR(user1.secret, ""), "\"", "\""));
|
||||
ast_string_field_set(reg, peername, ast_strip_quoted(S_OR(pre1.peer, ""), "\"", "\""));
|
||||
ast_string_field_set(reg, regdomain, ast_strip_quoted(S_OR(user2.domain, ""), "\"", "\""));
|
||||
|
||||
reg->transport = transport;
|
||||
reg->timeout = reg->expire = -1;
|
||||
reg->portno = portnum;
|
||||
reg->regdomainport = domainport;
|
||||
reg->callid_valid = FALSE;
|
||||
reg->ocseq = INITIAL_CSEQ;
|
||||
reg->refresh = reg->expiry = reg->configured_expiry = (host1.expiry ? atoi(ast_strip_quoted(host1.expiry, "\"", "\"")) : default_expiry);
|
||||
@@ -228,6 +282,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
const char *reg8 = "peer?name@namedomain:pass:authuser@domain:1234/extension~111";
|
||||
const char *reg9 = "peer?name:pass:authuser:1234/extension~111";
|
||||
const char *reg10 = "@domin:1234";
|
||||
const char *reg12 = "name@namedomain:4321:pass:authuser@domain";
|
||||
const char *reg13 = "name@namedomain:4321::@domain";
|
||||
|
||||
switch (cmd) {
|
||||
case TEST_INIT:
|
||||
@@ -249,6 +305,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
sip_parse_register_line(reg, default_expiry, reg1, 1) ||
|
||||
strcmp(reg->callback, "s") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "") ||
|
||||
strcmp(reg->secret, "") ||
|
||||
@@ -260,6 +317,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
reg->expiry != default_expiry ||
|
||||
reg->configured_expiry != default_expiry ||
|
||||
reg->portno != STANDARD_SIP_PORT ||
|
||||
(reg->regdomainport) ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
@@ -276,6 +334,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
sip_parse_register_line(reg, default_expiry, reg2, 1) ||
|
||||
strcmp(reg->callback, "s") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "") ||
|
||||
strcmp(reg->secret, "pass") ||
|
||||
@@ -287,6 +346,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
reg->expiry != default_expiry ||
|
||||
reg->configured_expiry != default_expiry ||
|
||||
reg->portno != STANDARD_SIP_PORT ||
|
||||
(reg->regdomainport) ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
@@ -302,7 +362,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
} else if (
|
||||
sip_parse_register_line(reg, default_expiry, reg3, 1) ||
|
||||
strcmp(reg->callback, "s") ||
|
||||
strcmp(reg->username, "name@namedomain") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "namedomain") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "authuser") ||
|
||||
strcmp(reg->secret, "pass") ||
|
||||
@@ -314,6 +375,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
reg->expiry != default_expiry ||
|
||||
reg->configured_expiry != default_expiry ||
|
||||
reg->portno != STANDARD_SIP_PORT ||
|
||||
(reg->regdomainport) ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
@@ -329,7 +391,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
} else if (
|
||||
sip_parse_register_line(reg, default_expiry, reg4, 1) ||
|
||||
strcmp(reg->callback, "extension") ||
|
||||
strcmp(reg->username, "name@namedomain") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "namedomain") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "authuser") ||
|
||||
strcmp(reg->secret, "pass") ||
|
||||
@@ -341,6 +404,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
reg->expiry != default_expiry ||
|
||||
reg->configured_expiry != default_expiry ||
|
||||
reg->portno != STANDARD_SIP_PORT ||
|
||||
(reg->regdomainport) ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
@@ -356,7 +420,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
} else if (
|
||||
sip_parse_register_line(reg, default_expiry, reg5, 1) ||
|
||||
strcmp(reg->callback, "extension") ||
|
||||
strcmp(reg->username, "name@namedomain") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "namedomain") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "authuser") ||
|
||||
strcmp(reg->secret, "pass") ||
|
||||
@@ -368,6 +433,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
reg->expiry != default_expiry ||
|
||||
reg->configured_expiry != default_expiry ||
|
||||
reg->portno != STANDARD_SIP_PORT ||
|
||||
(reg->regdomainport) ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
@@ -383,7 +449,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
} else if (
|
||||
sip_parse_register_line(reg, default_expiry, reg6, 1) ||
|
||||
strcmp(reg->callback, "extension") ||
|
||||
strcmp(reg->username, "name@namedomain") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "namedomain") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "authuser") ||
|
||||
strcmp(reg->secret, "pass") ||
|
||||
@@ -395,6 +462,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
reg->expiry != 111 ||
|
||||
reg->configured_expiry != 111 ||
|
||||
reg->portno != STANDARD_TLS_PORT ||
|
||||
(reg->regdomainport) ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
@@ -410,7 +478,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
} else if (
|
||||
sip_parse_register_line(reg, default_expiry, reg7, 1) ||
|
||||
strcmp(reg->callback, "extension") ||
|
||||
strcmp(reg->username, "name@namedomain") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "namedomain") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "authuser") ||
|
||||
strcmp(reg->secret, "pass") ||
|
||||
@@ -422,6 +491,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
reg->expiry != 111 ||
|
||||
reg->configured_expiry != 111 ||
|
||||
reg->portno != 1234 ||
|
||||
(reg->regdomainport) ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
@@ -437,7 +507,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
} else if (
|
||||
sip_parse_register_line(reg, default_expiry, reg8, 1) ||
|
||||
strcmp(reg->callback, "extension") ||
|
||||
strcmp(reg->username, "name@namedomain") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "namedomain") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "authuser") ||
|
||||
strcmp(reg->secret, "pass") ||
|
||||
@@ -449,6 +520,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
reg->expiry != 111 ||
|
||||
reg->configured_expiry != 111 ||
|
||||
reg->portno != 1234 ||
|
||||
(reg->regdomainport) ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
@@ -458,6 +530,60 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
ast_string_field_free_memory(reg);
|
||||
ast_free(reg);
|
||||
|
||||
/* ---Test reg12, add domain port --- */
|
||||
if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
|
||||
goto alloc_fail;
|
||||
} else if (
|
||||
sip_parse_register_line(reg, default_expiry, reg12, 1) ||
|
||||
strcmp(reg->callback, "s") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "namedomain") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "authuser") ||
|
||||
strcmp(reg->secret, "pass") ||
|
||||
strcmp(reg->peername, "") ||
|
||||
reg->transport != SIP_TRANSPORT_UDP ||
|
||||
reg->timeout != -1 ||
|
||||
reg->expire != -1 ||
|
||||
reg->refresh != default_expiry ||
|
||||
reg->expiry != default_expiry ||
|
||||
reg->configured_expiry != default_expiry ||
|
||||
reg->portno != STANDARD_SIP_PORT ||
|
||||
reg->regdomainport != 4321 ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
ast_test_status_update(test, "Test 12, add domain port failed.\n");
|
||||
res = AST_TEST_FAIL;
|
||||
}
|
||||
|
||||
/* ---Test reg13, domain port without secret --- */
|
||||
if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
|
||||
goto alloc_fail;
|
||||
} else if (
|
||||
sip_parse_register_line(reg, default_expiry, reg13, 1) ||
|
||||
strcmp(reg->callback, "s") ||
|
||||
strcmp(reg->username, "name") ||
|
||||
strcmp(reg->regdomain, "namedomain") ||
|
||||
strcmp(reg->hostname, "domain") ||
|
||||
strcmp(reg->authuser, "") ||
|
||||
strcmp(reg->secret, "") ||
|
||||
strcmp(reg->peername, "") ||
|
||||
reg->transport != SIP_TRANSPORT_UDP ||
|
||||
reg->timeout != -1 ||
|
||||
reg->expire != -1 ||
|
||||
reg->refresh != default_expiry ||
|
||||
reg->expiry != default_expiry ||
|
||||
reg->configured_expiry != default_expiry ||
|
||||
reg->portno != STANDARD_SIP_PORT ||
|
||||
reg->regdomainport != 4321 ||
|
||||
reg->callid_valid != FALSE ||
|
||||
reg->ocseq != INITIAL_CSEQ) {
|
||||
|
||||
ast_test_status_update(test, "Test 13, domain port without secret failed.\n");
|
||||
res = AST_TEST_FAIL;
|
||||
}
|
||||
|
||||
/* ---Test reg 9, missing domain, expected to fail --- */
|
||||
if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
|
||||
goto alloc_fail;
|
||||
@@ -483,7 +609,7 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
|
||||
/* ---Test reg 11, no registry object, expected to fail--- */
|
||||
if (!sip_parse_register_line(NULL, default_expiry, reg1, 1)) {
|
||||
ast_test_status_update(test,
|
||||
"Test 11, no registery object, expected to fail but did not.\n");
|
||||
"Test 11, no registry object, expected to fail but did not.\n");
|
||||
res = AST_TEST_FAIL;
|
||||
}
|
||||
|
||||
|
@@ -1074,6 +1074,7 @@ struct sip_pvt {
|
||||
struct offered_media offered_media[OFFERED_MEDIA_COUNT];
|
||||
struct ast_cc_config_params *cc_params;
|
||||
struct sip_epa_entry *epa_entry;
|
||||
int fromdomainport; /*!< Domain port to show in from field */
|
||||
};
|
||||
|
||||
/*! \brief sip packet - raw format for outbound packets that are sent or scheduled for transmission
|
||||
@@ -1203,6 +1204,7 @@ struct sip_peer {
|
||||
struct sip_st_cfg stimer; /*!< SIP Session-Timers */
|
||||
int timer_t1; /*!< The maximum T1 value for the peer */
|
||||
int timer_b; /*!< The maximum timer B (transaction timeouts) */
|
||||
int fromdomainport; /*!< The From: domain port */
|
||||
|
||||
/*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
|
||||
enum sip_peer_type type; /*!< Distinguish between "user" and "peer" types. This is used solely for CLI and manager commands */
|
||||
@@ -1232,7 +1234,8 @@ struct sip_registry {
|
||||
AST_STRING_FIELD(nonce); /*!< Authorization nonce */
|
||||
AST_STRING_FIELD(opaque); /*!< Opaque nonsense */
|
||||
AST_STRING_FIELD(qop); /*!< Quality of Protection, since SIP wasn't complicated enough yet. */
|
||||
AST_STRING_FIELD(domain); /*!< Authorization domain */
|
||||
AST_STRING_FIELD(authdomain); /*!< Authorization domain */
|
||||
AST_STRING_FIELD(regdomain); /*!< Registration doamin */
|
||||
AST_STRING_FIELD(username); /*!< Who we are registering as */
|
||||
AST_STRING_FIELD(authuser); /*!< Who we *authenticate* as */
|
||||
AST_STRING_FIELD(hostname); /*!< Domain or host we register to */
|
||||
@@ -1243,6 +1246,7 @@ struct sip_registry {
|
||||
);
|
||||
enum sip_transport transport; /*!< Transport for this registration UDP, TCP or TLS */
|
||||
int portno; /*!< Optional port override */
|
||||
int regdomainport; /*!< Port override for domainport */
|
||||
int expire; /*!< Sched ID of expiration */
|
||||
int configured_expiry; /*!< Configured value to use for the Expires header */
|
||||
int expiry; /*!< Negotiated value used for the Expires header */
|
||||
|
@@ -1192,12 +1192,16 @@ unsigned int __ast_app_separate_args(char *buf, char delim, int remove_chars, ch
|
||||
char *scan, *wasdelim = NULL;
|
||||
int paren = 0, quote = 0;
|
||||
|
||||
if (!buf || !array || !arraylen) {
|
||||
if (!array || !arraylen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(array, 0, arraylen * sizeof(*array));
|
||||
|
||||
if (!buf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
scan = buf;
|
||||
|
||||
for (argc = 0; *scan && (argc < arraylen - 1); argc++) {
|
||||
|
Reference in New Issue
Block a user