[svn-commits] file: branch file/issue8855 r194427 - /team/file/issue8855/channels/chan_sip.c
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed May 13 19:55:07 CDT 2009
Author: file
Date: Wed May 13 19:55:02 2009
New Revision: 194427
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=194427
Log:
Add progress thus far on making the nat option sane.
Modified:
team/file/issue8855/channels/chan_sip.c
Modified: team/file/issue8855/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/file/issue8855/channels/chan_sip.c?view=diff&rev=194427&r1=194426&r2=194427
==============================================================================
--- team/file/issue8855/channels/chan_sip.c (original)
+++ team/file/issue8855/channels/chan_sip.c Wed May 13 19:55:02 2009
@@ -1378,12 +1378,9 @@
#define SIP_DTMF_AUTO (3 << 15) /*!< DP: DTMF Support: AUTO switch between rfc2833 and in-band DTMF */
#define SIP_DTMF_SHORTINFO (4 << 15) /*!< DP: DTMF Support: SIP Info messages - "info" - short variant */
-/* NAT settings - see nat2str() */
-#define SIP_NAT (3 << 18) /*!< DP: four settings, uses two bits */
-#define SIP_NAT_NEVER (0 << 18) /*!< DP: No nat support */
-#define SIP_NAT_RFC3581 (1 << 18) /*!< DP: NAT RFC3581 */
-#define SIP_NAT_ROUTE (2 << 18) /*!< DP: NAT Only ROUTE */
-#define SIP_NAT_ALWAYS (3 << 18) /*!< DP: NAT Both ROUTE and RFC3581 */
+/* NAT settings */
+#define SIP_NAT_FORCE_RPORT (1 << 18) /*!< DP: Force rport even if not present in the request */
+#define SIP_NAT_RPORT_PRESENT (1 << 19) /*!< DP: rport was present in the request */
/* re-INVITE related settings */
#define SIP_REINVITE (7 << 20) /*!< DP: four settings, uses three bits */
@@ -1413,7 +1410,7 @@
/*! \brief Flags to copy from peer/user to dialog */
#define SIP_FLAGS_TO_COPY \
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \
- SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \
+ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT_FORCE_RPORT | SIP_G726_NONSTANDARD | \
SIP_USEREQPHONE | SIP_INSECURE)
/*@}*/
@@ -2362,7 +2359,7 @@
struct ast_str **m_buf, struct ast_str **a_buf,
int debug);
static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38);
-static void do_setnat(struct sip_pvt *p, int natflags);
+static void do_setnat(struct sip_pvt *p);
static void stop_media_flows(struct sip_pvt *p);
/*--- Authentication stuff */
@@ -2446,7 +2443,6 @@
static const char *sip_nat_mode(const struct sip_pvt *p);
static char *sip_show_inuse(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static char *transfermode2str(enum transfermodes mode) attribute_const;
-static const char *nat2str(int nat) attribute_const;
static int peer_status(struct sip_peer *peer, char *status, int statuslen);
static char *sip_show_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static char * _sip_show_peers(int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]);
@@ -3229,13 +3225,13 @@
if (p->outboundproxy)
return &p->outboundproxy->ip;
- return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
+ return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT) ? &p->recv : &p->sa;
}
/*! \brief Display SIP nat mode */
static const char *sip_nat_mode(const struct sip_pvt *p)
{
- return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
+ return ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) ? "NAT" : "no NAT";
}
/*! \brief Test PVT for debugging output */
@@ -3350,7 +3346,7 @@
static void build_via(struct sip_pvt *p)
{
/* Work around buggy UNIDEN UIP200 firmware */
- const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
+ const char *rport = (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT) || ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)) ? ";rport" : "";
/* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */
snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s:%d;branch=z9hG4bK%08x%s",
@@ -3915,7 +3911,7 @@
add_blank(req);
if (sip_debug_test_pvt(p)) {
- if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
+ if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT))
ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port), req->data->str);
else
ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->data->str);
@@ -4666,11 +4662,12 @@
}
/*! \brief Set nat mode on the various data sockets */
-static void do_setnat(struct sip_pvt *p, int natflags)
+static void do_setnat(struct sip_pvt *p)
{
const char *mode;
-
- natflags |= ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
+ int natflags;
+
+ natflags = ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP);
mode = natflags ? "On" : "Off";
if (p->rtp) {
@@ -4821,7 +4818,7 @@
ast_rtp_instance_set_qos(dialog->rtp, global_tos_audio, 0, "SIP RTP");
- do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
+ do_setnat(dialog);
return 0;
}
@@ -6858,9 +6855,9 @@
if (useglobal_nat && sin) {
/* Setup NAT structure according to global settings if we have an address */
- ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
+ ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
p->recv = *sin;
- do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
+ do_setnat(p);
}
if (p->method != SIP_REGISTER)
@@ -7758,7 +7755,7 @@
if (p->udptl) {
if (udptlportno > 0) {
sin.sin_port = htons(udptlportno);
- if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
struct sockaddr_in remote_address = { 0, };
ast_rtp_instance_get_remote_address(p->rtp, &remote_address);
if (remote_address.sin_addr.s_addr) {
@@ -8416,7 +8413,7 @@
rport = NULL; /* We already have a parameter to rport */
/* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */
- if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
+ if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) || (ast_test_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT)))) {
/* We need to add received port - rport */
char *end;
@@ -8920,9 +8917,9 @@
p->ocseq = INITIAL_CSEQ;
if (useglobal_nat && sin) {
- ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
+ ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT_FORCE_RPORT);
p->recv = *sin;
- do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
+ do_setnat(p);
}
ast_string_field_set(p, fromdomain, default_fromdomain);
@@ -11603,7 +11600,7 @@
/*! \brief Change the other partys IP address based on given contact */
static int set_address_from_contact(struct sip_pvt *pvt)
{
- if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
+ if (ast_test_flag(&pvt->flags[0], SIP_NAT_FORCE_RPORT)) {
/* NAT: Don't trust the contact field. Just use what they came to us
with. */
/*! \todo We need to save the TRANSPORT here too */
@@ -11738,7 +11735,7 @@
/*! \todo This could come before the checking of DNS earlier on, to avoid
DNS lookups where we don't need it... */
- if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
+ if (!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT)) {
peer->addr.sin_family = AF_INET;
memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
peer->addr.sin_port = htons(port);
@@ -12364,7 +12361,7 @@
ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
res = AUTH_PEER_NOT_DYNAMIC;
} else {
- ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
+ ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT);
if (ast_test_flag(&p->flags[1], SIP_PAGE2_REGISTERTRYING))
transmit_response(p, "100 Trying", req);
if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, req->ignore))) {
@@ -13322,7 +13319,7 @@
/* Check for rport */
c = strstr(via, ";rport");
if (c && (c[6] != '=')) /* rport query, not answer */
- ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
+ ast_set_flag(&p->flags[0], SIP_NAT_RPORT_PRESENT);
c = strchr(via, ';');
if (c)
@@ -13469,7 +13466,7 @@
if (p->sipoptions)
peer->sipoptions = p->sipoptions;
- do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
+ do_setnat(p);
ast_string_field_set(p, peersecret, peer->secret);
ast_string_field_set(p, peermd5secret, peer->md5secret);
@@ -13831,40 +13828,6 @@
return "strict";
}
-static struct _map_x_s natmodes[] = {
- { SIP_NAT_NEVER, "No"},
- { SIP_NAT_ROUTE, "Route"},
- { SIP_NAT_ALWAYS, "Always"},
- { SIP_NAT_RFC3581, "RFC3581"},
- { -1, NULL}, /* terminator */
-};
-
-/*! \brief Convert NAT setting to text string */
-static const char *nat2str(int nat)
-{
- return map_x_s(natmodes, nat, "Unknown");
-}
-
-#ifdef NOTUSED
-/* OEJ: This is not used, but may be useful in the future, so I don't want to
- delete it. Keeping it enabled generates compiler warnings.
- */
-
-static struct _map_x_s natcfgmodes[] = {
- { SIP_NAT_NEVER, "never"},
- { SIP_NAT_ROUTE, "route"},
- { SIP_NAT_ALWAYS, "yes"},
- { SIP_NAT_RFC3581, "no"},
- { -1, NULL}, /* terminator */
-};
-
-/*! \brief Convert NAT setting to text string appropriate for config files */
-static const char *nat2strconfig(int nat)
-{
- return map_x_s(natcfgmodes, nat, "Unknown");
-}
-#endif
-
/*! \brief Report Peer status in character string
* \return 0 if peer is unreachable, 1 if peer is online, -1 if unmonitored
*/
@@ -14013,7 +13976,7 @@
return CLI_SHOWUSAGE;
}
- ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
+ ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "ForcerPort");
user_iter = ao2_iterator_init(peers, 0);
while ((user = ao2_iterator_next(&user_iter))) {
@@ -14035,7 +13998,7 @@
user->accountcode,
user->context,
cli_yesno(user->ha != NULL),
- nat2str(ast_test_flag(&user->flags[0], SIP_NAT)));
+ cli_yesno(ast_test_flag(&user->flags[0], SIP_NAT_FORCE_RPORT)));
ao2_unlock(user);
unref_peer(user, "sip show users");
}
@@ -14162,7 +14125,7 @@
struct ao2_iterator i;
/* the last argument is left-aligned, so we don't need a size anyways */
-#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %s\n"
+#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-10.10s %-3.3s %-8s %-10s %s\n"
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
char name[256];
@@ -14203,7 +14166,7 @@
}
if (!s) /* Normal list */
- ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
+ ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Forcerport", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
i = ao2_iterator_init(peers, 0);
@@ -14262,7 +14225,7 @@
snprintf(srch, sizeof(srch), FORMAT, name,
peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
peer->host_dynamic ? " D " : " ", /* Dynamic or not? */
- ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
+ ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */
peer->ha ? " A " : " ", /* permit/deny */
ntohs(peer->addr.sin_port), status,
realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
@@ -14271,7 +14234,7 @@
ast_cli(fd, FORMAT, name,
peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
peer->host_dynamic ? " D " : " ", /* Dynamic or not? */
- ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */
+ ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? " N " : " ", /* NAT=yes? */
peer->ha ? " A " : " ", /* permit/deny */
ntohs(peer->addr.sin_port), status,
@@ -14286,7 +14249,7 @@
"IPaddress: %s\r\n"
"IPport: %d\r\n"
"Dynamic: %s\r\n"
- "Natsupport: %s\r\n"
+ "Forcerport: %s\r\n"
"VideoSupport: %s\r\n"
"TextSupport: %s\r\n"
"ACL: %s\r\n"
@@ -14297,7 +14260,7 @@
peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
ntohs(peer->addr.sin_port),
peer->host_dynamic ? "yes" : "no", /* Dynamic or not? */
- ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */
+ ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) ? "yes" : "no", /* NAT=yes? */
ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */
ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no", /* TEXTSUPPORT=yes? */
peer->ha ? "yes" : "no", /* permit/deny */
@@ -14911,7 +14874,7 @@
ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate);
ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire));
ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
- ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
+ ast_cli(fd, " Force rport : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)));
ast_cli(fd, " ACL : %s\n", cli_yesno(peer->ha != NULL));
ast_cli(fd, " T38 pt UDPTL : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)));
#ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
@@ -15020,7 +14983,7 @@
astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire));
astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
- astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
+ astman_append(s, "SIP-Forcerport: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)?"Y":"N"));
astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
@@ -15575,7 +15538,7 @@
ast_cli(a->fd, " Allowed transports: %s\n", get_transport_list(default_transports));
ast_cli(a->fd, " Outbound transport: %s\n", get_transport(default_primary_transport));
ast_cli(a->fd, " Context: %s\n", sip_cfg.default_context);
- ast_cli(a->fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
+ ast_cli(a->fd, " Force rport: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_NAT_FORCE_RPORT)));
ast_cli(a->fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
ast_cli(a->fd, " Qualify: %d\n", default_qualify);
ast_cli(a->fd, " Use ClientCode: %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE)));
@@ -15942,7 +15905,7 @@
ast_cli(a->fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
ast_cli(a->fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer));
- ast_cli(a->fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
+ ast_cli(a->fd, " Force rport: %s\n", cli_yesno(ast_test_flag(&cur->flags[0], SIP_NAT_FORCE_RPORT)));
ast_cli(a->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(a->fd, " Our Tag: %s\n", cur->tag);
ast_cli(a->fd, " Their Tag: %s\n", cur->theirtag);
@@ -22852,16 +22815,16 @@
ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
}
} else if (!strcasecmp(v->name, "nat")) {
- ast_set_flag(&mask[0], SIP_NAT);
- ast_clear_flag(&flags[0], SIP_NAT);
- if (!strcasecmp(v->value, "never"))
- ast_set_flag(&flags[0], SIP_NAT_NEVER);
- else if (!strcasecmp(v->value, "route"))
- ast_set_flag(&flags[0], SIP_NAT_ROUTE);
- else if (ast_true(v->value))
- ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
- else
- ast_set_flag(&flags[0], SIP_NAT_RFC3581);
+ ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT);
+ if (!strcasecmp(v->value, "no")) {
+ ast_clear_flag(&flags[0], SIP_NAT_FORCE_RPORT);
+ } else if (!strcasecmp(v->value, "force_rport")) {
+ ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT);
+ } else if (!strcasecmp(v->value, "yes")) {
+ ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT);
+ ast_set_flag(&mask[1], SIP_PAGE2_SYMMETRICRTP);
+ ast_set_flag(&flags[1], SIP_PAGE2_SYMMETRICRTP);
+ }
} else if (!strcasecmp(v->name, "canreinvite")) {
ast_set_flag(&mask[0], SIP_REINVITE);
ast_clear_flag(&flags[0], SIP_REINVITE);
@@ -23943,7 +23906,6 @@
ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
- ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */
ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */
ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine));
More information about the svn-commits
mailing list