diff options
-rw-r--r-- | channels/chan_sip.c | 52 | ||||
-rw-r--r-- | configs/sip.conf.sample | 34 |
2 files changed, 65 insertions, 21 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index a807d1a62..6a919ef6c 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -981,6 +981,7 @@ struct sip_auth { #define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) /*!< GP: Allow subscriptions from this peer? */ #define SIP_PAGE2_ALLOWOVERLAP (1 << 17) /*!< DP: Allow overlap dialing ? */ #define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) /*!< GP: Only issue MWI notification if subscribed to */ +#define SIP_PAGE2_IGNORESDPVERSION (1 << 19) /*!< GDP: Ignore the SDP session version number we receive and treat all sessions as new */ #define SIP_PAGE2_T38SUPPORT (7 << 20) /*!< GDP: T38 Fax Passthrough Support */ #define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) /*!< GDP: T38 Fax Passthrough Support */ @@ -999,9 +1000,9 @@ struct sip_auth { #define SIP_PAGE2_UDPTL_DESTINATION (1 << 30) /*!< DP: Use source IP of RTP as destination if NAT is enabled */ #define SIP_PAGE2_FLAGS_TO_COPY \ - (SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ - SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | \ - SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_UDPTL_DESTINATION) + (SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \ + SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | \ + SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_UDPTL_DESTINATION) /*@}*/ @@ -6761,13 +6762,39 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action return -1; } - if (p->sessionversion_remote < 0 || p->sessionversion_remote != rua_version) { - p->sessionversion_remote = rua_version; + /* we need to check the SDP version number the other end sent us; + * our rules for deciding what to accept are a bit complex. + * + * 1) if 'ignoresdpversion' has been set for this dialog, then + * we will just accept whatever they sent and assume it is + * a modification of the session, even if it is not + * 2) otherwise, if this is the first SDP we've seen from them + * we accept it + * 3) otherwise, if the new SDP version number is higher than the + * old one, we accept it + * 4) otherwise, if this SDP is in response to us requesting a switch + * to T.38, we accept the SDP, but also generate a warning message + * that this peer should have the 'ignoresdpversion' option set, + * because it is not following the SDP offer/answer RFC; if we did + * not request a switch to T.38, then we stop parsing the SDP, as it + * has not changed from the previous version + */ + + if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) || + (p->sessionversion_remote < 0) || + (p->sessionversion_remote < rua_version)) { + p->sessionversion_remote = rua_version; p->session_modify = TRUE; - } else if (p->sessionversion_remote == rua_version) { - p->session_modify = FALSE; - ast_debug(2, "SDP version number same as previous SDP\n"); - return 0; + } else { + if (p->t38.state == T38_LOCAL_REINVITE) { + p->sessionversion_remote = rua_version; + p->session_modify = TRUE; + ast_log(LOG_WARNING, "Call %s responded to our T.38 reinvite without changing SDP version; 'ignoresdpversion' should be set for this peer.\n", p->callid); + } else { + p->session_modify = FALSE; + ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid); + return 0; + } } /* Try to find first media stream */ @@ -13237,6 +13264,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct ast_cli(fd, " User=Phone : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE))); ast_cli(fd, " Video Support: %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT))); ast_cli(fd, " Text Support : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT))); + ast_cli(fd, " Ign SDP ver : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION))); ast_cli(fd, " Trust RPID : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID))); ast_cli(fd, " Send RPID : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_SENDRPID))); ast_cli(fd, " Subscriptions: %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); @@ -13439,6 +13467,7 @@ static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args ast_cli(a->fd, " Sess-Refresh : %s\n", strefresher2str(user->stimer.st_ref)); ast_cli(a->fd, " Sess-Expires : %d secs\n", user->stimer.st_max_se); ast_cli(a->fd, " Sess-Min-SE : %d secs\n", user->stimer.st_min_se); + ast_cli(a->fd, " Ign SDP ver : %s\n", cli_yesno(ast_test_flag(&user->flags[1], SIP_PAGE2_IGNORESDPVERSION))); ast_cli(a->fd, " Codec Order : ("); print_codec_to_cli(a->fd, &user->prefs); @@ -13590,6 +13619,7 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_ ast_cli(a->fd, " Videosupport: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT))); ast_cli(a->fd, " Textsupport: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT))); ast_cli(a->fd, " AutoCreate Peer: %s\n", cli_yesno(autocreatepeer)); + ast_cli(a->fd, " Ignore SDP sess. ver.: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION))); ast_cli(a->fd, " Match Auth Username: %s\n", cli_yesno(global_match_auth_username)); ast_cli(a->fd, " Allow unknown access: %s\n", cli_yesno(global_allowguest)); ast_cli(a->fd, " Allow subscriptions: %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))); @@ -20496,6 +20526,9 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask } else if (!strcasecmp(v->name, "allowsubscribe")) { ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); + } else if (!strcasecmp(v->name, "ignoresdpversion")) { + ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION); + ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION); } else if (!strcasecmp(v->name, "t38pt_udptl")) { ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); @@ -21613,6 +21646,7 @@ static int reload_config(enum channelreloadreason reason) ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT); + ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION); /* Read the [general] config section of sip.conf (or from realtime config) */ for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index 0fb6afe54..a769f189e 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -570,6 +570,15 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; instead of INVITE. This can be combined with 'nonat', as ; 'canreinvite=update,nonat'. It implies 'yes'. +;ignoresdpversion=yes ; By default, Asterisk will honor the session version + ; number in SDP packets and will only modify the SDP + ; session if the version number changes. This option will + ; force asterisk to ignore the SDP session version number + ; and treat all SDP data as new data. This is required + ; for devices that send us non standard SDP packets + ; (observed with Microsoft OCS). By default this option is + ; off. + ;----------------------------------------- REALTIME SUPPORT ------------------------ ; For additional information on ARA, the Asterisk Realtime Architecture, ; please read realtime.txt and extconfig.txt in the /doc directory of the @@ -729,12 +738,19 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; subscribecontext subscribecontext ; videosupport videosupport ; maxcallbitrate maxcallbitrate -; rfc2833compensate mailbox -; session-timers busylevel -; session-expires -; session-minse template -; session-refresher fromdomain -; t38pt_usertpsource regexten +; rfc2833compensate rfc2833compensate +; ignoresdpversion ignoresdpversion +; session-timers session-timers +; session-expires session-expires +; session-minse session-minse +; session-refresher session-refresher +; t38pt_usertpsource t38pt_usertpsource +; regexten +; template +; fromdomain +; regexten +; mailbox +; busylevel ; fromuser ; host ; port @@ -745,17 +761,11 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; rtpholdtimeout ; sendrpid ; outboundproxy -; rfc2833compensate ; callbackextension ; registertrying -; session-timers -; session-expires -; session-minse -; session-refresher ; timert1 ; timerb ; qualifyfreq -; t38pt_usertpsource ; contactpermit ; Limit what a host may register as (a neat trick ; contactdeny ; is to register at the same IP as a SIP provider, ; ; then call oneself, and get redirected to that |