From 22569d4ac5f81b945871fa4ba49d79c5149ac284 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 10 Jun 2010 17:08:29 -0500 Subject: [PATCH] add multiple rtp-ip support to sofia profiles 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 | 41 +++++++++++++++++------- src/mod/endpoints/mod_sofia/mod_sofia.h | 8 ++++- src/mod/endpoints/mod_sofia/sofia.c | 14 +++++--- src/mod/endpoints/mod_sofia/sofia_glue.c | 38 +++++++++++++--------- 4 files changed, 67 insertions(+), 34 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 1d274c23d8..c497632f34 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -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, " %s\n", switch_str_nil(profile->context)); stream->write_function(stream, " %s\n", zstr(profile->challenge_realm) ? "auto_to" : profile->challenge_realm); - stream->write_function(stream, " %s\n", switch_str_nil(profile->rtpip)); + for (x = 0; x < profile->rtpip_index; x++) { + stream->write_function(stream, " %s\n", switch_str_nil(profile->rtpip[x])); + } stream->write_function(stream, " %s\n", profile->extrtpip); stream->write_function(stream, " %s\n", switch_str_nil(profile->sipip)); stream->write_function(stream, " %s\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); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index d2c34cf9a9..fd00a21c7d 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -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; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 7dc4eef1bf..ac22a23544 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -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) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 751e7d0e48..c2aaf5265e 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -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;