Update talk to 51314459

R=mallinath@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2100004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4608 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/app/webrtc/jsepsessiondescription_unittest.cc b/talk/app/webrtc/jsepsessiondescription_unittest.cc
index 83f67cb..e2b59fb 100644
--- a/talk/app/webrtc/jsepsessiondescription_unittest.cc
+++ b/talk/app/webrtc/jsepsessiondescription_unittest.cc
@@ -79,16 +79,18 @@
                                  cricket::NS_GINGLE_P2P,
                                  std::vector<std::string>(),
                                  kCandidateUfragVoice, kCandidatePwdVoice,
-                                 cricket::ICEMODE_FULL, NULL,
-                                 cricket::Candidates()))));
+                                 cricket::ICEMODE_FULL,
+                                 cricket::CONNECTIONROLE_NONE,
+                                 NULL, cricket::Candidates()))));
   EXPECT_TRUE(desc->AddTransportInfo(
       cricket::TransportInfo(cricket::CN_VIDEO,
                              cricket::TransportDescription(
                                  cricket::NS_GINGLE_P2P,
                                  std::vector<std::string>(),
                                  kCandidateUfragVideo, kCandidatePwdVideo,
-                                 cricket::ICEMODE_FULL, NULL,
-                                 cricket::Candidates()))));
+                                 cricket::ICEMODE_FULL,
+                                 cricket::CONNECTIONROLE_NONE,
+                                 NULL, cricket::Candidates()))));
   return desc;
 }
 
diff --git a/talk/app/webrtc/webrtcsdp.cc b/talk/app/webrtc/webrtcsdp.cc
index 9910a51..a3bfa71 100644
--- a/talk/app/webrtc/webrtcsdp.cc
+++ b/talk/app/webrtc/webrtcsdp.cc
@@ -141,6 +141,7 @@
 static const char kAttributeCandidatePassword[] = "password";
 static const char kAttributeCandidateGeneration[] = "generation";
 static const char kAttributeFingerprint[] = "fingerprint";
+static const char kAttributeSetup[] = "setup";
 static const char kAttributeFmtp[] = "fmtp";
 static const char kAttributeRtpmap[] = "rtpmap";
 static const char kAttributeRtcp[] = "rtcp";
@@ -318,6 +319,9 @@
 static bool ParseFingerprintAttribute(const std::string& line,
                                       talk_base::SSLFingerprint** fingerprint,
                                       SdpParseError* error);
+static bool ParseDtlsSetup(const std::string& line,
+                           cricket::ConnectionRole* role,
+                           SdpParseError* error);
 
 // Helper functions
 
@@ -902,7 +906,8 @@
                     SdpParseError* error) {
   std::string session_id;
   std::string session_version;
-  TransportDescription session_td(NS_JINGLE_ICE_UDP, Candidates());
+  TransportDescription session_td(NS_JINGLE_ICE_UDP,
+                                  std::string(), std::string());
   RtpHeaderExtensions session_extmaps;
   cricket::SessionDescription* desc = new cricket::SessionDescription();
   std::vector<JsepIceCandidate*> candidates;
@@ -1226,8 +1231,23 @@
       os << kSdpDelimiterColon
          << fp->algorithm << kSdpDelimiterSpace
          << fp->GetRfc4572Fingerprint();
-
       AddLine(os.str(), message);
+
+      // Inserting setup attribute.
+      if (transport_info->description.connection_role !=
+              cricket::CONNECTIONROLE_NONE) {
+        // Making sure we are not using "passive" mode.
+        cricket::ConnectionRole role =
+            transport_info->description.connection_role;
+        ASSERT(role == cricket::CONNECTIONROLE_ACTIVE ||
+               role == cricket::CONNECTIONROLE_ACTPASS);
+        InitAttrLine(kAttributeSetup, &os);
+        std::string dtls_role_str = role == cricket::CONNECTIONROLE_ACTPASS ?
+            cricket::CONNECTIONROLE_ACTPASS_STR :
+            cricket::CONNECTIONROLE_ACTIVE_STR;
+        os << kSdpDelimiterColon << dtls_role_str;
+        AddLine(os.str(), message);
+      }
     }
   }
 
@@ -1796,6 +1816,10 @@
         return false;
       }
       session_td->identity_fingerprint.reset(fingerprint);
+    } else if (HasAttribute(line, kAttributeSetup)) {
+      if (!ParseDtlsSetup(line, &(session_td->connection_role), error)) {
+        return false;
+      }
     } else if (HasAttribute(line, kAttributeMsidSemantics)) {
       std::string semantics;
       if (!GetValue(line, kAttributeMsidSemantics, &semantics, error)) {
@@ -1876,6 +1900,24 @@
   return true;
 }
 
+static bool ParseDtlsSetup(const std::string& line,
+                           cricket::ConnectionRole* role,
+                           SdpParseError* error) {
+  // setup-attr           =  "a=setup:" role
+  // role                 =  "active" / "passive" / "actpass" / "holdconn"
+  std::vector<std::string> fields;
+  talk_base::split(line.substr(kLinePrefixLength), kSdpDelimiterColon, &fields);
+  const size_t expected_fields = 2;
+  if (fields.size() != expected_fields) {
+    return ParseFailedExpectFieldNum(line, expected_fields, error);
+  }
+  std::string role_str = fields[1];
+  if (!cricket::StringToConnectionRole(role_str, role)) {
+    return ParseFailed(line, "Invalid attribute value.", error);
+  }
+  return true;
+}
+
 // RFC 3551
 //  PT   encoding    media type  clock rate   channels
 //                      name                    (Hz)
@@ -2039,6 +2081,7 @@
                                    session_td.ice_ufrag,
                                    session_td.ice_pwd,
                                    session_td.ice_mode,
+                                   session_td.connection_role,
                                    session_td.identity_fingerprint.get(),
                                    Candidates());
 
@@ -2378,6 +2421,10 @@
         return false;
       }
       transport->identity_fingerprint.reset(fingerprint);
+    } else if (HasAttribute(line, kAttributeSetup)) {
+      if (!ParseDtlsSetup(line, &(transport->connection_role), error)) {
+        return false;
+      }
     } else if (is_rtp) {
       //
       // RTP specific attrubtes
diff --git a/talk/app/webrtc/webrtcsdp_unittest.cc b/talk/app/webrtc/webrtcsdp_unittest.cc
index 9e4c660..5fa8b0c 100644
--- a/talk/app/webrtc/webrtcsdp_unittest.cc
+++ b/talk/app/webrtc/webrtcsdp_unittest.cc
@@ -485,19 +485,13 @@
     EXPECT_TRUE(desc_.AddTransportInfo(
         TransportInfo(kAudioContentName,
                       TransportDescription(NS_JINGLE_ICE_UDP,
-                                           std::vector<std::string>(),
                                            kCandidateUfragVoice,
-                                           kCandidatePwdVoice,
-                                           cricket::ICEMODE_FULL,
-                                           NULL, Candidates()))));
+                                           kCandidatePwdVoice))));
     EXPECT_TRUE(desc_.AddTransportInfo(
         TransportInfo(kVideoContentName,
                       TransportDescription(NS_JINGLE_ICE_UDP,
-                                           std::vector<std::string>(),
                                            kCandidateUfragVideo,
-                                           kCandidatePwdVideo,
-                                           cricket::ICEMODE_FULL,
-                                           NULL, Candidates()))));
+                                           kCandidatePwdVideo))));
 
     // v4 host
     int port = 1234;
@@ -860,9 +854,7 @@
     }
     TransportInfo transport_info(
         content_name, TransportDescription(NS_JINGLE_ICE_UDP,
-                                           std::vector<std::string>(),
-                                           ufrag, pwd, cricket::ICEMODE_FULL,
-                                           NULL, Candidates()));
+                                           ufrag, pwd));
     SessionDescription* desc =
         const_cast<SessionDescription*>(jdesc->description());
     desc->RemoveTransportInfoByName(content_name);
@@ -903,16 +895,18 @@
                                            std::vector<std::string>(),
                                            kCandidateUfragVoice,
                                            kCandidatePwdVoice,
-                                           cricket::ICEMODE_FULL, &fingerprint,
-                                           Candidates()))));
+                                           cricket::ICEMODE_FULL,
+                                           cricket::CONNECTIONROLE_NONE,
+                                           &fingerprint, Candidates()))));
     EXPECT_TRUE(desc_.AddTransportInfo(
         TransportInfo(kVideoContentName,
                       TransportDescription(NS_JINGLE_ICE_UDP,
                                            std::vector<std::string>(),
                                            kCandidateUfragVideo,
                                            kCandidatePwdVideo,
-                                           cricket::ICEMODE_FULL, &fingerprint,
-                                           Candidates()))));
+                                           cricket::ICEMODE_FULL,
+                                           cricket::CONNECTIONROLE_NONE,
+                                           &fingerprint, Candidates()))));
   }
 
   void AddExtmap() {
@@ -984,11 +978,8 @@
     EXPECT_TRUE(desc_.AddTransportInfo(
            TransportInfo(kDataContentName,
                          TransportDescription(NS_JINGLE_ICE_UDP,
-                                              std::vector<std::string>(),
                                               kCandidateUfragData,
-                                              kCandidatePwdData,
-                                              cricket::ICEMODE_FULL,
-                                              NULL, Candidates()))));
+                                              kCandidatePwdData))));
   }
 
   void AddRtpDataChannel() {
@@ -1011,11 +1002,8 @@
     EXPECT_TRUE(desc_.AddTransportInfo(
            TransportInfo(kDataContentName,
                          TransportDescription(NS_JINGLE_ICE_UDP,
-                                              std::vector<std::string>(),
                                               kCandidateUfragData,
-                                              kCandidatePwdData,
-                                              cricket::ICEMODE_FULL,
-                                              NULL, Candidates()))));
+                                              kCandidatePwdData))));
   }
 
   bool TestDeserializeDirection(cricket::MediaContentDirection direction) {
@@ -1966,3 +1954,60 @@
   EXPECT_TRUE(SdpDeserialize(sdp_with_data, &jdesc_output));
   EXPECT_EQ(sdp_with_data, webrtc::SdpSerialize(jdesc_output));
 }
+
+TEST_F(WebRtcSdpTest, SerializeDtlsSetupAttribute) {
+  AddFingerprint();
+  TransportInfo audio_transport_info =
+      *(desc_.GetTransportInfoByName(kAudioContentName));
+  EXPECT_EQ(cricket::CONNECTIONROLE_NONE,
+            audio_transport_info.description.connection_role);
+  audio_transport_info.description.connection_role =
+        cricket::CONNECTIONROLE_ACTIVE;
+
+  TransportInfo video_transport_info =
+      *(desc_.GetTransportInfoByName(kVideoContentName));
+  EXPECT_EQ(cricket::CONNECTIONROLE_NONE,
+            video_transport_info.description.connection_role);
+  video_transport_info.description.connection_role =
+        cricket::CONNECTIONROLE_ACTIVE;
+
+  desc_.RemoveTransportInfoByName(kAudioContentName);
+  desc_.RemoveTransportInfoByName(kVideoContentName);
+
+  desc_.AddTransportInfo(audio_transport_info);
+  desc_.AddTransportInfo(video_transport_info);
+
+  ASSERT_TRUE(jdesc_.Initialize(desc_.Copy(),
+                                jdesc_.session_id(),
+                                jdesc_.session_version()));
+  std::string message = webrtc::SdpSerialize(jdesc_);
+  std::string sdp_with_dtlssetup = kSdpFullString;
+
+  // Fingerprint attribute is necessary to add DTLS setup attribute.
+  InjectAfter(kAttributeIcePwdVoice,
+              kFingerprint, &sdp_with_dtlssetup);
+  InjectAfter(kAttributeIcePwdVideo,
+              kFingerprint, &sdp_with_dtlssetup);
+  // Now adding |setup| attribute.
+  InjectAfter(kFingerprint,
+              "a=setup:active\r\n", &sdp_with_dtlssetup);
+  EXPECT_EQ(sdp_with_dtlssetup, message);
+}
+
+TEST_F(WebRtcSdpTest, DeserializeDtlsSetupAttribute) {
+  JsepSessionDescription jdesc_with_dtlssetup(kDummyString);
+  std::string sdp_with_dtlssetup = kSdpFullString;
+  InjectAfter(kSessionTime,
+              "a=setup:actpass\r\n",
+              &sdp_with_dtlssetup);
+  EXPECT_TRUE(SdpDeserialize(sdp_with_dtlssetup, &jdesc_with_dtlssetup));
+  cricket::SessionDescription* desc = jdesc_with_dtlssetup.description();
+  const cricket::TransportInfo* atinfo =
+      desc->GetTransportInfoByName("audio_content_name");
+  EXPECT_EQ(cricket::CONNECTIONROLE_ACTPASS,
+            atinfo->description.connection_role);
+  const cricket::TransportInfo* vtinfo =
+        desc->GetTransportInfoByName("video_content_name");
+  EXPECT_EQ(cricket::CONNECTIONROLE_ACTPASS,
+            vtinfo->description.connection_role);
+}
diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc
index b056757..7016e2a 100644
--- a/talk/app/webrtc/webrtcsession.cc
+++ b/talk/app/webrtc/webrtcsession.cc
@@ -505,6 +505,26 @@
   return webrtc_session_desc_factory_->secure();
 }
 
+bool WebRtcSession::GetSslRole(talk_base::SSLRole* role) {
+  if (local_description() == NULL || remote_description() == NULL) {
+    LOG(LS_INFO) << "Local and Remote descriptions must be applied to get "
+                 << "SSL Role of the session.";
+    return false;
+  }
+
+  // TODO(mallinath) - Return role of each transport, as role may differ from
+  // one another.
+  // In current implementaion we just return the role of first transport in the
+  // transport map.
+  for (cricket::TransportMap::const_iterator iter = transport_proxies().begin();
+       iter != transport_proxies().end(); ++iter) {
+    if (iter->second->impl()) {
+      return iter->second->impl()->GetSslRole(role);
+    }
+  }
+  return false;
+}
+
 void WebRtcSession::CreateOffer(CreateSessionDescriptionObserver* observer,
                                 const MediaConstraintsInterface* constraints) {
   webrtc_session_desc_factory_->CreateOffer(observer, constraints);
@@ -517,42 +537,22 @@
 
 bool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
                                         std::string* err_desc) {
-  cricket::SecureMediaPolicy secure_policy =
-      webrtc_session_desc_factory_->secure();
   // Takes the ownership of |desc| regardless of the result.
   talk_base::scoped_ptr<SessionDescriptionInterface> desc_temp(desc);
 
-  if (error() != cricket::BaseSession::ERROR_NONE) {
-    return BadLocalSdp(SessionErrorMsg(error()), err_desc);
-  }
-
-  if (!desc || !desc->description()) {
-    return BadLocalSdp(kInvalidSdp, err_desc);
-  }
-
-  if (!VerifyBundleSettings(desc->description())) {
-    return BadLocalSdp(kBundleWithoutRtcpMux, err_desc);
-  }
-
-  Action action = GetAction(desc->type());
-  if (!ExpectSetLocalDescription(action)) {
-    std::string type = desc->type();
-    return BadLocalSdp(BadStateErrMsg(type, state()), err_desc);
-  }
-  if (secure_policy == cricket::SEC_REQUIRED &&
-      !VerifyCrypto(desc->description())) {
-    return BadLocalSdp(kSdpWithoutCrypto, err_desc);
-  }
-  if (action == kAnswer && !VerifyMediaDescriptions(
-          desc->description(), remote_description()->description())) {
-    return BadLocalSdp(kMlineMismatch, err_desc);
+  // Validate SDP.
+  if (!ValidateSessionDescription(desc, cricket::CS_LOCAL, err_desc)) {
+    return false;
   }
 
   // Update the initiator flag if this session is the initiator.
+  Action action = GetAction(desc->type());
   if (state() == STATE_INIT && action == kOffer) {
     set_initiator(true);
   }
 
+  cricket::SecureMediaPolicy secure_policy =
+      webrtc_session_desc_factory_->secure();
   // Update the MediaContentDescription crypto settings as per the policy set.
   UpdateSessionDescriptionSecurePolicy(secure_policy, desc->description());
 
@@ -589,40 +589,16 @@
 
 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
                                          std::string* err_desc) {
-  cricket::SecureMediaPolicy secure_policy =
-      webrtc_session_desc_factory_->secure();
   // Takes the ownership of |desc| regardless of the result.
   talk_base::scoped_ptr<SessionDescriptionInterface> desc_temp(desc);
 
-  if (error() != cricket::BaseSession::ERROR_NONE) {
-    return BadRemoteSdp(SessionErrorMsg(error()), err_desc);
-  }
-
-  if (!desc || !desc->description()) {
-    return BadRemoteSdp(kInvalidSdp, err_desc);
-  }
-
-  if (!VerifyBundleSettings(desc->description())) {
-    return BadRemoteSdp(kBundleWithoutRtcpMux, err_desc);
-  }
-
-  Action action = GetAction(desc->type());
-  if (!ExpectSetRemoteDescription(action)) {
-    std::string type = desc->type();
-    return BadRemoteSdp(BadStateErrMsg(type, state()), err_desc);
-  }
-
-  if (action == kAnswer && !VerifyMediaDescriptions(
-          desc->description(), local_description()->description())) {
-    return BadRemoteSdp(kMlineMismatch, err_desc);
-  }
-
-  if (secure_policy == cricket::SEC_REQUIRED &&
-      !VerifyCrypto(desc->description())) {
-    return BadRemoteSdp(kSdpWithoutCrypto, err_desc);
+  // Validate SDP.
+  if (!ValidateSessionDescription(desc, cricket::CS_REMOTE, err_desc)) {
+    return false;
   }
 
   // Transport and Media channels will be created only when offer is set.
+  Action action = GetAction(desc->type());
   if (action == kOffer && !CreateChannels(desc->description())) {
     // TODO(mallinath) - Handle CreateChannel failure, as new local description
     // is applied. Restore back to old description.
@@ -1094,36 +1070,6 @@
   ProcessNewLocalCandidate(proxy->content_name(), candidates);
 }
 
-bool WebRtcSession::ExpectSetLocalDescription(Action action) {
-  return ((action == kOffer && state() == STATE_INIT) ||
-          // update local offer
-          (action == kOffer && state() == STATE_SENTINITIATE) ||
-          // update the current ongoing session.
-          (action == kOffer && state() == STATE_RECEIVEDACCEPT) ||
-          (action == kOffer && state() == STATE_SENTACCEPT) ||
-          (action == kOffer && state() == STATE_INPROGRESS) ||
-          // accept remote offer
-          (action == kAnswer && state() == STATE_RECEIVEDINITIATE) ||
-          (action == kAnswer && state() == STATE_SENTPRACCEPT) ||
-          (action == kPrAnswer && state() == STATE_RECEIVEDINITIATE) ||
-          (action == kPrAnswer && state() == STATE_SENTPRACCEPT));
-}
-
-bool WebRtcSession::ExpectSetRemoteDescription(Action action) {
-  return ((action == kOffer && state() == STATE_INIT) ||
-          // update remote offer
-          (action == kOffer && state() == STATE_RECEIVEDINITIATE) ||
-          // update the current ongoing session
-          (action == kOffer && state() == STATE_RECEIVEDACCEPT) ||
-          (action == kOffer && state() == STATE_SENTACCEPT) ||
-          (action == kOffer && state() == STATE_INPROGRESS) ||
-          // accept local offer
-          (action == kAnswer && state() == STATE_SENTINITIATE) ||
-          (action == kAnswer && state() == STATE_RECEIVEDPRACCEPT) ||
-          (action == kPrAnswer && state() == STATE_SENTINITIATE) ||
-          (action == kPrAnswer && state() == STATE_RECEIVEDPRACCEPT));
-}
-
 void WebRtcSession::OnCandidatesAllocationDone() {
   ASSERT(signaling_thread()->IsCurrent());
   if (ice_observer_) {
@@ -1378,7 +1324,7 @@
 }
 
 // Returns false if bundle is enabled and rtcp_mux is disabled.
-bool WebRtcSession::VerifyBundleSettings(const SessionDescription* desc) {
+bool WebRtcSession::ValidateBundleSettings(const SessionDescription* desc) {
   bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE);
   if (!bundle_enabled)
     return true;
@@ -1409,4 +1355,79 @@
   return description->rtcp_mux();
 }
 
+bool WebRtcSession::ValidateSessionDescription(
+    const SessionDescriptionInterface* sdesc,
+    cricket::ContentSource source, std::string* error_desc) {
+
+  if (error() != cricket::BaseSession::ERROR_NONE) {
+    return BadSdp(source, SessionErrorMsg(error()), error_desc);
+  }
+
+  if (!sdesc || !sdesc->description()) {
+    return BadSdp(source, kInvalidSdp, error_desc);
+  }
+
+  std::string type = sdesc->type();
+  Action action = GetAction(sdesc->type());
+  if (source == cricket::CS_LOCAL) {
+    if (!ExpectSetLocalDescription(action))
+      return BadSdp(source, BadStateErrMsg(type, state()), error_desc);
+  } else {
+    if (!ExpectSetRemoteDescription(action))
+      return BadSdp(source, BadStateErrMsg(type, state()), error_desc);
+  }
+
+  // Verify crypto settings.
+  if (webrtc_session_desc_factory_->secure() == cricket::SEC_REQUIRED &&
+      !VerifyCrypto(sdesc->description())) {
+    return BadSdp(source, kSdpWithoutCrypto, error_desc);
+  }
+
+  if (!ValidateBundleSettings(sdesc->description())) {
+    return BadSdp(source, kBundleWithoutRtcpMux, error_desc);
+  }
+
+  // Verify m-lines in Answer when compared against Offer.
+  if (action == kAnswer) {
+    const cricket::SessionDescription* offer_desc =
+        (source == cricket::CS_LOCAL) ? remote_description()->description() :
+            local_description()->description();
+    if (!VerifyMediaDescriptions(sdesc->description(), offer_desc)) {
+      return BadSdp(source, kMlineMismatch, error_desc);
+    }
+  }
+
+  return true;
+}
+
+bool WebRtcSession::ExpectSetLocalDescription(Action action) {
+  return ((action == kOffer && state() == STATE_INIT) ||
+          // update local offer
+          (action == kOffer && state() == STATE_SENTINITIATE) ||
+          // update the current ongoing session.
+          (action == kOffer && state() == STATE_RECEIVEDACCEPT) ||
+          (action == kOffer && state() == STATE_SENTACCEPT) ||
+          (action == kOffer && state() == STATE_INPROGRESS) ||
+          // accept remote offer
+          (action == kAnswer && state() == STATE_RECEIVEDINITIATE) ||
+          (action == kAnswer && state() == STATE_SENTPRACCEPT) ||
+          (action == kPrAnswer && state() == STATE_RECEIVEDINITIATE) ||
+          (action == kPrAnswer && state() == STATE_SENTPRACCEPT));
+}
+
+bool WebRtcSession::ExpectSetRemoteDescription(Action action) {
+  return ((action == kOffer && state() == STATE_INIT) ||
+          // update remote offer
+          (action == kOffer && state() == STATE_RECEIVEDINITIATE) ||
+          // update the current ongoing session
+          (action == kOffer && state() == STATE_RECEIVEDACCEPT) ||
+          (action == kOffer && state() == STATE_SENTACCEPT) ||
+          (action == kOffer && state() == STATE_INPROGRESS) ||
+          // accept local offer
+          (action == kAnswer && state() == STATE_SENTINITIATE) ||
+          (action == kAnswer && state() == STATE_RECEIVEDPRACCEPT) ||
+          (action == kPrAnswer && state() == STATE_SENTINITIATE) ||
+          (action == kPrAnswer && state() == STATE_RECEIVEDPRACCEPT));
+}
+
 }  // namespace webrtc
diff --git a/talk/app/webrtc/webrtcsession.h b/talk/app/webrtc/webrtcsession.h
index 202ca66..0cb049f 100644
--- a/talk/app/webrtc/webrtcsession.h
+++ b/talk/app/webrtc/webrtcsession.h
@@ -130,6 +130,9 @@
   void set_secure_policy(cricket::SecureMediaPolicy secure_policy);
   cricket::SecureMediaPolicy secure_policy() const;
 
+  // Get current ssl role from transport.
+  bool GetSslRole(talk_base::SSLRole* role);
+
   // Generic error message callback from WebRtcSession.
   // TODO - It may be necessary to supply error code as well.
   sigslot::signal0<> SignalError;
@@ -152,9 +155,6 @@
     return remote_desc_.get();
   }
 
-  void set_secure(cricket::SecureMediaPolicy secure_policy);
-  cricket::SecureMediaPolicy secure();
-
   // Get the id used as a media stream track's "id" field from ssrc.
   virtual bool GetTrackIdBySsrc(uint32 ssrc, std::string* id);
 
@@ -223,10 +223,6 @@
       const cricket::Candidates& candidates);
   virtual void OnCandidatesAllocationDone();
 
-  // Check if a call to SetLocalDescription is acceptable with |action|.
-  bool ExpectSetLocalDescription(Action action);
-  // Check if a call to SetRemoteDescription is acceptable with |action|.
-  bool ExpectSetRemoteDescription(Action action);
   // Creates local session description with audio and video contents.
   bool CreateDefaultLocalDescription();
   // Enables media channels to allow sending of media.
@@ -275,8 +271,20 @@
   std::string BadStateErrMsg(const std::string& type, State state);
   void SetIceConnectionState(PeerConnectionInterface::IceConnectionState state);
 
-  bool VerifyBundleSettings(const cricket::SessionDescription* desc);
+  bool ValidateBundleSettings(const cricket::SessionDescription* desc);
   bool HasRtcpMuxEnabled(const cricket::ContentInfo* content);
+  // Below methods are helper methods which verifies SDP.
+  bool ValidateSessionDescription(const SessionDescriptionInterface* sdesc,
+                                  cricket::ContentSource source,
+                                  std::string* error_desc);
+
+  // Check if a call to SetLocalDescription is acceptable with |action|.
+  bool ExpectSetLocalDescription(Action action);
+  // Check if a call to SetRemoteDescription is acceptable with |action|.
+  bool ExpectSetRemoteDescription(Action action);
+  // Verifies a=setup attribute as per RFC 5763.
+  bool ValidateDtlsSetupAttribute(const cricket::SessionDescription* desc,
+                                  Action action);
 
   talk_base::scoped_ptr<cricket::VoiceChannel> voice_channel_;
   talk_base::scoped_ptr<cricket::VideoChannel> video_channel_;
diff --git a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
index 2021085..13f54a7 100644
--- a/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
+++ b/talk/app/webrtc/webrtcsessiondescriptionfactory.cc
@@ -343,6 +343,13 @@
   // an answer should also contain new ice ufrag and password if an offer has
   // been received with new ufrag and password.
   request.options.transport_options.ice_restart = session_->IceRestartPending();
+  // We should pass current ssl role to the transport description factory, if
+  // there is already an existing ongoing session.
+  talk_base::SSLRole ssl_role;
+  if (session_->GetSslRole(&ssl_role)) {
+    request.options.transport_options.prefer_passive_role =
+        (talk_base::SSL_SERVER == ssl_role);
+  }
 
   cricket::SessionDescription* desc(session_desc_factory_.CreateAnswer(
       static_cast<cricket::BaseSession*>(session_)->remote_description(),