diff options
-rw-r--r-- | channels/chan_sip.c | 24 | ||||
-rw-r--r-- | configs/sip.conf.sample | 5 | ||||
-rw-r--r-- | include/asterisk/rtp.h | 3 | ||||
-rw-r--r-- | main/rtp.c | 10 |
4 files changed, 39 insertions, 3 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 15984fb0e..0e8c24a01 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -807,10 +807,12 @@ struct sip_auth { #define SIP_PAGE2_UDPTL_DESTINATION (1 << 28) /*!< 28: Use source IP of RTP as destination if NAT is enabled */ #define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) /*!< 29: Has a dialog been established? */ #define SIP_PAGE2_RPORT_PRESENT (1 << 30) /*!< 30: Was rport received in the Via header? */ +#define SIP_PAGE2_CONSTANT_SSRC (1 << 31) /*!< 31: Don't change SSRC on reinvite */ #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_UDPTL_DESTINATION) + SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | \ + SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_CONSTANT_SSRC) /* SIP packet flags */ #define SIP_PKT_DEBUG (1 << 0) /*!< Debug this packet */ @@ -2939,6 +2941,9 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer) ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); + if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { + ast_rtp_set_constantssrc(dialog->rtp); + } /* Set Frame packetization */ ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); dialog->autoframing = peer->autoframing; @@ -2949,6 +2954,9 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer) ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); + if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { + ast_rtp_set_constantssrc(dialog->vrtp); + } } ast_string_field_set(dialog, peername, peer->name); @@ -14854,6 +14862,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); return -1; } + ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE); } else { p->jointcapability = p->capability; if (option_debug > 2) @@ -14908,6 +14917,14 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); return -1; } + if (ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC)) { + if (p->rtp) { + ast_rtp_set_constantssrc(p->rtp); + } + if (p->vrtp) { + ast_rtp_set_constantssrc(p->vrtp); + } + } } else { /* No SDP in invite, call control session */ p->jointcapability = p->capability; if (option_debug > 1) @@ -17366,6 +17383,9 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); + } else if (!strcasecmp(v->name, "constantssrc")) { + ast_set_flag(&mask[1], SIP_PAGE2_CONSTANT_SSRC); + ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC); } else res = 0; @@ -18422,6 +18442,8 @@ static int reload_config(enum channelreloadreason reason) default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; } else if (!strcasecmp(v->name, "matchexterniplocally")) { global_matchexterniplocally = ast_true(v->value); + } else if (!strcasecmp(v->name, "constantssrc")) { + ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC); } } diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index 741ae7570..57d965503 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -365,6 +365,8 @@ 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'. +;constantssrc=yes ; Don't change the RTP SSRC when our media stream changes + ;----------------------------------------- REALTIME SUPPORT ------------------------ ; For additional information on ARA, the Asterisk Realtime Architecture, ; please read realtime.txt and extconfig.txt in the /doc directory of the @@ -524,7 +526,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; maxcallbitrate maxcallbitrate ; rfc2833compensate mailbox ; t38pt_usertpsource username -; template +; constantssrc template ; fromdomain ; regexten ; fromuser @@ -537,6 +539,7 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; sendrpid ; outboundproxy ; rfc2833compensate +; constantssrc ; 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, diff --git a/include/asterisk/rtp.h b/include/asterisk/rtp.h index f9da4bdac..fada0bcb4 100644 --- a/include/asterisk/rtp.h +++ b/include/asterisk/rtp.h @@ -179,6 +179,9 @@ int ast_rtp_sendcng(struct ast_rtp *rtp, int level); int ast_rtp_settos(struct ast_rtp *rtp, int tos); +/*! \brief When changing sources, don't generate a new SSRC */ +void ast_rtp_set_constantssrc(struct ast_rtp *rtp); + void ast_rtp_new_source(struct ast_rtp *rtp); /*! \brief Setting RTP payload types from lines in a SDP description: */ diff --git a/main/rtp.c b/main/rtp.c index c1dc445b7..770292a4f 100644 --- a/main/rtp.c +++ b/main/rtp.c @@ -174,6 +174,7 @@ struct ast_rtp { struct ast_codec_pref pref; struct ast_rtp *bridged; /*!< Who we are Packet bridged to */ int set_marker_bit:1; /*!< Whether to set the marker bit or not */ + unsigned int constantssrc:1; }; /* Forward declarations */ @@ -2054,12 +2055,19 @@ int ast_rtp_settos(struct ast_rtp *rtp, int tos) return res; } +void ast_rtp_set_constantssrc(struct ast_rtp *rtp) +{ + rtp->constantssrc = 1; +} + void ast_rtp_new_source(struct ast_rtp *rtp) { if (rtp) { rtp->set_marker_bit = 1; + if (!rtp->constantssrc) { + rtp->ssrc = ast_random(); + } } - return; } void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them) |