[asterisk-commits] oej: branch group/pine-multiple-externip-1.4 r288711 - /team/group/pine-multi...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Sep 24 04:37:37 CDT 2010
Author: oej
Date: Fri Sep 24 04:37:32 2010
New Revision: 288711
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=288711
Log:
Getting stuck in an airport made this happen
Modified:
team/group/pine-multiple-externip-1.4/channels/chan_sip.c
Modified: team/group/pine-multiple-externip-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pine-multiple-externip-1.4/channels/chan_sip.c?view=diff&rev=288711&r1=288710&r2=288711
==============================================================================
--- team/group/pine-multiple-externip-1.4/channels/chan_sip.c (original)
+++ team/group/pine-multiple-externip-1.4/channels/chan_sip.c Fri Sep 24 04:37:32 2010
@@ -1007,6 +1007,7 @@
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 */
+ struct sockaddr_in externip; /*!< External IP to use for this connection */
time_t lastrtprx; /*!< Last RTP received */
time_t lastrtptx; /*!< Last RTP sent */
int rtptimeout; /*!< RTP timeout time */
@@ -1184,6 +1185,7 @@
struct timeval ps; /*!< Ping send time */
struct sockaddr_in defaddr; /*!< Default IP address, used until registration */
+ struct sockaddr_in externip; /*!< External IP to use for this connection */
struct ast_ha *ha; /*!< Access control list */
struct ast_ha *contactha; /*!< Restrict what IPs are allowed in the Contact header (for registration) */
struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
@@ -1547,7 +1549,7 @@
static int sip_prune_realtime(int fd, int argc, char *argv[]);
/*--- Internal UA client handling (outbound registrations) */
-static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us);
+static int ast_sip_ouraddrfor(struct sip_pvt *dialog, struct in_addr *them, struct in_addr *us);
static void sip_registry_destroy(struct sip_registry *reg);
static int sip_register(char *value, int lineno);
static char *regstate2str(enum sipregistrystate regstate) attribute_const;
@@ -1912,35 +1914,40 @@
* apply it to their address to see if we need to substitute our
* externip or can get away with our internal bindaddr
*/
-static enum sip_result ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us)
+static enum sip_result ast_sip_ouraddrfor(struct sip_pvt *dialog, struct in_addr *them, struct in_addr *us)
{
struct sockaddr_in theirs, ours;
+ struct sockaddr_in *useexternip = dialog->externip.sin_addr.s_addr ? &dialog->externip : &externip;
/* Get our local information */
ast_ouraddrfor(them, us);
theirs.sin_addr = *them;
ours.sin_addr = *us;
- if (localaddr && externip.sin_addr.s_addr &&
+
+ if (localaddr && useexternip->sin_addr.s_addr &&
(ast_apply_ha(localaddr, &theirs)) &&
(!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) {
- if (externexpire && time(NULL) >= externexpire) {
+ if (!dialog->externip.sin_addr.s_addr && externexpire && time(NULL) >= externexpire) {
struct ast_hostent ahp;
struct hostent *hp;
externexpire = time(NULL) + externrefresh;
if ((hp = ast_gethostbyname(externhost, &ahp))) {
memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
- } else
+ } else {
ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
- }
- *us = externip.sin_addr;
+ }
+ }
+ *us = useexternip->sin_addr;
if (option_debug) {
- ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n",
- ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
- }
- } else if (bindaddr.sin_addr.s_addr)
+ ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip %s\n",
+ ast_inet_ntoa(*(struct in_addr *)&them->s_addr),
+ ast_inet_ntoa(*(struct in_addr *)&us->s_addr) );
+ }
+ } else if (bindaddr.sin_addr.s_addr) {
*us = bindaddr.sin_addr;
+ }
return AST_SUCCESS;
}
@@ -3134,6 +3141,11 @@
dialog->maxcallbitrate = peer->maxcallbitrate;
if (!dialog->portinuri)
dialog->portinuri = peer->portinuri;
+ if (peer->externip.sin_addr.s_addr) {
+ memcpy(&dialog->externip.sin_addr, &peer->externip.sin_addr, sizeof(dialog->sa.sin_addr));
+ } else {
+ memcpy(&dialog->externip.sin_addr, &externip.sin_addr, sizeof(dialog->sa.sin_addr));
+ }
return 0;
}
@@ -4818,7 +4830,7 @@
if (sin) {
p->sa = *sin;
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+ if (ast_sip_ouraddrfor(p, &p->sa.sin_addr, &p->ourip))
p->ourip = __ourip;
} else
p->ourip = __ourip;
@@ -5463,11 +5475,9 @@
/* Host information */
struct ast_hostent audiohp;
struct ast_hostent videohp;
- struct ast_hostent imagehp;
struct ast_hostent sessionhp;
struct hostent *hp = NULL; /*!< RTP Audio host IP */
struct hostent *vhp = NULL; /*!< RTP video host IP */
- struct hostent *ihp = NULL; /*!< UDPTL host IP */
int portno = -1; /*!< RTP Audio port number */
int vportno = -1; /*!< RTP Video port number */
int udptlportno = -1; /*!< UDPTL Image port number */
@@ -5543,7 +5553,6 @@
processed = TRUE;
hp = &sessionhp.hp;
vhp = hp;
- ihp = hp;
}
break;
case 'a':
@@ -5678,11 +5687,6 @@
processed = TRUE;
vhp = &videohp.hp;
}
- } else if (image) {
- if (process_sdp_c(value, &imagehp)) {
- processed = TRUE;
- ihp = &imagehp.hp;
- }
}
break;
case 'a':
@@ -5717,7 +5721,7 @@
}
/* Sanity checks */
- if (!hp && !vhp && !ihp) {
+ if (!hp && !vhp) {
ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
return -1;
}
@@ -5852,7 +5856,7 @@
ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(isin.sin_addr));
}
} else
- memcpy(&isin.sin_addr, ihp->h_addr, sizeof(isin.sin_addr));
+ memcpy(&isin.sin_addr, hp->h_addr, sizeof(isin.sin_addr));
ast_udptl_set_peer(p->udptl, &isin);
if (debug)
ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(isin.sin_addr), ntohs(isin.sin_port));
@@ -6740,7 +6744,7 @@
if (sin) {
p->sa = *sin;
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+ if (ast_sip_ouraddrfor(p, &p->sa.sin_addr, &p->ourip))
p->ourip = __ourip;
} else
p->ourip = __ourip;
@@ -8277,7 +8281,7 @@
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))
+ if (ast_sip_ouraddrfor(p, &p->sa.sin_addr, &p->ourip))
p->ourip = bindaddr.sin_addr;
build_contact(p);
}
@@ -9913,37 +9917,24 @@
if (sip_debug_test_pvt(p))
ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
- /* Since extensions.conf can have unescaped characters, try matching a
- * decoded uri in addition to the non-decoded uri. */
- decoded_uri = ast_strdupa(uri);
- ast_uri_decode(decoded_uri);
-
/* If this is a subscription we actually just need to see if a hint exists for the extension */
if (req->method == SIP_SUBSCRIBE) {
char hint[AST_MAX_EXTENSION];
- int which = 0;
- if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, uri) ||
- (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, decoded_uri) && (which = 1))) {
- if (!oreq) {
- ast_string_field_set(p, exten, which ? decoded_uri : uri);
- }
- return 0;
- } else {
- return -1;
- }
+ return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
} else {
- int which = 0;
+ decoded_uri = ast_strdupa(uri);
+ ast_uri_decode(decoded_uri);
/* Check the dialplan for the username part of the request URI,
the domain will be stored in the SIPDOMAIN variable
+ Since extensions.conf can have unescaped characters, try matching a decoded
+ uri in addition to the non-decoded uri
Return 0 if we have a matching extension */
- if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) ||
- (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) && (which = 1)) ||
+ if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) ||
!strcmp(decoded_uri, ast_pickup_ext())) {
- if (!oreq) {
- ast_string_field_set(p, exten, which ? decoded_uri : uri);
- }
+ if (!oreq)
+ ast_string_field_set(p, exten, decoded_uri);
return 0;
- }
+ }
}
/* Return 1 for pickup extension or overlap dialling support (if we support it) */
@@ -12453,7 +12444,7 @@
}
/* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+ if (ast_sip_ouraddrfor(p, &p->sa.sin_addr, &p->ourip))
p->ourip = __ourip;
build_via(p);
build_callid_pvt(p);
@@ -13112,12 +13103,11 @@
{
if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
/* if we can't BYE, then this is really a pending CANCEL */
- if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
- p->invitestate = INV_CANCELLED;
+ if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
/* Actually don't destroy us yet, wait for the 487 on our original
INVITE, but do set an autodestruct just in case we never get it. */
- } else {
+ else {
/* We have a pending outbound invite, don't send someting
new in-transaction */
if (p->pendinginvite)
@@ -16853,7 +16843,7 @@
if (option_debug)
ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
if (req->method != SIP_ACK)
- transmit_response(p, "500 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */
+ transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */
return -1;
}
} else if (p->icseq &&
@@ -17226,7 +17216,7 @@
return 0;
}
/* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+ if (ast_sip_ouraddrfor(p, &p->sa.sin_addr, &p->ourip))
p->ourip = __ourip;
build_via(p);
build_callid_pvt(p);
@@ -17560,7 +17550,7 @@
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))
+ if (ast_sip_ouraddrfor(p, &p->sa.sin_addr, &p->ourip))
p->ourip = __ourip;
build_via(p);
build_callid_pvt(p);
@@ -17761,7 +17751,7 @@
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))
+ if (ast_sip_ouraddrfor(p, &p->sa.sin_addr, &p->ourip))
p->ourip = __ourip;
build_via(p);
build_callid_pvt(p);
@@ -18496,6 +18486,14 @@
ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
} else if (!strcasecmp(v->name, "mohsuggest")) {
ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
+ } else if (!strcasecmp(v->name, "externip")) {
+ struct hostent *hp;
+ struct ast_hostent ahp;
+ if (!(hp = ast_gethostbyname(v->value, &ahp))) {
+ ast_log(LOG_WARNING, "Invalid address for externip keyword: %s at line %d\n", v->value, v->lineno);
+ } else {
+ memcpy(&peer->externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr));
+ }
} else if (!strcasecmp(v->name, "mailbox")) {
ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
} else if (!strcasecmp(v->name, "hasvoicemail")) {
More information about the asterisk-commits
mailing list