]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add multiple rtp-ip support to sofia profiles
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 10 Jun 2010 22:08:29 +0000 (17:08 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 10 Jun 2010 22:10:03 +0000 (17:10 -0500)
add extra rtp-ip params to a profile to add more ip which will be used round-robin as new calls progress.

src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c

index 1d274c23d85b165931bb3277f99ea6c00a62e352..c497632f349b14804a32a42d2877c068944272fe 100644 (file)
@@ -263,7 +263,7 @@ char *generate_pai_str(switch_core_session_t *session)
        callee_name = switch_sanitize_number(switch_core_session_strdup(session, callee_name));
 
        if (!zstr(callee_number) && (zstr(ua) || !switch_stristr("polycom", ua))) {
-               callee_number = switch_core_session_sprintf(session, "sip:%s@%s", callee_number, tech_pvt->profile->sipip);
+               callee_number = switch_core_session_sprintf(session, "sip:%s@%s", callee_number, tech_pvt->sipip);
        }
 
        header = (tech_pvt->cid_type == CID_TYPE_RPID && !switch_stristr("aastra", ua)) ? "Remote-Party-ID" : "P-Asserted-Identity";
@@ -2411,7 +2411,11 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
                } else if (!strcasecmp(argv[0], "profile")) {
                        struct cb_helper cb;
                        char *sql = NULL;
+                       int x = 0 ;
+
                        cb.row_process = 0;
+
+
                        if ((argv[1]) && (profile = sofia_glue_find_profile(argv[1]))) {
                                if (!argv[2] || (strcasecmp(argv[2], "reg") && strcasecmp(argv[2], "user"))) {
                                        stream->write_function(stream, "%s\n", line);
@@ -2426,7 +2430,9 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
                                        stream->write_function(stream, "Dialplan         \t%s\n", switch_str_nil(profile->dialplan));
                                        stream->write_function(stream, "Context          \t%s\n", switch_str_nil(profile->context));
                                        stream->write_function(stream, "Challenge Realm  \t%s\n", zstr(profile->challenge_realm) ? "auto_to" : profile->challenge_realm);
-                                       stream->write_function(stream, "RTP-IP           \t%s\n", switch_str_nil(profile->rtpip));
+                                       for (x = 0; x < profile->rtpip_index; x++) {
+                                               stream->write_function(stream, "RTP-IP           \t%s\n", switch_str_nil(profile->rtpip[x]));
+                                       }
                                        if (profile->extrtpip) {
                                                stream->write_function(stream, "Ext-RTP-IP       \t%s\n", profile->extrtpip);
                                        }
@@ -2688,6 +2694,8 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
                } else if (!strcasecmp(argv[0], "profile")) {
                        struct cb_helper cb;
                        char *sql = NULL;
+                       int x = 0;
+
                        cb.row_process = 0;
 
                        if ((argv[1]) && (profile = sofia_glue_find_profile(argv[1]))) {
@@ -2707,7 +2715,9 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
                                        stream->write_function(stream, "    <context>%s</context>\n", switch_str_nil(profile->context));
                                        stream->write_function(stream, "    <challenge-realm>%s</challenge-realm>\n",
                                                                                   zstr(profile->challenge_realm) ? "auto_to" : profile->challenge_realm);
-                                       stream->write_function(stream, "    <rtp-ip>%s</rtp-ip>\n", switch_str_nil(profile->rtpip));
+                                       for (x = 0; x < profile->rtpip_index; x++) {
+                                               stream->write_function(stream, "    <rtp-ip>%s</rtp-ip>\n", switch_str_nil(profile->rtpip[x]));
+                                       }
                                        stream->write_function(stream, "    <ext-rtp-ip>%s</ext-rtp-ip>\n", profile->extrtpip);
                                        stream->write_function(stream, "    <sip-ip>%s</sip-ip>\n", switch_str_nil(profile->sipip));
                                        stream->write_function(stream, "    <ext-sip-ip>%s</ext-sip-ip>\n", profile->extsipip);
@@ -4243,26 +4253,33 @@ static void general_event_handler(switch_event_t *event)
                                switch_mutex_lock(mod_sofia_globals.hash_mutex);
                                if (mod_sofia_globals.profile_hash) {
                                        for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
-                                               int rb = 0;
+                                               int rb = 0, x = 0;
                                                switch_hash_this(hi, &var, NULL, &val);
                                                if ((profile = (sofia_profile_t *) val) && profile->auto_restart) {
                                                        if (!strcmp(profile->sipip, old_ip4)) {
                                                                profile->sipip = switch_core_strdup(profile->pool, new_ip4);
                                                                rb++;
                                                        }
-                                                       if (!strcmp(profile->rtpip, old_ip4)) {
-                                                               profile->rtpip = switch_core_strdup(profile->pool, new_ip4);
-                                                               rb++;
+                                                       
+                                                       for (x = 0; x < profile->rtpip_index; x++) {
+
+                                                               if (!strcmp(profile->rtpip[x], old_ip4)) {
+                                                                       profile->rtpip[x] = switch_core_strdup(profile->pool, new_ip4);
+                                                                       rb++;
+                                                               }
+
+                                                               if (!strcmp(profile->rtpip[x], old_ip6)) {
+                                                                       profile->rtpip[x] = switch_core_strdup(profile->pool, new_ip6);
+                                                                       rb++;
+                                                               }
                                                        }
+                                                       
+
                                                        if (!strcmp(profile->sipip, old_ip6)) {
                                                                profile->sipip = switch_core_strdup(profile->pool, new_ip6);
                                                                rb++;
                                                        }
-                                                       if (!strcmp(profile->rtpip, old_ip6)) {
-                                                               profile->rtpip = switch_core_strdup(profile->pool, new_ip6);
-                                                               rb++;
-                                                       }
-
+                                                       
                                                        if (rb) {
                                                                sofia_set_pflag_locked(profile, PFLAG_RESPAWN);
                                                                sofia_clear_pflag_locked(profile, PFLAG_RUNNING);
index d2c34cf9a9784ccd8335007c76e870f3e58a7f0f..fd00a21c7d90264b35d2fddb85c5e9043c1e481b 100644 (file)
@@ -437,6 +437,8 @@ typedef enum {
        MEDIA_OPT_BYPASS_AFTER_ATT_XFER = (1 << 1)
 } sofia_media_options_t;
 
+#define MAX_RTPIP 50
+
 struct sofia_profile {
        int debug;
        char *name;
@@ -446,7 +448,9 @@ struct sofia_profile {
        char *context;
        char *shutdown_type;
        char *extrtpip;
-       char *rtpip;
+       char *rtpip[MAX_RTPIP];
+       uint32_t rtpip_index;
+       uint32_t rtpip_next;
        char *sipip;
        char *extsipip;
        char *username;
@@ -569,6 +573,7 @@ struct private_object {
        uint32_t ssrc;
        uint32_t video_ssrc;
        sofia_profile_t *profile;
+       char *sipip;
        char *local_sdp_audio_ip;
        switch_port_t local_sdp_audio_port;
        char *remote_sdp_audio_ip;
@@ -627,6 +632,7 @@ struct private_object {
        char *x_freeswitch_support_local;
        char *last_sent_callee_id_name;
        char *last_sent_callee_id_number;
+       char *rtpip;
        switch_port_t stun_port;
        uint32_t stun_flags;
        unsigned long rm_rate;
index 7dc4eef1bfaef51d8d4c9a0c16ea7a37db07ac96..ac22a235442e75da7c448a0a0077b51f80dca2ed 100644 (file)
@@ -3005,7 +3005,11 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                                } else {
                                                        ip = strcasecmp(val, "auto") ? val : mod_sofia_globals.guess_ip;
                                                }
-                                               profile->rtpip = switch_core_strdup(profile->pool, ip);
+                                               if (profile->rtpip_index < MAX_RTPIP) {
+                                                       profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, ip);
+                                               } else {
+                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
+                                               }
                                        } else if (!strcasecmp(var, "sip-ip")) {
                                                char *ip = mod_sofia_globals.guess_ip;
 
@@ -3416,8 +3420,8 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                        profile->sipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
                                }
 
-                               if (!profile->rtpip) {
-                                       profile->rtpip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
+                               if (!profile->rtpip[0]) {
+                                       profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
                                }
 
                                if (switch_core_get_variable("nat_type")) {
@@ -3443,9 +3447,9 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                        profile->username = switch_core_strdup(profile->pool, "FreeSWITCH");
                                }
 
-                               if (!profile->rtpip) {
+                               if (!profile->rtpip[0]) {
                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Setting ip to '127.0.0.1'\n");
-                                       profile->rtpip = switch_core_strdup(profile->pool, "127.0.0.1");
+                                       profile->rtpip[profile->rtpip_index++] = switch_core_strdup(profile->pool, "127.0.0.1");
                                }
 
                                if (!profile->sip_port) {
index 751e7d0e482ac8a3e631c9ef097b9ae2ec1926a6..c2aaf5265ed223ddea45e2bc21bf4f4d411eb632 100644 (file)
@@ -578,6 +578,12 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
        tech_pvt->x_freeswitch_support_local = FREESWITCH_SUPPORT;
 
        tech_pvt->profile = profile;
+
+       tech_pvt->rtpip = switch_core_session_strdup(session, profile->rtpip[profile->rtpip_next++]);
+       if (profile->rtpip_next >= profile->rtpip_index) {
+               profile->rtpip_next = 0;
+       }
+
        profile->inuse++;
        switch_mutex_unlock(profile->flag_mutex);
        switch_mutex_unlock(tech_pvt->flag_mutex);
@@ -637,7 +643,7 @@ switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, private_
                char *p;
 
                if (!sofia_test_pflag(profile, PFLAG_STUN_ENABLED)) {
-                       *ip = switch_core_strdup(pool, profile->rtpip);
+                       *ip = switch_core_strdup(pool, tech_pvt->rtpip);
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Trying to use STUN but its disabled!\n");
                        goto out;
                }
@@ -681,7 +687,7 @@ switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, private_
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Success [%s]:[%d]\n", *ip, *port);
                status = SWITCH_STATUS_SUCCESS;
                if (tech_pvt) {
-                       if (myport == *port && !strcmp(*ip, tech_pvt->profile->rtpip)) {
+                       if (myport == *port && !strcmp(*ip, tech_pvt->rtpip)) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Not Required ip and port match. [%s]:[%d]\n", *ip, *port);
                                if (sofia_test_pflag(profile, PFLAG_STUN_AUTO_DISABLE)) {
                                        sofia_clear_pflag(profile, PFLAG_STUN_ENABLED);
@@ -724,7 +730,7 @@ const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name)
 
 switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int force)
 {
-       char *lookup_rtpip = tech_pvt->profile->rtpip;  /* Pointer to externally looked up address */
+       char *lookup_rtpip = tech_pvt->rtpip;   /* Pointer to externally looked up address */
        switch_port_t sdp_port, rtcp_port;              /* The external port to be sent in the SDP */
        const char *use_ip = NULL;      /* The external IP to be sent in the SDP */
 
@@ -738,16 +744,16 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc
 
        /* Release the local sdp port */
        if (tech_pvt->local_sdp_audio_port) {
-               switch_rtp_release_port(tech_pvt->profile->rtpip, tech_pvt->local_sdp_audio_port);
+               switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_audio_port);
        }
 
        /* Request a local port from the core's allocator */
-       if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(tech_pvt->profile->rtpip))) {
+       if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(tech_pvt->rtpip))) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "No RTP ports available!\n");
                return SWITCH_STATUS_FALSE;
        }
 
-       tech_pvt->local_sdp_audio_ip = tech_pvt->profile->rtpip;
+       tech_pvt->local_sdp_audio_ip = tech_pvt->rtpip;
 
        sdp_port = tech_pvt->local_sdp_audio_port;
 
@@ -771,7 +777,7 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc
                                        switch_nat_add_mapping(tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP, &rtcp_port, SWITCH_FALSE);
                                } else {
                                        /* No NAT detected */
-                                       use_ip = tech_pvt->profile->rtpip;
+                                       use_ip = tech_pvt->rtpip;
                                }
                        } else {
                                /* Address properly resolved, use it as external ip */
@@ -780,7 +786,7 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc
                }
        } else {
                /* No NAT traversal required, use the profile's rtp ip */
-               use_ip = tech_pvt->profile->rtpip;
+               use_ip = tech_pvt->rtpip;
        }
 
        tech_pvt->adv_sdp_audio_port = sdp_port;
@@ -795,7 +801,7 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc
 
 switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, int force)
 {
-       char *lookup_rtpip = tech_pvt->profile->rtpip;  /* Pointer to externally looked up address */
+       char *lookup_rtpip = tech_pvt->rtpip;   /* Pointer to externally looked up address */
        switch_port_t sdp_port;         /* The external port to be sent in the SDP */
        const char *use_ip = NULL;      /* The external IP to be sent in the SDP */
 
@@ -809,11 +815,11 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, in
 
        /* Release the local sdp port */
        if (tech_pvt->local_sdp_video_port) {
-               switch_rtp_release_port(tech_pvt->profile->rtpip, tech_pvt->local_sdp_video_port);
+               switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_video_port);
        }
 
        /* Request a local port from the core's allocator */
-       if (!(tech_pvt->local_sdp_video_port = switch_rtp_request_port(tech_pvt->profile->rtpip))) {
+       if (!(tech_pvt->local_sdp_video_port = switch_rtp_request_port(tech_pvt->rtpip))) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_CRIT, "No RTP ports available!\n");
                return SWITCH_STATUS_FALSE;
        }
@@ -839,7 +845,7 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, in
                                        switch_nat_add_mapping(tech_pvt->local_sdp_video_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE);
                                } else {
                                        /* No NAT detected */
-                                       use_ip = tech_pvt->profile->rtpip;
+                                       use_ip = tech_pvt->rtpip;
                                }
                        } else {
                                /* Address properly resolved, use it as external ip */
@@ -848,7 +854,7 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, in
                }
        } else {
                /* No NAT traversal required, use the profile's rtp ip */
-               use_ip = tech_pvt->profile->rtpip;
+               use_ip = tech_pvt->rtpip;
        }
 
        tech_pvt->adv_sdp_video_port = sdp_port;
@@ -2269,7 +2275,7 @@ void sofia_glue_deactivate_rtp(private_object_t *tech_pvt)
        if (tech_pvt->video_rtp_session) {
                switch_rtp_destroy(&tech_pvt->video_rtp_session);
        } else if (tech_pvt->local_sdp_video_port) {
-               switch_rtp_release_port(tech_pvt->profile->rtpip, tech_pvt->local_sdp_video_port);
+               switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_video_port);
        }
 
 
@@ -2282,7 +2288,7 @@ void sofia_glue_deactivate_rtp(private_object_t *tech_pvt)
        if (tech_pvt->rtp_session) {
                switch_rtp_destroy(&tech_pvt->rtp_session);
        } else if (tech_pvt->local_sdp_audio_port) {
-               switch_rtp_release_port(tech_pvt->profile->rtpip, tech_pvt->local_sdp_audio_port);
+               switch_rtp_release_port(tech_pvt->rtpip, tech_pvt->local_sdp_audio_port);
        }
 
        if (tech_pvt->local_sdp_audio_port > 0 && !zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) {
@@ -4470,7 +4476,7 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
 
                        tech_pvt->adv_sdp_audio_ip = tech_pvt->extrtpip = (char *) ip;
                        tech_pvt->adv_sdp_audio_port = tech_pvt->local_sdp_audio_port = atoi(port);
-                       tech_pvt->local_sdp_audio_ip = tech_pvt->profile->rtpip;
+                       tech_pvt->local_sdp_audio_ip = tech_pvt->rtpip;
 
                        if (r_ip && r_port) {
                                tech_pvt->remote_sdp_audio_ip = (char *) r_ip;