Add new "route" mode to work around UNIDEN bugs (bug #2308)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3661 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 21 years ago
parent c22fdb7232
commit f1be7d7ffc

@ -3,9 +3,9 @@
* *
* Implementation of Session Initiation Protocol * Implementation of Session Initiation Protocol
* *
* Copyright (C) 1999, Mark Spencer * Copyright (C) 2004, Digium, Inc.
* *
* Mark Spencer <markster@linux-support.net> * Mark Spencer <markster@digium.com>
* *
* This program is free software, distributed under the terms of * This program is free software, distributed under the terms of
* the GNU General Public License * the GNU General Public License
@ -478,8 +478,9 @@ static int sip_reloading = 0;
#define REG_STATE_NOAUTH 6 #define REG_STATE_NOAUTH 6
#define SIP_NAT_NEVER 0 #define SIP_NAT_NEVER 0
#define SIP_NAT_RFC3581 1 #define SIP_NAT_RFC3581 (1 << 0)
#define SIP_NAT_ALWAYS 2 #define SIP_NAT_ROUTE (1 << 2)
#define SIP_NAT_ALWAYS (SIP_NAT_ROUTE | SIP_NAT_RFC3581)
/* sip_registry: Registrations with other SIP proxies */ /* sip_registry: Registrations with other SIP proxies */
struct sip_registry { struct sip_registry {
@ -575,7 +576,7 @@ static inline int sip_debug_test_pvt(struct sip_pvt *p)
{ {
if (sipdebug == 0) if (sipdebug == 0)
return 0; return 0;
return sip_debug_test_addr(((p->nat == SIP_NAT_ALWAYS) ? &p->recv : &p->sa)); return sip_debug_test_addr(((p->nat & SIP_NAT_ROUTE) ? &p->recv : &p->sa));
} }
@ -584,7 +585,7 @@ static int __sip_xmit(struct sip_pvt *p, char *data, int len)
{ {
int res; int res;
char iabuf[INET_ADDRSTRLEN]; char iabuf[INET_ADDRSTRLEN];
if (p->nat == SIP_NAT_ALWAYS) if (p->nat & SIP_NAT_ROUTE)
res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in)); res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->recv, sizeof(struct sockaddr_in));
else else
res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in)); res=sendto(sipsock, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_in));
@ -663,7 +664,7 @@ static int retrans_pkt(void *data)
if (pkt->retrans < MAX_RETRANS) { if (pkt->retrans < MAX_RETRANS) {
pkt->retrans++; pkt->retrans++;
if (sip_debug_test_pvt(pkt->owner)) { if (sip_debug_test_pvt(pkt->owner)) {
if (pkt->owner->nat == SIP_NAT_ALWAYS) if (pkt->owner->nat & SIP_NAT_ROUTE)
ast_verbose("Retransmitting #%d (NAT):\n%s\n to %s:%d\n", pkt->retrans, pkt->data, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port)); ast_verbose("Retransmitting #%d (NAT):\n%s\n to %s:%d\n", pkt->retrans, pkt->data, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->recv.sin_addr), ntohs(pkt->owner->recv.sin_port));
else else
ast_verbose("Retransmitting #%d (no NAT):\n%s\n to %s:%d\n", pkt->retrans, pkt->data, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port)); ast_verbose("Retransmitting #%d (no NAT):\n%s\n to %s:%d\n", pkt->retrans, pkt->data, ast_inet_ntoa(iabuf, sizeof(iabuf), pkt->owner->sa.sin_addr), ntohs(pkt->owner->sa.sin_port));
@ -863,7 +864,7 @@ static int send_response(struct sip_pvt *p, struct sip_request *req, int reliabl
struct sip_request tmp; struct sip_request tmp;
char tmpmsg[80]; char tmpmsg[80];
if (sip_debug_test_pvt(p)) { if (sip_debug_test_pvt(p)) {
if (p->nat == SIP_NAT_ALWAYS) if (p->nat & SIP_NAT_ROUTE)
ast_verbose("%sTransmitting (NAT):\n%s\n to %s:%d\n", reliable ? "Reliably " : "", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); ast_verbose("%sTransmitting (NAT):\n%s\n to %s:%d\n", reliable ? "Reliably " : "", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
else else
ast_verbose("%sTransmitting (no NAT):\n%s\n to %s:%d\n", reliable ? "Reliably " : "", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port)); ast_verbose("%sTransmitting (no NAT):\n%s\n to %s:%d\n", reliable ? "Reliably " : "", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port));
@ -896,7 +897,7 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, int reliable
struct sip_request tmp; struct sip_request tmp;
char tmpmsg[80]; char tmpmsg[80];
if (sip_debug_test_pvt(p)) { if (sip_debug_test_pvt(p)) {
if (p->nat == SIP_NAT_ALWAYS) if (p->nat & SIP_NAT_ROUTE)
ast_verbose("%sTransmitting:\n%s (NAT) to %s:%d\n", reliable ? "Reliably " : "", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port)); ast_verbose("%sTransmitting:\n%s (NAT) to %s:%d\n", reliable ? "Reliably " : "", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
else else
ast_verbose("%sTransmitting:\n%s (no NAT) to %s:%d\n", reliable ? "Reliably " : "", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port)); ast_verbose("%sTransmitting:\n%s (no NAT) to %s:%d\n", reliable ? "Reliably " : "", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port));
@ -1275,12 +1276,12 @@ static int create_addr(struct sip_pvt *r, char *opeer)
r->capability = p->capability; r->capability = p->capability;
r->nat = p->nat; r->nat = p->nat;
if (r->rtp) { if (r->rtp) {
ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (r->nat == SIP_NAT_ALWAYS)); ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (r->nat & SIP_NAT_ROUTE));
ast_rtp_setnat(r->rtp, (r->nat == SIP_NAT_ALWAYS)); ast_rtp_setnat(r->rtp, (r->nat & SIP_NAT_ROUTE));
} }
if (r->vrtp) { if (r->vrtp) {
ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (r->nat == SIP_NAT_ALWAYS)); ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (r->nat & SIP_NAT_ROUTE));
ast_rtp_setnat(r->vrtp, (r->nat == SIP_NAT_ALWAYS)); ast_rtp_setnat(r->vrtp, (r->nat & SIP_NAT_ROUTE));
} }
strncpy(r->peername, p->username, sizeof(r->peername)-1); strncpy(r->peername, p->username, sizeof(r->peername)-1);
strncpy(r->authname, p->username, sizeof(r->authname)-1); strncpy(r->authname, p->username, sizeof(r->authname)-1);
@ -2304,9 +2305,9 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg
/* Setup NAT structure according to global settings if we have an address */ /* Setup NAT structure according to global settings if we have an address */
p->nat = global_nat; p->nat = global_nat;
memcpy(&p->recv, sin, sizeof(p->recv)); memcpy(&p->recv, sin, sizeof(p->recv));
ast_rtp_setnat(p->rtp, (p->nat == SIP_NAT_ALWAYS)); ast_rtp_setnat(p->rtp, (p->nat & SIP_NAT_ROUTE));
if (p->vrtp) if (p->vrtp)
ast_rtp_setnat(p->vrtp, (p->nat == SIP_NAT_ALWAYS)); ast_rtp_setnat(p->vrtp, (p->nat & SIP_NAT_ROUTE));
} }
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
@ -3124,7 +3125,7 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, char *msg, int se
if (newbranch) { if (newbranch) {
p->branch ^= rand(); p->branch ^= rand();
if (p->nat != SIP_NAT_NEVER) if (p->nat & SIP_NAT_RFC3581)
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
else /* Some implementations (e.g. Uniden UIP200) can't handle rport being in the message!! */ else /* Some implementations (e.g. Uniden UIP200) can't handle rport being in the message!! */
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
@ -3719,7 +3720,7 @@ static int transmit_invite(struct sip_pvt *p, char *cmd, int sdp, char *auth, ch
if (init) { if (init) {
/* Bump branch even on initial requests */ /* Bump branch even on initial requests */
p->branch ^= rand(); p->branch ^= rand();
if (p->nat != SIP_NAT_NEVER) if (p->nat & SIP_NAT_RFC3581)
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
else /* Work around buggy UNIDEN UIP200 firmware */ else /* Work around buggy UNIDEN UIP200 firmware */
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
@ -4087,7 +4088,7 @@ static int transmit_register(struct sip_registry *r, char *cmd, char *auth, char
p->ocseq = r->ocseq; p->ocseq = r->ocseq;
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
if (p->nat != SIP_NAT_NEVER) if (p->nat & SIP_NAT_RFC3581)
snprintf(via, sizeof(via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(via, sizeof(via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
else /* Work around buggy UNIDEN UIP200 firmware */ else /* Work around buggy UNIDEN UIP200 firmware */
snprintf(via, sizeof(via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(via, sizeof(via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
@ -4338,7 +4339,7 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
} else } else
port = DEFAULT_SIP_PORT; port = DEFAULT_SIP_PORT;
memcpy(&oldsin, &p->addr, sizeof(oldsin)); memcpy(&oldsin, &p->addr, sizeof(oldsin));
if (p->nat != SIP_NAT_ALWAYS) { if (p->nat & SIP_NAT_RFC3581) {
/* XXX This could block for a long time XXX */ /* XXX This could block for a long time XXX */
hp = ast_gethostbyname(n, &ahp); hp = ast_gethostbyname(n, &ahp);
if (!hp) { if (!hp) {
@ -5088,9 +5089,9 @@ static int check_via(struct sip_pvt *p, struct sip_request *req)
p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT); p->sa.sin_port = htons(pt ? atoi(pt) : DEFAULT_SIP_PORT);
c = strstr(via, ";rport"); c = strstr(via, ";rport");
if (c && (c[6] != '=')) if (c && (c[6] != '='))
p->nat = SIP_NAT_ALWAYS; p->nat |= SIP_NAT_ROUTE;
if (sip_debug_test_pvt(p)) { if (sip_debug_test_pvt(p)) {
if (p->nat == SIP_NAT_ALWAYS) if (p->nat & SIP_NAT_ROUTE)
ast_verbose("Sending to %s : %d (NAT)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port)); ast_verbose("Sending to %s : %d (NAT)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port));
else else
ast_verbose("Sending to %s : %d (non-NAT)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port)); ast_verbose("Sending to %s : %d (non-NAT)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->sa.sin_addr), ntohs(p->sa.sin_port));
@ -5249,12 +5250,12 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, char *cmd
} }
if (p->rtp) { if (p->rtp) {
ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (p->nat == SIP_NAT_ALWAYS)); ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (p->nat & SIP_NAT_ROUTE));
ast_rtp_setnat(p->rtp, (p->nat == SIP_NAT_ALWAYS)); ast_rtp_setnat(p->rtp, (p->nat & SIP_NAT_ROUTE));
} }
if (p->vrtp) { if (p->vrtp) {
ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (p->nat == SIP_NAT_ALWAYS)); ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (p->nat & SIP_NAT_ROUTE));
ast_rtp_setnat(p->vrtp, (p->nat == SIP_NAT_ALWAYS)); ast_rtp_setnat(p->vrtp, (p->nat & SIP_NAT_ROUTE));
} }
if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, cmd, uri, reliable, ignore))) { if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), user->name, user->secret, user->md5secret, cmd, uri, reliable, ignore))) {
sip_cancel_destroy(p); sip_cancel_destroy(p);
@ -5324,12 +5325,12 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, char *cmd
p->ospauth = peer->ospauth; p->ospauth = peer->ospauth;
#endif #endif
if (p->rtp) { if (p->rtp) {
ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (p->nat == SIP_NAT_ALWAYS)); ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (p->nat & SIP_NAT_ROUTE));
ast_rtp_setnat(p->rtp, (p->nat == SIP_NAT_ALWAYS)); ast_rtp_setnat(p->rtp, (p->nat & SIP_NAT_ROUTE));
} }
if (p->vrtp) { if (p->vrtp) {
ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (p->nat == SIP_NAT_ALWAYS)); ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (p->nat & SIP_NAT_ROUTE));
ast_rtp_setnat(p->vrtp, (p->nat == SIP_NAT_ALWAYS)); ast_rtp_setnat(p->vrtp, (p->nat & SIP_NAT_ROUTE));
} }
strncpy(p->peersecret, peer->secret, sizeof(p->peersecret)-1); strncpy(p->peersecret, peer->secret, sizeof(p->peersecret)-1);
p->peersecret[sizeof(p->peersecret)-1] = '\0'; p->peersecret[sizeof(p->peersecret)-1] = '\0';
@ -5467,6 +5468,22 @@ static int sip_show_inuse(int fd, int argc, char *argv[]) {
#undef FORMAT2 #undef FORMAT2
} }
static char *nat2str(int nat)
{
switch(nat) {
case SIP_NAT_NEVER:
return "No";
case SIP_NAT_ROUTE:
return "Route";
case SIP_NAT_ALWAYS:
return "Always";
case SIP_NAT_RFC3581:
return "RFC3581";
default:
return "Unknown";
}
}
/*--- sip_show_users: CLI Command 'SIP Show Users' ---*/ /*--- sip_show_users: CLI Command 'SIP Show Users' ---*/
static int sip_show_users(int fd, int argc, char *argv[]) static int sip_show_users(int fd, int argc, char *argv[])
{ {
@ -5482,7 +5499,7 @@ static int sip_show_users(int fd, int argc, char *argv[])
user->accountcode, user->accountcode,
user->context, user->context,
user->ha ? "Yes" : "No", user->ha ? "Yes" : "No",
user->nat ? ((user->nat == SIP_NAT_ALWAYS) ? "Yes" : "RFC3581" ): "No"); nat2str(user->nat));
} }
ast_mutex_unlock(&userl.lock); ast_mutex_unlock(&userl.lock);
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -5526,7 +5543,7 @@ static int sip_show_peers(int fd, int argc, char *argv[])
snprintf(srch, sizeof(srch), FORMAT, name, snprintf(srch, sizeof(srch), FORMAT, name,
peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
peer->dynamic ? " D " : " ", /* Dynamic or not? */ peer->dynamic ? " D " : " ", /* Dynamic or not? */
(peer->nat == SIP_NAT_ALWAYS) ? " N " : " ", /* NAT=yes? */ (peer->nat & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
peer->ha ? " A " : " ", /* permit/deny */ peer->ha ? " A " : " ", /* permit/deny */
nm, nm,
ntohs(peer->addr.sin_port), status); ntohs(peer->addr.sin_port), status);
@ -5547,7 +5564,7 @@ static int sip_show_peers(int fd, int argc, char *argv[])
ast_cli(fd, FORMAT, name, ast_cli(fd, FORMAT, name,
peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
peer->dynamic ? " D " : " ", /* Dynamic or not? */ peer->dynamic ? " D " : " ", /* Dynamic or not? */
(peer->nat == SIP_NAT_ALWAYS) ? " N " : " ", /* NAT=yes? */ (peer->nat & SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
peer->ha ? " A " : " ", /* permit/deny */ peer->ha ? " A " : " ", /* permit/deny */
nm, nm,
ntohs(peer->addr.sin_port), status); ntohs(peer->addr.sin_port), status);
@ -5630,7 +5647,7 @@ static int sip_show_peer(int fd, int argc, char *argv[])
ast_cli(fd, " Expire : %d\n", peer->expire); ast_cli(fd, " Expire : %d\n", peer->expire);
ast_cli(fd, " Expiry : %d\n", peer->expiry); ast_cli(fd, " Expiry : %d\n", peer->expiry);
ast_cli(fd, " Insecure : %s\n", (peer->insecure?((peer->insecure == 2)?"Very":"Yes"):"No") ); ast_cli(fd, " Insecure : %s\n", (peer->insecure?((peer->insecure == 2)?"Very":"Yes"):"No") );
ast_cli(fd, " Nat : %s\n", (peer->nat?((peer->nat == SIP_NAT_ALWAYS) ? "Yes" : "RFC3581"):"No")); ast_cli(fd, " Nat : %s\n", nat2str(peer->nat));
ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No"));
ast_cli(fd, " CanReinvite : %s\n", (peer->canreinvite?"Yes":"No")); ast_cli(fd, " CanReinvite : %s\n", (peer->canreinvite?"Yes":"No"));
ast_cli(fd, " PromiscRedir : %s\n", (peer->promiscredir?"Yes":"No")); ast_cli(fd, " PromiscRedir : %s\n", (peer->promiscredir?"Yes":"No"));
@ -5834,7 +5851,7 @@ static int sip_show_channel(int fd, int argc, char *argv[])
ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) ); ast_cli(fd, " Format %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) );
ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port)); ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port));
ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port)); ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port));
ast_cli(fd, " NAT Support: %s\n", cur->nat ? ((cur->nat == SIP_NAT_ALWAYS) ? "Yes" : "RFC3581"): "No"); ast_cli(fd, " NAT Support: %s\n", nat2str(cur->nat));
ast_cli(fd, " Our Tag: %08d\n", cur->tag); ast_cli(fd, " Our Tag: %08d\n", cur->tag);
ast_cli(fd, " Their Tag: %s\n", cur->theirtag); ast_cli(fd, " Their Tag: %s\n", cur->theirtag);
ast_cli(fd, " SIP User agent: %s\n", cur->useragent); ast_cli(fd, " SIP User agent: %s\n", cur->useragent);
@ -7531,7 +7548,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer)
if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
if (p->nat != SIP_NAT_NEVER) if (p->nat & SIP_NAT_RFC3581)
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
else /* UNIDEN UIP200 bug */ else /* UNIDEN UIP200 bug */
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
@ -7747,7 +7764,7 @@ static int sip_poke_peer(struct sip_peer *peer)
if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
if (p->nat != SIP_NAT_NEVER) if (p->nat & SIP_NAT_RFC3581)
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
else else
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
@ -7869,7 +7886,7 @@ static struct ast_channel *sip_request(char *type, int format, void *data)
if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip)) if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
memcpy(&p->ourip, &__ourip, sizeof(p->ourip)); memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
if (p->nat != SIP_NAT_NEVER) if (p->nat & SIP_NAT_RFC3581)
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x;rport", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
else /* UNIDEN bug */ else /* UNIDEN bug */
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch); snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
@ -7947,6 +7964,8 @@ static struct sip_user *build_user(char *name, struct ast_variable *v)
} else if (!strcasecmp(v->name, "nat")) { } else if (!strcasecmp(v->name, "nat")) {
if (!strcasecmp(v->value, "never")) if (!strcasecmp(v->value, "never"))
user->nat = SIP_NAT_NEVER; user->nat = SIP_NAT_NEVER;
else if (!strcasecmp(v->value, "route"))
user->nat = SIP_NAT_ROUTE;
else if (ast_true(v->value)) else if (ast_true(v->value))
user->nat = SIP_NAT_ALWAYS; user->nat = SIP_NAT_ALWAYS;
else else
@ -8129,6 +8148,8 @@ static struct sip_peer *build_peer(char *name, struct ast_variable *v)
} else if (!strcasecmp(v->name, "nat")) { } else if (!strcasecmp(v->name, "nat")) {
if (!strcasecmp(v->value, "rfc3581")) if (!strcasecmp(v->value, "rfc3581"))
peer->nat = SIP_NAT_RFC3581; peer->nat = SIP_NAT_RFC3581;
else if (!strcasecmp(v->value, "route"))
peer->nat = SIP_NAT_ROUTE;
else if (ast_true(v->value)) else if (ast_true(v->value))
peer->nat = SIP_NAT_ALWAYS; peer->nat = SIP_NAT_ALWAYS;
else else
@ -8378,6 +8399,8 @@ static int reload_config(void)
} else if (!strcasecmp(v->name, "nat")) { } else if (!strcasecmp(v->name, "nat")) {
if (!strcasecmp(v->value, "rfc3581")) if (!strcasecmp(v->value, "rfc3581"))
global_nat = SIP_NAT_RFC3581; global_nat = SIP_NAT_RFC3581;
else if (!strcasecmp(v->value, "route"))
global_nat = SIP_NAT_ROUTE;
else if (ast_true(v->value)) else if (ast_true(v->value))
global_nat = SIP_NAT_ALWAYS; global_nat = SIP_NAT_ALWAYS;
else else

@ -66,6 +66,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; yes = Always ignore info and assume NAT ; yes = Always ignore info and assume NAT
; no = Use NAT mode only according to RFC3581 ; no = Use NAT mode only according to RFC3581
; never = Never attempt NAT mode or RFC3581 support ; never = Never attempt NAT mode or RFC3581 support
; route = Assume NAT, don't send rport (work around more UNIDEN bugs)
;promiscredir = no ; If yes, allows 302 or REDIR to non-local SIP address ;promiscredir = no ; If yes, allows 302 or REDIR to non-local SIP address
; ; Note that promiscredir when redirects are made to the ; ; Note that promiscredir when redirects are made to the
; ; local system will cause loops since SIP is incapable ; ; local system will cause loops since SIP is incapable

Loading…
Cancel
Save