]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add an external port output parameter to switch_nat_add_mapping and use it in sofia_g...
authorMathieu Rene <mrene@avgs.ca>
Fri, 5 Jun 2009 02:30:44 +0000 (02:30 +0000)
committerMathieu Rene <mrene@avgs.ca>
Fri, 5 Jun 2009 02:30:44 +0000 (02:30 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13629 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_nat.h
src/mod/applications/mod_commands/mod_commands.c
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/event_handlers/mod_event_socket/mod_event_socket.c
src/switch_nat.c

index 38bf23c8db35646b8750d0ccacac454e281368b1..ebcbf2f09067ae9877713719b083a3049532a92d 100644 (file)
@@ -59,9 +59,22 @@ typedef enum {
   \note Generally called by the core_init
 */
 SWITCH_DECLARE(void) switch_nat_init(switch_memory_pool_t *pool);
+/*!
+ \brief Shuts down the NAT Traversal System
+*/
 SWITCH_DECLARE(void) switch_nat_shutdown(void);
 
-SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping(switch_port_t port, switch_nat_ip_proto_t proto);
+/*!
+ \brief Maps a port through the NAT Traversal System
+ \param port Internal port to map
+ \param proto Protocol
+ \param external_port [out] Mapped external port 
+*/
+SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t *external_port);
+/*!
+ \brief Deletes a NAT mapping
+ \param proto Protocol
+*/
 SWITCH_DECLARE(switch_status_t) switch_nat_del_mapping(switch_port_t port, switch_nat_ip_proto_t proto);
 
 
index 98f3df894f8d8ac291d3512a77e47a548335cf72..8288fa6f242b0c9f57e6aa17354ecdb7a5aded5d 100644 (file)
@@ -49,6 +49,7 @@ SWITCH_STANDARD_API(nat_map_function)
        int argc;
        char *mydata = NULL, *argv[4];
        switch_nat_ip_proto_t proto = SWITCH_NAT_UDP;
+       switch_port_t external_port = 0;
 
        if (!cmd) {
                goto error;
@@ -70,8 +71,8 @@ SWITCH_STANDARD_API(nat_map_function)
        }
 
        if (argv[0] && switch_stristr("add", argv[0])) {
-               if (switch_nat_add_mapping((switch_port_t)atoi(argv[1]), proto) == SWITCH_STATUS_SUCCESS) {
-                       stream->write_function(stream, "true");
+               if (switch_nat_add_mapping((switch_port_t)atoi(argv[1]), proto, &external_port) == SWITCH_STATUS_SUCCESS) {
+                       stream->write_function(stream, "%d", (int)external_port);
                        goto ok;
                }
        } else if (argv[0] && switch_stristr("del", argv[0])) {
index af813ad975404fd423133fb312e1decc16388a00..ea895f19c48129e0aaa8216630ee28ad941f3842 100644 (file)
@@ -762,13 +762,13 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
                                                                        );
 
        if (sofia_test_pflag(profile, PFLAG_AUTO_NAT)) {
-               if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_UDP) == SWITCH_STATUS_SUCCESS) {
+               if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_UDP, NULL) == SWITCH_STATUS_SUCCESS) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created UDP nat mapping for %s port %d\n", profile->name, profile->sip_port);
                }
-               if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_TCP) == SWITCH_STATUS_SUCCESS) {
+               if (switch_nat_add_mapping(profile->sip_port, SWITCH_NAT_TCP, NULL) == SWITCH_STATUS_SUCCESS) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created TCP nat mapping for %s port %d\n", profile->name, profile->sip_port);
                }
-               if(sofia_test_pflag(profile, PFLAG_TLS) && switch_nat_add_mapping(profile->tls_sip_port, SWITCH_NAT_TCP) == SWITCH_STATUS_SUCCESS) {
+               if(sofia_test_pflag(profile, PFLAG_TLS) && switch_nat_add_mapping(profile->tls_sip_port, SWITCH_NAT_TCP, NULL) == SWITCH_STATUS_SUCCESS) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created TCP/TLS nat mapping for %s port %d\n", profile->name, profile->tls_sip_port);
                }
        }
index a83336304ebc8560efc6fe3e15b345cf4023b0b8..993c002919613643abbf8baefcf7ada7a4a46665 100644 (file)
@@ -630,6 +630,7 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc
        switch_port_t sdp_port;
        char tmp[50];
        const char *use_ip = NULL;
+       switch_port_t external_port = 0;
 
        if (!force) {
                if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) ||
@@ -667,12 +668,12 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc
 
        if (tech_pvt->profile->extrtpip && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
                tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, tech_pvt->profile->extrtpip);
-               switch_nat_add_mapping((switch_port_t)sdp_port, SWITCH_NAT_UDP);
+               switch_nat_add_mapping((switch_port_t)sdp_port, SWITCH_NAT_UDP, &external_port);
        } else {
                tech_pvt->adv_sdp_audio_ip = switch_core_session_strdup(tech_pvt->session, ip);
        }
        
-       tech_pvt->adv_sdp_audio_port = sdp_port;
+       tech_pvt->adv_sdp_audio_port = external_port != 0 ? external_port : sdp_port;
 
        switch_snprintf(tmp, sizeof(tmp), "%d", sdp_port);
        switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
@@ -686,6 +687,7 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, in
        char *ip = tech_pvt->profile->rtpip;
        switch_port_t sdp_port;
        char tmp[50];
+       switch_port_t external_port = 0;
 
        if (!force) {
                if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)
@@ -712,11 +714,11 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, in
                }
        }
 
-       tech_pvt->adv_sdp_video_port = sdp_port;
-
        if (sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
-               switch_nat_add_mapping((switch_port_t)sdp_port, SWITCH_NAT_UDP);
+               switch_nat_add_mapping((switch_port_t)sdp_port, SWITCH_NAT_UDP, &external_port);
        }
+       
+       tech_pvt->adv_sdp_video_port = external_port != 0 ? external_port : sdp_port;
 
        switch_snprintf(tmp, sizeof(tmp), "%d", sdp_port);
        switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, tech_pvt->adv_sdp_audio_ip);
index 7e3bd13d4364e75de4a5c1a6ed7e5850c99b44e9..f6b0095fc11438d5795d36b207a572460c4c0db1 100644 (file)
@@ -2291,7 +2291,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Socket up listening on %s:%u\n", prefs.ip, prefs.port);
 
                if (prefs.nat_map) {
-                       switch_nat_add_mapping(prefs.port, SWITCH_NAT_TCP);
+                       switch_nat_add_mapping(prefs.port, SWITCH_NAT_TCP, NULL);
                }
 
                break;
index 68b897e6e09b0947e6b828e76605fbe9f7ef5a71..a59533f36fe4e16f42ffe84a8ea2c033e6187181 100644 (file)
@@ -170,7 +170,7 @@ SWITCH_DECLARE(void) switch_nat_init(switch_memory_pool_t *pool)
        }
 }
 
-static switch_status_t switch_nat_add_mapping_pmp(switch_port_t port, switch_nat_ip_proto_t proto)
+static switch_status_t switch_nat_add_mapping_pmp(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t *external_port)
 {
        switch_status_t status = SWITCH_STATUS_FALSE;
        natpmpresp_t response;
@@ -198,6 +198,16 @@ static switch_status_t switch_nat_add_mapping_pmp(switch_port_t port, switch_nat
                                                  response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" :
                                                  (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" : "UNKNOWN"),
                                                  response.pnu.newportmapping.privateport);
+               if (external_port) {
+                       *external_port = response.pnu.newportmapping.mappedpublicport;
+               } else if (response.pnu.newportmapping.mappedpublicport != response.pnu.newportmapping.privateport) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "External port %hu protocol %s was not available, it was instead mapped to %hu",
+                               response.pnu.newportmapping.privateport,
+                               response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" :
+                               (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" : "UNKNOWN"),
+                               response.pnu.newportmapping.mappedpublicport);
+               }
+                                               
                status = SWITCH_STATUS_SUCCESS;
        }
 
@@ -285,16 +295,20 @@ static switch_status_t switch_nat_del_mapping_upnp(switch_port_t port, switch_na
        return status;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping(switch_port_t port, switch_nat_ip_proto_t proto)
+SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping(switch_port_t port, switch_nat_ip_proto_t proto, switch_port_t *external_port)
 {
        switch_status_t status = SWITCH_STATUS_FALSE;
 
        switch (nat_globals.nat_type) {
        case SWITCH_NAT_TYPE_PMP:
-               status = switch_nat_add_mapping_pmp(port, proto);
+               status = switch_nat_add_mapping_pmp(port, proto, external_port);
                break;
        case SWITCH_NAT_TYPE_UPNP:
-               status = switch_nat_add_mapping_upnp(port, proto);
+               if ((status = switch_nat_add_mapping_upnp(port, proto)) && status == SWITCH_STATUS_SUCCESS) {
+                       if (external_port) {
+                               *external_port = port;
+                       }       
+               }
                break;
        default:
                break;