From: Ghislain MARY Date: Thu, 11 Oct 2012 13:35:52 +0000 (+0200) Subject: Allow random selection of media ports without configured ranges. X-Git-Url: http://sjero.net/git/?p=linphone;a=commitdiff_plain;h=3910894b7cf4ae3d8c596fb7106919b5f4886470 Allow random selection of media ports without configured ranges. --- diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index d0667251..a930b1be 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -298,17 +298,35 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCa return _create_local_media_description(lc,call,id,id); } -static int find_port_offset(LinphoneCore *lc){ +static int find_port_offset(LinphoneCore *lc, SalStreamType type){ int offset; MSList *elem; - int audio_port; + int tried_port; + int existing_port; bool_t already_used=FALSE; for(offset=0;offset<100;offset+=2){ - audio_port=linphone_core_get_audio_port (lc)+offset; + switch (type) { + default: + case SalAudio: + tried_port=linphone_core_get_audio_port (lc)+offset; + break; + case SalVideo: + tried_port=linphone_core_get_video_port (lc)+offset; + break; + } already_used=FALSE; for(elem=lc->calls;elem!=NULL;elem=elem->next){ LinphoneCall *call=(LinphoneCall*)elem->data; - if (call->audio_port==audio_port) { + switch (type) { + default: + case SalAudio: + existing_port = call->audio_port; + break; + case SalVideo: + existing_port = call->video_port; + break; + } + if (existing_port==tried_port) { already_used=TRUE; break; } @@ -322,8 +340,54 @@ static int find_port_offset(LinphoneCore *lc){ return offset; } +static int select_random_port(LinphoneCore *lc, SalStreamType type) { + MSList *elem; + int nb_tries; + int tried_port = 0; + int existing_port = 0; + int min_port = 0, max_port = 0; + bool_t already_used = FALSE; + + switch (type) { + default: + case SalAudio: + linphone_core_get_audio_port_range(lc, &min_port, &max_port); + break; + case SalVideo: + linphone_core_get_video_port_range(lc, &min_port, &max_port); + break; + } + tried_port = (rand() % (max_port - min_port) + min_port) & ~0x1; + if (tried_port < min_port) tried_port = min_port + 2; + for (nb_tries = 0; nb_tries < 100; nb_tries++) { + for (elem = lc->calls; elem != NULL; elem = elem->next) { + LinphoneCall *call = (LinphoneCall *)elem->data; + switch (type) { + default: + case SalAudio: + existing_port = call->audio_port; + break; + case SalVideo: + existing_port = call->video_port; + break; + } + if (existing_port == tried_port) { + already_used = TRUE; + break; + } + } + if (!already_used) break; + } + if (nb_tries == 100) { + ms_error("Could not find any free port!"); + return -1; + } + return tried_port; +} + static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){ int port_offset; + int min_port, max_port; call->magic=linphone_call_magic; call->refcnt=1; call->state=LinphoneCallIdle; @@ -333,10 +397,26 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, call->log=linphone_call_log_new(call, from, to); call->owns_call_log=TRUE; linphone_core_notify_all_friends(call->core,LinphoneStatusOnThePhone); - port_offset=find_port_offset (call->core); - if (port_offset==-1) return; - call->audio_port=linphone_core_get_audio_port(call->core)+port_offset; - call->video_port=linphone_core_get_video_port(call->core)+port_offset; + linphone_core_get_audio_port_range(call->core, &min_port, &max_port); + if (min_port == max_port) { + /* Used fixed RTP audio port. */ + port_offset=find_port_offset (call->core, SalAudio); + if (port_offset==-1) return; + call->audio_port=linphone_core_get_audio_port(call->core)+port_offset; + } else { + /* Select random RTP audio port in the specified range. */ + call->audio_port = select_random_port(call->core, SalAudio); + } + linphone_core_get_video_port_range(call->core, &min_port, &max_port); + if (min_port == max_port) { + /* Used fixed RTP video port. */ + port_offset=find_port_offset (call->core, SalVideo); + if (port_offset==-1) return; + call->video_port=linphone_core_get_video_port(call->core)+port_offset; + } else { + /* Select random RTP video port in the specified range. */ + call->video_port = select_random_port(call->core, SalVideo); + } linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO); linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2936ca0b..db7a8ea7 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -624,18 +624,29 @@ static void sip_config_read(LinphoneCore *lc) static void rtp_config_read(LinphoneCore *lc) { - int port; + int min_port, max_port; int jitt_comp; int nortp_timeout; bool_t rtp_no_xmit_on_audio_mute; bool_t adaptive_jitt_comp_enabled; - port=lp_config_get_int(lc->config,"rtp","audio_rtp_port",7078); - linphone_core_set_audio_port(lc,port); + if (lp_config_get_range(lc->config, "rtp", "audio_rtp_port", &min_port, &max_port, 7078, 7078) == TRUE) { + if (min_port <= 0) min_port = 1; + if (max_port > 65535) max_port = 65535; + linphone_core_set_audio_port_range(lc, min_port, max_port); + } else { + min_port = lp_config_get_int(lc->config, "rtp", "audio_rtp_port", 7078); + linphone_core_set_audio_port(lc, min_port); + } - port=lp_config_get_int(lc->config,"rtp","video_rtp_port",9078); - if (port==0) port=9078; - linphone_core_set_video_port(lc,port); + if (lp_config_get_range(lc->config, "rtp", "video_rtp_port", &min_port, &max_port, 9078, 9078) == TRUE) { + if (min_port <= 0) min_port = 1; + if (max_port > 65535) max_port = 65535; + linphone_core_set_video_port_range(lc, min_port, max_port); + } else { + min_port = lp_config_get_int(lc->config, "rtp", "video_rtp_port", 9078); + linphone_core_set_video_port(lc, min_port); + } jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60); linphone_core_set_audio_jittcomp(lc,jitt_comp); @@ -1440,7 +1451,18 @@ int linphone_core_get_video_jittcomp(LinphoneCore *lc) **/ int linphone_core_get_audio_port(const LinphoneCore *lc) { - return lc->rtp_conf.audio_rtp_port; + return lc->rtp_conf.audio_rtp_min_port; +} + +/** + * Get the audio port range from which is randomly chosen the UDP port used for audio streaming. + * + * @ingroup network_parameters + */ +void linphone_core_get_audio_port_range(const LinphoneCore *lc, int *min_port, int *max_port) +{ + *min_port = lc->rtp_conf.audio_rtp_min_port; + *max_port = lc->rtp_conf.audio_rtp_max_port; } /** @@ -1449,7 +1471,18 @@ int linphone_core_get_audio_port(const LinphoneCore *lc) * @ingroup network_parameters **/ int linphone_core_get_video_port(const LinphoneCore *lc){ - return lc->rtp_conf.video_rtp_port; + return lc->rtp_conf.video_rtp_min_port; +} + +/** + * Get the video port range from which is randomly chosen the UDP port used for video streaming. + * + * @ingroup network_parameters + */ +void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, int *max_port) +{ + *min_port = lc->rtp_conf.video_rtp_min_port; + *max_port = lc->rtp_conf.video_rtp_max_port; } @@ -1501,7 +1534,16 @@ void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc,bool_t rtp_no_ **/ void linphone_core_set_audio_port(LinphoneCore *lc, int port) { - lc->rtp_conf.audio_rtp_port=port; + lc->rtp_conf.audio_rtp_min_port=lc->rtp_conf.audio_rtp_max_port=port; +} + +/** + * Sets the UDP port range from which to randomly select the port used for audio streaming. + */ +void linphone_core_set_audio_port_range(LinphoneCore *lc, int min_port, int max_port) +{ + lc->rtp_conf.audio_rtp_min_port=min_port; + lc->rtp_conf.audio_rtp_max_port=max_port; } /** @@ -1510,7 +1552,16 @@ void linphone_core_set_audio_port(LinphoneCore *lc, int port) * @ingroup network_parameters **/ void linphone_core_set_video_port(LinphoneCore *lc, int port){ - lc->rtp_conf.video_rtp_port=port; + lc->rtp_conf.video_rtp_min_port=lc->rtp_conf.video_rtp_max_port=port; +} + +/** + * Sets the UDP port range from which to randomly select the port used for video streaming. + */ +void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_port) +{ + lc->rtp_conf.video_rtp_min_port=min_port; + lc->rtp_conf.video_rtp_max_port=max_port; } /** @@ -4556,8 +4607,16 @@ void sip_config_uninit(LinphoneCore *lc) void rtp_config_uninit(LinphoneCore *lc) { rtp_config_t *config=&lc->rtp_conf; - lp_config_set_int(lc->config,"rtp","audio_rtp_port",config->audio_rtp_port); - lp_config_set_int(lc->config,"rtp","video_rtp_port",config->video_rtp_port); + if (config->audio_rtp_min_port == config->audio_rtp_max_port) { + lp_config_set_int(lc->config, "rtp", "audio_rtp_port", config->audio_rtp_min_port); + } else { + lp_config_set_range(lc->config, "rtp", "audio_rtp_port", config->audio_rtp_min_port, config->audio_rtp_max_port); + } + if (config->video_rtp_min_port == config->video_rtp_max_port) { + lp_config_set_int(lc->config, "rtp", "video_rtp_port", config->video_rtp_min_port); + } else { + lp_config_set_range(lc->config, "rtp", "video_rtp_port", config->video_rtp_min_port, config->video_rtp_max_port); + } lp_config_set_int(lc->config,"rtp","audio_jitt_comp",config->audio_jitt_comp); lp_config_set_int(lc->config,"rtp","video_jitt_comp",config->video_jitt_comp); lp_config_set_int(lc->config,"rtp","nortp_timeout",config->nortp_timeout); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 0209a377..1849c083 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1115,14 +1115,22 @@ void linphone_core_set_video_jittcomp(LinphoneCore *lc, int value); int linphone_core_get_audio_port(const LinphoneCore *lc); +void linphone_core_get_audio_port_range(const LinphoneCore *lc, int *min_port, int *max_port); + int linphone_core_get_video_port(const LinphoneCore *lc); +void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, int *max_port); + int linphone_core_get_nortp_timeout(const LinphoneCore *lc); void linphone_core_set_audio_port(LinphoneCore *lc, int port); +void linphone_core_set_audio_port_range(LinphoneCore *lc, int min_port, int max_port); + void linphone_core_set_video_port(LinphoneCore *lc, int port); +void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_port); + void linphone_core_set_nortp_timeout(LinphoneCore *lc, int port); void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc, bool_t use_info); diff --git a/coreapi/private.h b/coreapi/private.h index 82ebf363..028b408f 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -398,8 +398,10 @@ typedef struct sip_config typedef struct rtp_config { - int audio_rtp_port; - int video_rtp_port; + int audio_rtp_min_port; + int audio_rtp_max_port; + int video_rtp_min_port; + int video_rtp_max_port; int audio_jitt_comp; /*jitter compensation*/ int video_jitt_comp; /*jitter compensation*/ int nortp_timeout;