diff options
author | David Vossel <dvossel@digium.com> | 2009-09-02 21:39:31 +0000 |
---|---|---|
committer | David Vossel <dvossel@digium.com> | 2009-09-02 21:39:31 +0000 |
commit | a83cf36204f0b7110ea1a15811ef21a9399f2aea (patch) | |
tree | 395d7d994594dcdcb93ac681c78a5b3cd814f9a7 | |
parent | 0a67bc66107ad8f4e6e4e48fac27882a55cd10a9 (diff) |
port string to int conversion using sscanf
There are several instances where a port is parsed
from a uri or some other source and converted to
an int value using atoi(), if for some reason the
port string is empty, then a standard port is used.
This logic is used over and over, so I created a function
to handle it in a safer way using sscanf().
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@215681 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r-- | channels/chan_sip.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 898db785c..a80a2af8e 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -3170,6 +3170,20 @@ static int proxy_update(struct sip_proxy *proxy) return TRUE; } +/*! \brief converts ascii port to int representation. If no + * 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) +{ + int port = standard; + if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 0)) { + port = standard; + } + + return port; +} + /*! \brief Allocate and initialize sip proxy */ static struct sip_proxy *proxy_allocate(char *name, char *port, int force) { @@ -3184,7 +3198,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((!ast_strlen_zero(port) ? atoi(port) : STANDARD_SIP_PORT)); + proxy->ip.sin_port = htons(port_str2int(port, STANDARD_SIP_PORT)); proxy_update(proxy); return proxy; } @@ -5229,10 +5243,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) { - if (ast_strlen_zero(port) || sscanf(port, "%30u", &portno) != 1) { - portno = (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); } else { portno = ntohs(sin->sin_port); } @@ -5259,7 +5270,7 @@ static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockadd } } if (!portno) - portno = port ? atoi(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); hp = ast_gethostbyname(hostn, &ahp); if (!hp) { ast_log(LOG_WARNING, "No such host: %s\n", peername); @@ -12204,7 +12215,6 @@ static int __set_address_from_contact(const char *fullcontact, struct sockaddr_i char *host, *pt, *transport; char contact_buf[256]; char *contact; - int use_tls = FALSE; /* Work on a copy */ ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); @@ -12215,20 +12225,20 @@ static int __set_address_from_contact(const char *fullcontact, struct sockaddr_i * * Note: The outbound proxy could be using UDP between the proxy and Asterisk. * We still need to be able to send to the remote agent through the proxy. - */ + */ - if (!parse_uri(contact, "sip,sips", &contact, NULL, &host, &pt, NULL, &transport)) { - if (((get_transport_str2enum(transport) == SIP_TRANSPORT_TLS)) || - !(strncasecmp(fullcontact, "sips", 4))) { - use_tls = TRUE; - port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_TLS_PORT; - } else { - port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_SIP_PORT; - } - } else { + if (parse_uri(contact, "sip,sips", &contact, NULL, &host, &pt, NULL, &transport)) { ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact); } + /* set port */ + if (((get_transport_str2enum(transport) == SIP_TRANSPORT_TLS)) || !(strncasecmp(fullcontact, "sips", 4))) { + port = port_str2int(pt, STANDARD_TLS_PORT); + } else { + port = port_str2int(pt, STANDARD_SIP_PORT); + } + + /* XXX This could block for a long time XXX */ /* We should only do this if it's a name, not an IP */ /* \todo - if there's no PORT number in contact - we are required to check NAPTR/SRV records @@ -12347,13 +12357,10 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st /* if the port is not specified but the transport is, make sure to set the * 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. */ - if (ast_strlen_zero(pt)) { - port = (transport_type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT; - } else { - port = atoi(pt); - } + + port = port_str2int(pt, (transport_type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT); } else { - port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_SIP_PORT; + port = port_str2int(pt, STANDARD_SIP_PORT); transport_type = pvt->socket.type; } @@ -14024,7 +14031,7 @@ static void check_via(struct sip_pvt *p, struct sip_request *req) if (pt) *pt++ = '\0'; /* remember port pointer */ p->sa = p->recv; - p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); + p->sa.sin_port = htons(port_str2int(pt, STANDARD_SIP_PORT)); if (sip_debug_test_pvt(p)) { const struct sockaddr_in *dst = sip_real_dst(p); |