aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c24
-rw-r--r--configs/sip.conf.sample5
-rw-r--r--include/asterisk/rtp.h3
-rw-r--r--main/rtp.c10
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)