diff options
-rw-r--r-- | channels/chan_sip.c | 42 | ||||
-rw-r--r-- | configs/sip.conf.sample | 3 |
2 files changed, 33 insertions, 12 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 908bc80cc..a43783cdb 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1776,6 +1776,7 @@ struct sip_pvt { long branch; /*!< The branch identifier of this session */ long invite_branch; /*!< The branch used when we sent the initial INVITE */ int64_t sessionversion_remote; /*!< Remote UA's SDP Session Version */ + 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 */ @@ -2029,6 +2030,7 @@ struct sip_peer { struct sip_proxy *outboundproxy; /*!< Outbound proxy for this peer */ struct ast_dnsmgr_entry *dnsmgr;/*!< DNS refresh manager for peer */ struct sockaddr_in addr; /*!< IP address of peer */ + int portinuri:1; /*!< Whether the port should be included in the URI */ struct sip_pvt *call; /*!< Call pointer */ int pokeexpire; /*!< Qualification: When to expire poke (qualify= checking) */ int lastms; /*!< Qualification: How long last response took (in ms), or -1 for no response */ @@ -3209,11 +3211,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; @@ -3233,7 +3239,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; } @@ -5277,6 +5283,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; dialog->chanvars = copy_vars(peer->chanvars); @@ -5299,8 +5307,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) */ @@ -5335,7 +5345,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); } @@ -5362,7 +5372,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); @@ -10804,7 +10814,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); } @@ -12192,6 +12202,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 */ @@ -12343,9 +12354,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); } @@ -12390,6 +12401,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; @@ -12443,6 +12455,7 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st ast_string_field_set(peer, useragent, ""); peer->sipoptions = 0; peer->lastms = 0; + peer->portinuri = 0; pvt->expiry = 0; ast_verb(3, "Unregistered SIP '%s'\n", peer->name); @@ -12468,11 +12481,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 @@ -14145,7 +14159,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(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); @@ -24214,6 +24228,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; @@ -24365,6 +24382,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 { @@ -24620,7 +24638,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, sip_cfg.srvlookup ? transport : NULL)) { + if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.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; diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index bdd356c29..23c16979c 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -152,6 +152,9 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; Disabling DNS SRV lookups disables the ; ability to place SIP calls based on domain ; names to some other SIP users on the Internet + ; Specifying a port in a SIP peer definition or + ; when dialing outbound calls will supress SRV + ; lookups for that peer or call. ;pedantic=yes ; Enable checking of tags in headers, ; international character conversions in URIs |