]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 221266 via svnmerge from
authorTerry Wilson <twilson@digium.com>
Wed, 30 Sep 2009 18:58:49 +0000 (18:58 +0000)
committerTerry Wilson <twilson@digium.com>
Wed, 30 Sep 2009 18:58:49 +0000 (18:58 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

................
  r221266 | twilson | 2009-09-30 12:52:30 -0500 (Wed, 30 Sep 2009) | 32 lines

  Merged revisions 221086 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.4

  ........
    r221086 | twilson | 2009-09-30 09:49:11 -0500 (Wed, 30 Sep 2009) | 25 lines

    Change the SSRC by default when our media stream changes

    Be default, change SSRC when doing an audio stream changes Asterisk doesn't
    honor marker bit when reinvited to already-bridged RTP streams,resulting in
    far-end stack discarding packets with "old" timestamps that areactually part of
    a new stream.  This patch sends AST_CONTROL_SRCUPDATE whenever there is a
    reinvite, unless the 'constantssrc' is set to true in sip.conf.

    The original issue reported to Digium support detailed the following situation:
    ITSP <-> Asterisk 1.4.26.2 <-> SIP-based Application Server Call comes in
    fromITSP, Asterisk dials the app server which sends a re-invite back
    toAsterisk--not to negotiate to send media directly to the ITSP, but to
    indicatethat it's changing the stream it's sending to Asterisk.  The app
    servergenerates a new SSRC, sequence numbers, timestamps, and sets the marker
    bit on the new stream.  Asterisk passes through the teimstamp of the new stream,
    butdoes not reset the SSRC, sequence numbers, or set the marker bit.

    When the timestamp on the new stream is older than the timestamp on the
    originalstream, the ITSP (which doesn't know there has been any change) discards
    the newframes because it thinks they are too old.  This patch addresses this by
    changing the SSRC on a stream update unless constantssrc=true is set in
    sip.conf.

    Review: https://reviewboard.asterisk.org/r/374/
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.1@221302 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
configs/sip.conf.sample
include/asterisk/rtp.h
main/rtp.c

index 029c1572846db53691516926f05cdfee593558e4..688ff81efdc9a37765ea15bb736aba7b0d460ce5 100644 (file)
@@ -1061,6 +1061,7 @@ struct sip_auth {
 #define SIP_PAGE2_RTCACHEFRIENDS       (1 << 0)        /*!< GP: Should we keep RT objects in memory for extended time? */
 #define SIP_PAGE2_RTAUTOCLEAR          (1 << 2)        /*!< GP: Should we clean memory from peers after expiry? */
 /* Space for addition of other realtime flags in the future */
+#define SIP_PAGE2_CONSTANT_SSRC     (1 << 8)   /*!< GDP: Don't change SSRC on reinvite */
 #define SIP_PAGE2_STATECHANGEQUEUE     (1 << 9)        /*!< D: Unsent state pending change exists */
 
 #define SIP_PAGE2_RPORT_PRESENT         (1 << 10)       /*!< Was rport received in the Via header? */
@@ -1092,7 +1093,7 @@ struct sip_auth {
        (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 | SIP_PAGE2_VIDEOSUPPORT_ALWAYS)
+       SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_CONSTANT_SSRC)
 
 /*@}*/ 
 
@@ -4525,6 +4526,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;
@@ -4535,6 +4539,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);
+               }
        }
        if (dialog->trtp) { /* Realtime text */
                ast_rtp_setdtmf(dialog->trtp, 0);
@@ -18501,6 +18508,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;
                                ast_debug(1, "Hm....  No sdp for the moment\n");
@@ -18549,6 +18557,14 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                                ast_debug(1, "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;
                        ast_debug(2, "No SDP in Invite, third party call control\n");
@@ -21795,6 +21811,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;
 
@@ -23173,6 +23192,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);
                } else if (!strcasecmp(v->name, "session-timers")) {
                        int i = (int) str2stmode(v->value); 
                        if (i < 0) {
index a56941e71ccfa73147045cf4dd53431d67fcb8ca..7dd8f283865e2a130f286409445d0723f16d2d52 100644 (file)
@@ -633,6 +633,8 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
                                 ; (observed with Microsoft OCS). By default this option is
                                 ; off.
 
+;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
index f9076d54b12336fabcc34e4d59797fdfedbfe9fc..3037c5e32972df230ad6897003428048327fe99b 100644 (file)
@@ -210,6 +210,9 @@ int ast_rtp_sendcng(struct ast_rtp *rtp, int level);
 
 int ast_rtp_setqos(struct ast_rtp *rtp, int tos, int cos, char *desc);
 
+/*! \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: */
index dcd6807b20a78d4ce601bb047840a9a5f5bfbadc..de50a0397a9e8e07594a4cc0a429a9f095c3c0a5 100644 (file)
@@ -181,6 +181,7 @@ struct ast_rtp {
        struct sockaddr_in strict_rtp_address;  /*!< Remote address information for strict RTP purposes */
 
        int set_marker_bit:1;           /*!< Whether to set the marker bit or not */
+       unsigned int constantssrc:1;
        struct rtp_red *red;
 };
 
@@ -2604,12 +2605,19 @@ int ast_rtp_setqos(struct ast_rtp *rtp, int type_of_service, int class_of_servic
        return ast_netsock_set_qos(rtp->s, type_of_service, class_of_service, desc);
 }
 
+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)