aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authormnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b>2009-09-30 22:36:54 +0000
committermnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b>2009-09-30 22:36:54 +0000
commit9ef4ae01fdf22a31d7cfef2697877ddfb782fadd (patch)
treed508fa66944a42d1320df42471e0c3efbbf36dcd /channels
parentf83de494325b01669c3693eb3dcc26938450c3d6 (diff)
Merged revisions 221432 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ................ r221432 | mnicholson | 2009-09-30 15:40:20 -0500 (Wed, 30 Sep 2009) | 17 lines Merged revisions 221360 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r221360 | mnicholson | 2009-09-30 14:36:06 -0500 (Wed, 30 Sep 2009) | 10 lines Fix SRV lookup and Request-URI generation in chan_sip. This patch adds a new field "portinuri" to the sip dialog struct and the sip peer struct. That field is used during RURI generation to determine if the port should be included in the RURI. It is also used in some places to determine if an SRV lookup should occur. (closes issue #14418) Reported by: klaus3000 Tested by: klaus3000, mnicholson Review: https://reviewboard.asterisk.org/r/369/ ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.1@221478 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 688ff81ef..95293be3b 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1319,6 +1319,7 @@ struct sip_pvt {
int sessionversion; /*!< SDP Session Version */
int64_t sessionversion_remote; /*!< Remote UA's SDP Session Version */
int session_modify; /*!< Session modification request true/false */
+ int portinuri:1; /*!< Non zero if a port has been specified, will also disable srv lookups */
struct sockaddr_in sa; /*!< Our peer */
struct sockaddr_in redirip; /*!< Where our RTP should be going if not to us */
struct sockaddr_in vredirip; /*!< Where our Video RTP should be going if not to us */
@@ -1559,6 +1560,7 @@ struct sip_peer {
struct ast_dnsmgr_entry *dnsmgr;/*!< DNS refresh manager for peer */
struct sockaddr_in addr; /*!< IP address of peer */
int maxcallbitrate; /*!< Maximum Bitrate for a video call */
+ int portinuri:1; /*!< Whether the port should be included in the URI */
/* Qualification */
struct sip_pvt *call; /*!< Call pointer */
@@ -2684,11 +2686,15 @@ static int proxy_update(struct sip_proxy *proxy)
* pt buffer is provided or the pt has errors when being converted
* to an int value, the port provided as the standard is used.
*/
-static int port_str2int(const char *pt, unsigned int standard)
+static int port_str2int(const char *pt, unsigned int standard, int *found_port)
{
int port = standard;
if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) {
port = standard;
+ if (found_port)
+ *found_port = 0;
+ } else if (found_port) {
+ *found_port = 1;
}
return port;
@@ -2708,7 +2714,7 @@ static struct sip_proxy *proxy_allocate(char *name, char *port, int force)
return NULL;
proxy->force = force;
ast_copy_string(proxy->name, name, sizeof(proxy->name));
- proxy->ip.sin_port = htons(port_str2int(port, STANDARD_SIP_PORT));
+ proxy->ip.sin_port = htons(port_str2int(port, STANDARD_SIP_PORT, NULL));
proxy_update(proxy);
return proxy;
}
@@ -4614,6 +4620,8 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
dialog->noncodeccapability &= ~AST_RTP_DTMF;
if (peer->call_limit)
ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
+ if (!dialog->portinuri)
+ dialog->portinuri = peer->portinuri;
return 0;
}
@@ -4634,8 +4642,10 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
ast_copy_string(peername, opeer, sizeof(peername));
port = strchr(peername, ':');
- if (port)
+ if (port) {
*port++ = '\0';
+ dialog->portinuri = 1;
+ }
dialog->sa.sin_family = AF_INET;
dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
@@ -4667,7 +4677,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
/* This address should be updated using dnsmgr */
memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr));
if (!sin->sin_port) {
- portno = port_str2int(port, (dialog->socket.type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
+ portno = port_str2int(port, (dialog->socket.type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT, NULL);
} else {
portno = ntohs(sin->sin_port);
}
@@ -4694,7 +4704,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd
}
}
if (!portno)
- portno = port_str2int(port, (dialog->socket.type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
+ portno = port_str2int(port, (dialog->socket.type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT, NULL);
hp = ast_gethostbyname(hostn, &ahp);
if (!hp) {
ast_log(LOG_WARNING, "No such host: %s\n", peername);
@@ -9671,7 +9681,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
ast_str_append(&invite, 0, "%s@", n);
}
ast_str_append(&invite, 0, "%s", p->tohost);
- if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
+ if (p->portinuri)
ast_str_append(&invite, 0, ":%d", ntohs(p->sa.sin_port));
ast_str_append(&invite, 0, "%s", urioptions);
}
@@ -10785,6 +10795,7 @@ static int expire_register(const void *data)
return 0;
peer->expire = -1;
+ peer->portinuri = 0;
memset(&peer->addr, 0, sizeof(peer->addr));
destroy_association(peer); /* remove registration data from storage */
@@ -10936,9 +10947,9 @@ static int __set_address_from_contact(const char *fullcontact, struct sockaddr_i
/* set port */
if (((get_transport_str2enum(transport) == SIP_TRANSPORT_TLS)) || !(strncasecmp(fullcontact, "sips", 4))) {
- port = port_str2int(pt, STANDARD_TLS_PORT);
+ port = port_str2int(pt, STANDARD_TLS_PORT, NULL);
} else {
- port = port_str2int(pt, STANDARD_SIP_PORT);
+ port = port_str2int(pt, STANDARD_SIP_PORT, NULL);
}
/* XXX This could block for a long time XXX */
@@ -10977,6 +10988,7 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
int expire = atoi(expires);
char *curi, *host, *pt, *transport;
int port;
+ int portinuri;
int transport_type;
const char *useragent;
struct hostent *hp;
@@ -11030,6 +11042,7 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
peer->useragent[0] = '\0';
peer->sipoptions = 0;
peer->lastms = 0;
+ peer->portinuri = 0;
pvt->expiry = 0;
ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
@@ -11055,11 +11068,12 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
* default port to match the specified transport. This may or may not be the
* same transport used by the pvt struct for the Register dialog. */
- port = port_str2int(pt, (transport_type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
+ port = port_str2int(pt, (transport_type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT, &portinuri);
} else {
- port = port_str2int(pt, STANDARD_SIP_PORT);
+ port = port_str2int(pt, STANDARD_SIP_PORT, &portinuri);
transport_type = pvt->socket.type;
}
+ peer->portinuri = portinuri;
/* if the peer's socket type is different than the Registration
* transport type, change it. If it got this far, it is a
@@ -12520,7 +12534,7 @@ static void check_via(struct sip_pvt *p, struct sip_request *req)
memset(&p->sa, 0, sizeof(p->sa));
p->sa.sin_family = AF_INET;
memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
- p->sa.sin_port = htons(port_str2int(pt, STANDARD_SIP_PORT));
+ p->sa.sin_port = htons(port_str2int(pt, STANDARD_SIP_PORT, NULL));
if (sip_debug_test_pvt(p)) {
const struct sockaddr_in *dst = sip_real_dst(p);
@@ -22148,6 +22162,9 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
/* XXX should unregister ? */
}
+ if (found)
+ peer->portinuri = 0;
+
/* If we have realm authentication information, remove them (reload) */
clear_realm_authentication(peer->auth);
peer->auth = NULL;
@@ -22291,6 +22308,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
}
} else if (!strcasecmp(v->name, "port")) {
+ peer->portinuri = 1;
if (!realtime && peer->host_dynamic) {
peer->defaddr.sin_port = htons(atoi(v->value));
} else {
@@ -22533,7 +22551,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
snprintf(transport, sizeof(transport), "_sip._%s", get_transport(peer->socket.type));
- if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, global_srvlookup ? transport : NULL)) {
+ if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, global_srvlookup && !peer->portinuri ? transport : NULL)) {
ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
unref_peer(peer, "getting rid of a peer pointer");
return NULL;