aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c52
-rw-r--r--configs/sip.conf.sample34
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