[asterisk-commits] rizzo: branch rizzo/astobj2 r75526 - /team/rizzo/astobj2/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jul 18 01:36:24 CDT 2007
Author: rizzo
Date: Wed Jul 18 01:36:23 2007
New Revision: 75526
URL: http://svn.digium.com/view/asterisk?view=rev&rev=75526
Log:
initial cleanup for better support of natted sessions
(this and subsequent changes are also strong trunk candidates):
- remove the 'ourport' variable, the same information is in bindaddr.sin_port
- change the 'ourip' field in a sip_pvt to a sockaddr_in, so it has
room to store a port number as well. Use it to store the externally
visible address/port for the SIP messages (computed using any
applicable technique, e.g. stun or "externip" or whatever);
The above reveals a lot of duplicate sections of code around
the call to ast_sip_ouraddrfor(), and also a mixed usage of 'ourip'
as the address for media sessions as well.
Remaining changes (yet to make) will need to:
- re-engineer sip_ouraddrfor() to remove the duplications;
- separate the field used to store media addresses from the
one used for SIP addresses.
- bring in proper stun support for the various sessions.
Modified:
team/rizzo/astobj2/channels/chan_sip.c
Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=75526&r1=75525&r2=75526
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Wed Jul 18 01:36:23 2007
@@ -1032,7 +1032,7 @@
time_t lastrtptx; /*!< Last RTP sent */
int rtptimeout; /*!< RTP timeout time */
struct sockaddr_in recv; /*!< Received as */
- struct in_addr ourip; /*!< Our IP */
+ struct sockaddr_in ourip; /*!< Our IP (as seen from the outside) */
struct ast_channel *owner; /*!< Who owns us (if we have an owner) */
struct sip_route *route; /*!< Head of linked list of routing steps (fm Record-Route) */
int route_persistant; /*!< Is this the "real" route? */
@@ -1404,7 +1404,6 @@
static struct ast_ha *localaddr;
static struct in_addr __ourip;
-static int ourport;
static struct sockaddr_in debugaddr;
static struct ast_config *notify_types; /*!< The list of manual NOTIFY types we know how to send */
@@ -2175,7 +2174,8 @@
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
- ast_inet_ntoa(p->ourip), ourport, p->branch, rport);
+ ast_inet_ntoa(p->ourip.sin_addr),
+ ntohs(bindaddr.sin_port), p->branch, rport);
}
/*! \brief NAT fix - decide which IP address to use for ASterisk server?
@@ -4837,7 +4837,7 @@
{
char buf[33];
- const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip));
+ const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip.sin_addr));
ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
@@ -4913,12 +4913,13 @@
if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
p->timer_t1 = SIP_TIMER_T1; /* Default SIP retransmission timer T1 (RFC 3261) */
+ p->ourip.sin_port = bindaddr.sin_port; /* XXX later, update with stun or similar */
if (sin) {
p->sa = *sin;
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+ p->ourip.sin_addr = __ourip;
} else
- p->ourip = __ourip;
+ p->ourip.sin_addr = __ourip;
/* Copy global flags to this PVT at setup. */
ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
@@ -6623,12 +6624,13 @@
/* Initialize the bare minimum */
p->method = intended_method;
+ p->ourip.sin_port = bindaddr.sin_port;
if (sin) {
p->sa = *sin;
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+ p->ourip.sin_addr = __ourip;
} else
- p->ourip = __ourip;
+ p->ourip.sin_addr = __ourip;
p->branch = ast_random();
make_our_tag(p->tag, sizeof(p->tag));
@@ -6927,12 +6929,12 @@
udptldest.sin_port = p->udptlredirip.sin_port;
udptldest.sin_addr = p->udptlredirip.sin_addr;
} else {
- udptldest.sin_addr = p->ourip;
- udptldest.sin_port = udptlsin.sin_port;
+ udptldest.sin_addr = p->ourip.sin_addr;
+ udptldest.sin_port = udptlsin.sin_port; /* XXX are we sure ? */
}
- if (debug)
- ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port));
+ if (debug) /* XXX is the message correct ? */
+ ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(udptlsin.sin_port));
/* We break with the "recommendation" and send our IP, in order that our
peer doesn't have to ast_gethostbyname() us */
@@ -7018,7 +7020,8 @@
dest->sin_port = p->redirip.sin_port;
dest->sin_addr = p->redirip.sin_addr;
} else {
- dest->sin_addr = p->ourip;
+ /* XXX need to handle NAT */
+ dest->sin_addr = p->ourip.sin_addr;
dest->sin_port = sin->sin_port;
}
if (needvideo) {
@@ -7027,7 +7030,8 @@
vdest->sin_addr = p->vredirip.sin_addr;
vdest->sin_port = p->vredirip.sin_port;
} else {
- vdest->sin_addr = p->ourip;
+ /* XXX need to handle NAT */
+ vdest->sin_addr = p->ourip.sin_addr;
vdest->sin_port = vsin->sin_port;
}
}
@@ -7117,7 +7121,7 @@
get_our_media_address(p, needvideo, &sin, &vsin, &tsin, &dest, &vdest);
if (debug)
- ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port));
+ ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(sin.sin_port));
/* Ok, we need video. Let's add what we need for video and set codecs.
Video is handled differently than audio since we can not transcode. */
@@ -7128,7 +7132,7 @@
if (p->maxcallbitrate)
snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
if (debug)
- ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));
+ ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(vsin.sin_port));
}
/* Check if we need text in this call */
if((capability & AST_FORMAT_TEXT_MASK) && !ast_test_flag(&p->flags[1], SIP_PAGE2_NOTEXT)) {
@@ -7154,13 +7158,13 @@
tdest.sin_addr = p->tredirip.sin_addr;
tdest.sin_port = p->tredirip.sin_port;
} else {
- tdest.sin_addr = p->ourip;
+ tdest.sin_addr = p->ourip.sin_addr;
tdest.sin_port = tsin.sin_port;
}
ast_str_append(&m_text, 0, "m=text %d RTP/AVP", ntohs(tdest.sin_port));
if (debug)
- ast_verbose("Text is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(tsin.sin_port));
+ ast_verbose("Text is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(tsin.sin_port));
}
/* Start building generic SDP headers */
@@ -7480,11 +7484,11 @@
/* Construct Contact: header */
char port[16];
port[0] = '\0';
- if (ourport != STANDARD_SIP_PORT)
- snprintf(port, sizeof(port), ":%6d", ourport);
+ if (ntohs(p->ourip.sin_port) != STANDARD_SIP_PORT)
+ snprintf(port, sizeof(port), ":%6d", ntohs(p->ourip.sin_port));
ast_string_field_build(p, our_contact, "<sip:%s%s%s%s>",
p->exten, ast_strlen_zero(p->exten) ? "" : "@",
- ast_inet_ntoa(p->ourip), port);
+ ast_inet_ntoa(p->ourip.sin_addr), port);
}
/*! \brief Build the Remote Party-ID & From using callingpres options */
@@ -7554,7 +7558,7 @@
break;
}
- fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
+ fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
if (send_pres_tags)
@@ -7633,10 +7637,10 @@
l = tmp_l;
}
- if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
- snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), ourport, p->tag);
+ if (ntohs(p->ourip.sin_port) != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain))
+ snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)), ntohs(p->ourip.sin_port), p->tag);
else
- snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
+ snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)), p->tag);
/* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
if (!ast_strlen_zero(p->fullcontact)) {
@@ -7985,7 +7989,7 @@
ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n",
- S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
+ S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)));
/* Cisco has a bug in the SIP stack where it can't accept the
(0/0) notification. This can temporarily be disabled in
sip.conf with the "buggymwi" option */
@@ -8226,8 +8230,9 @@
based on whether the remote host is on the external or
internal network so we can register through nat
*/
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = bindaddr.sin_addr;
+ p->ourip.sin_port = bindaddr.sin_port; /* XXX nat... */
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+ p->ourip.sin_addr = bindaddr.sin_addr;
build_contact(p);
}
@@ -11887,7 +11892,7 @@
ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer));
ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
- ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
+ ast_cli(fd, " Audio IP: %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip.sin_addr), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
ast_cli(fd, " Our Tag: %s\n", cur->tag);
ast_cli(fd, " Their Tag: %s\n", cur->theirtag);
ast_cli(fd, " SIP User agent: %s\n", cur->useragent);
@@ -12321,8 +12326,9 @@
add_header(&req, var->name, var->value);
/* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
+ p->ourip.sin_port = bindaddr.sin_port; /* XXX nat */
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+ p->ourip.sin_addr = __ourip;
build_via(p);
build_callid_pvt(p);
ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
@@ -16458,8 +16464,9 @@
return 0;
}
/* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
+ p->ourip.sin_port = bindaddr.sin_port;
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+ p->ourip.sin_addr = __ourip;
build_via(p);
build_callid_pvt(p);
/* Destroy this session after 32 secs */
@@ -16720,8 +16727,9 @@
ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
/* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
+ p->ourip.sin_port = bindaddr.sin_port;
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+ p->ourip.sin_addr = __ourip;
build_via(p);
build_callid_pvt(p);
@@ -16896,8 +16904,9 @@
if (ast_strlen_zero(p->peername) && ext)
ast_string_field_set(p, peername, ext);
/* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
- p->ourip = __ourip;
+ p->ourip.sin_port = bindaddr.sin_port;
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip.sin_addr))
+ p->ourip.sin_addr = __ourip;
build_via(p);
build_callid_pvt(p);
@@ -17716,7 +17725,7 @@
memset(&global_outboundproxy, 0, sizeof(struct sip_proxy));
global_outboundproxy.ip.sin_port = htons(STANDARD_SIP_PORT);
global_outboundproxy.ip.sin_family = AF_INET; /* Type of address: IPv4 */
- ourport = STANDARD_SIP_PORT;
+ bindaddr.sin_port = htons(STANDARD_SIP_PORT);
global_srvlookup = DEFAULT_SRVLOOKUP;
global_tos_sip = DEFAULT_TOS_SIP;
global_tos_audio = DEFAULT_TOS_AUDIO;
@@ -17948,8 +17957,9 @@
M_F("cos_video", ast_str2cos(v->value, &global_cos_video))
M_F("cos_text", ast_str2cos(v->value, &global_cos_text))
M_F("bindport", {
- if (sscanf(v->value, "%d", &ourport) == 1) {
- bindaddr.sin_port = htons(ourport);
+ int i;
+ if (sscanf(v->value, "%d", &i) == 1) {
+ bindaddr.sin_port = htons(i);
} else {
ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
} } )
@@ -18202,12 +18212,12 @@
if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
if (!p->pendinginvite) {
if (option_debug > 2) {
- ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
+ ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
}
transmit_reinvite_with_sdp(p, TRUE);
} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
if (option_debug > 2) {
- ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
+ ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
}
ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
}
@@ -18259,7 +18269,7 @@
if (flag)
ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
else
- ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
+ ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip.sin_addr));
}
transmit_reinvite_with_sdp(p, TRUE);
} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
@@ -18267,7 +18277,7 @@
if (flag)
ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
else
- ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
+ ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip.sin_addr));
}
ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
}
@@ -18283,7 +18293,7 @@
if (flag)
ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(p->udptlredirip.sin_addr), ntohs(p->udptlredirip.sin_port));
else
- ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip));
+ ast_log(LOG_DEBUG, "Responding 200 OK on SIP '%s' - It's UDPTL soon redirected to us (IP %s)\n", p->callid, ast_inet_ntoa(p->ourip.sin_addr));
}
pvt->t38.state = T38_ENABLED;
p->t38.state = T38_ENABLED;
@@ -18430,15 +18440,15 @@
if (chan->_state != AST_STATE_UP) { /* We are in early state */
append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
if (option_debug)
- ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
+ ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
} else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */
if (option_debug > 2) {
- ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
+ ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
}
transmit_reinvite_with_sdp(p, FALSE);
} else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
if (option_debug > 2) {
- ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
+ ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
}
/* We have a pending Invite. Send re-invite when we're done with the invite */
ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
More information about the asterisk-commits
mailing list