Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 315497) +++ channels/chan_sip.c (working copy) @@ -7545,14 +7545,9 @@ static void free_via(struct sip_via *v) { - if (!v) { - return; - } - - if (v->via) { + if (v) { ast_free(v->via); } - ast_free(v); } @@ -7699,17 +7694,20 @@ p->sa.sin_family = AF_INET; memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); - if (via->port) { - p->sa.sin_port = via->port; - } else { - p->sa.sin_port = STANDARD_SIP_PORT; - } - if (addr_is_multicast(&p->sa.sin_addr)) { setsockopt(sipsock, IPPROTO_IP, IP_MULTICAST_TTL, &via->ttl, sizeof(via->ttl)); } } + /* rfc3263#section-5: Typically, for unicast UDP requests, the + * response is sent back to the source IP address where the request came + * from, using the port contained in the Via header. */ + if (via->port) { + p->sa.sin_port = htons(via->port); + } else { + p->sa.sin_port = htons(STANDARD_SIP_PORT); + } + free_via(via); return 0; } @@ -9919,6 +9917,7 @@ /* default to routing the response to the address where the request * came from. Since we don't have a transport layer, we do this here. + * (process_via might update only the port, as per the spec.) */ p->sa = p->recv; @@ -14344,7 +14343,7 @@ if (!strncmp(cur, "rport=", 6)) { int port = strtol(cur+6, NULL, 10); /* XXX add error checking */ - p->ourip.sin_port = ntohs(port); + p->ourip.sin_port = htons(port); } else if (!strncmp(cur, "received=", 9)) { if (ast_parse_arg(cur+9, PARSE_INADDR, &p->ourip)) ; /* XXX add error checking */