From c3fdb98f07e2ae5223a4780b025f698fe6fb7154 Mon Sep 17 00:00:00 2001
From: Alexandre Savard <alexandresavard@alexandresavard-desktop.(none)>
Date: Thu, 25 Mar 2010 15:06:52 -0400
Subject: [PATCH] [#3071] Fix segfault on receiving INVITE without SDP, send
 488 error

---
 sflphone-common/src/sip/sdp.cpp         | 23 +++++++++++++++
 sflphone-common/src/sip/sdp.h           | 19 ++++++-------
 sflphone-common/src/sip/sipvoiplink.cpp | 19 +++----------
 sflphone-common/src/sip/sipvoiplink.h   | 38 ++++++++++++-------------
 4 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/sflphone-common/src/sip/sdp.cpp b/sflphone-common/src/sip/sdp.cpp
index 94c8e64634..5b3066212a 100644
--- a/sflphone-common/src/sip/sdp.cpp
+++ b/sflphone-common/src/sip/sdp.cpp
@@ -211,6 +211,10 @@ int Sdp::receiving_initial_offer (pjmedia_sdp_session* remote, CodecOrder select
 
     pj_status_t status;
 
+	if (!remote) {
+		return !PJ_SUCCESS;
+	}
+
     // Create the SDP negociator instance by calling
     // pjmedia_sdp_neg_create_w_remote_offer with the remote offer, and by providing the local offer ( optional )
 
@@ -531,6 +535,19 @@ AudioCodec* Sdp::get_session_media (void)
 }
 
 
+pj_status_t Sdp::start_negociation()
+{
+	pj_status_t status;
+
+	if (_negociator) {
+		status = pjmedia_sdp_neg_negotiate(_pool, _negociator, 0);
+	}
+	else {
+		status = !PJ_SUCCESS;
+	}
+
+	return status;
+}
 
 void Sdp::toString (void)
 {
@@ -648,6 +665,9 @@ void Sdp::set_media_transport_info_from_remote_sdp (const pjmedia_sdp_session *r
 
     _info ("SDP: Fetching media from sdp");
 
+    if(!remote_sdp)
+    	return;
+
     pjmedia_sdp_media *r_media;
 
     this->get_remote_sdp_media_from_offer (remote_sdp, &r_media);
@@ -667,6 +687,9 @@ void Sdp::get_remote_sdp_media_from_offer (const pjmedia_sdp_session* remote_sdp
 {
     int count, i;
 
+    if(!remote_sdp)
+    	return;
+
     count = remote_sdp->media_count;
     *r_media =  NULL;
 
diff --git a/sflphone-common/src/sip/sdp.h b/sflphone-common/src/sip/sdp.h
index e3932751aa..8c81168adf 100644
--- a/sflphone-common/src/sip/sdp.h
+++ b/sflphone-common/src/sip/sdp.h
@@ -166,10 +166,7 @@ class Sdp {
          * @return pj_status_t  0 on success
          *                      1 otherwise
          */
-        pj_status_t start_negociation( void ){
-            return pjmedia_sdp_neg_negotiate(
-                       _pool, _negociator, 0);
-        }
+        pj_status_t start_negociation( void );
 
          /*
          * Retrieve the negociated sdp offer from the sip payload.
@@ -221,7 +218,7 @@ class Sdp {
 
         std::vector<sdpMedia*> get_session_media_list (void) { return _session_media; }
 
-	void get_remote_sdp_crypto_from_offer (const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer);
+        void get_remote_sdp_crypto_from_offer (const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer);
 
     private:
         /** Codec Map */
@@ -253,13 +250,13 @@ class Sdp {
         /** Local audio port */
         int _local_extern_audio_port;
 
-        /** Remote's audio port */
+        /** Remote audio port */
         unsigned int _remote_audio_port;
 
         std::string _zrtp_hello_hash;
 
-	/** "a=crypto" sdes local attributes obtained from AudioSrtpSession */
-	std::vector<std::string> _srtp_crypto;
+        /** "a=crypto" sdes local attributes obtained from AudioSrtpSession */
+        std::vector<std::string> _srtp_crypto;
         
         Sdp(const Sdp&); //No Copy Constructor
         Sdp& operator=(const Sdp&); //No Assignment Operator
@@ -350,12 +347,12 @@ class Sdp {
         void get_remote_sdp_media_from_offer (const pjmedia_sdp_session* r_sdp, pjmedia_sdp_media** r_media);
 
 	
-	/* 
+        /*
          * Adds a sdes attribute to the given media section.
          *
          * @param media The media to add the srtp attribute to 
-	 */
-	void sdp_add_sdes_attribute(std::vector<std::string>& crypto);
+         */
+        void sdp_add_sdes_attribute(std::vector<std::string>& crypto);
 
         /* 
          * Adds a zrtp-hash  attribute to 
diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp
index 4d068c4862..c38a29e979 100644
--- a/sflphone-common/src/sip/sipvoiplink.cpp
+++ b/sflphone-common/src/sip/sipvoiplink.cpp
@@ -820,30 +820,20 @@ SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl)
 bool
 SIPVoIPLink::answer (const CallID& id)
 {
-    SIPCall *call;
     pj_status_t status;
     pjsip_tx_data *tdata;
-    Sdp *local_sdp;
     pjsip_inv_session *inv_session;
 
-    _debug ("SIPVoIPLink::answer: start answering ");
+    _debug ("UserAgent: Answering call %s", id.c_str());
 
-    call = getSIPCall (id);
+    SIPCall *call = getSIPCall (id);
 
     if (call==0) {
-        _debug ("! SIP Failure: SIPCall doesn't exists");
+        _debug ("UserAgent: SIPCall %s doesn't exists while answering", id.c_str());
         return false;
     }
 
-    local_sdp = call->getLocalSDP();
-
-    /*
-    try {
-        call->getAudioRtp()->initAudioRtpSession (call);
-    } catch (...) {
-        _debug ("Failed to create rtp thread from answer");
-    }
-    */
+    Sdp *local_sdp = call->getLocalSDP();
 
     inv_session = call->getInvSession();
 
@@ -3683,7 +3673,6 @@ mod_on_rx_request (pjsip_rx_data *rdata)
         return false;
     }
 
-
     /* Create the local dialog (UAS) */
     status = pjsip_dlg_create_uas (pjsip_ua_instance(), rdata, NULL, &dialog);
     if (status != PJ_SUCCESS) {
diff --git a/sflphone-common/src/sip/sipvoiplink.h b/sflphone-common/src/sip/sipvoiplink.h
index 8a3e45acd7..119c83c3dc 100644
--- a/sflphone-common/src/sip/sipvoiplink.h
+++ b/sflphone-common/src/sip/sipvoiplink.h
@@ -422,7 +422,7 @@ class SIPVoIPLink : public VoIPLink
 	 * General Sip transport creation method according to the 
 	 * transport type specified in account settings
 	 * @param id The account id for which a transport must
-         * be created.
+     * be created.
 	 */
 	bool createSipTransport(AccountID id);
 
@@ -436,28 +436,28 @@ class SIPVoIPLink : public VoIPLink
 	 */
 	bool addTransportToMap(std::string key, pjsip_transport* transport);
 
-        /** 
+     /**
 	 * Create SIP UDP transport from account's setting
 	 * @param id The account id for which a transport must
-         * be created.
+     * be created.
 	 * @return pj_status_t PJ_SUCCESS on success 
 	 */
         int createUdpTransport (AccountID = "");
 
-        /**
-         * Create a TLS transport from the default TLS listener from
-         * @param id The account id for which a transport must
-         * be created.
-         * @return pj_status_t PJ_SUCCESS on success 
-         */
-        pj_status_t createTlsTransport(const AccountID& id,  std::string remoteAddr);
+     /**
+      * Create a TLS transport from the default TLS listener from
+      * @param id The account id for which a transport must
+      * be created.
+      * @return pj_status_t PJ_SUCCESS on success
+      */
+     pj_status_t createTlsTransport(const AccountID& id,  std::string remoteAddr);
 
 	/**
-         * Create a UDP transport using stun server to resove public address
-         * @param id The account id for which a transport must
-         * be created.
-         * @return pj_status_t PJ_SUCCESS on success 
-         */
+     * Create a UDP transport using stun server to resove public address
+     * @param id The account id for which a transport must
+     * be created.
+     * @return pj_status_t PJ_SUCCESS on success
+     */
 	pj_status_t createAlternateUdpTransport (AccountID id);
 
 
@@ -474,11 +474,11 @@ class SIPVoIPLink : public VoIPLink
 	EventThread* _evThread;
 	ost::Mutex _mutexSIP;
 
-        /* Number of SIP accounts connected to the link */
-        int _clients;
+    /* Number of SIP accounts connected to the link */
+    int _clients;
         
-        /* 
-         * Get the correct address to use (ie advertised) from 
+    /*
+     * Get the correct address to use (ie advertised) from
          * a uri. The corresponding transport that should be used
          * with that uri will be discovered. 
          *
-- 
GitLab