| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 using cricket::PRFLX_PORT_TYPE; | 54 using cricket::PRFLX_PORT_TYPE; |
| 55 | 55 |
| 56 namespace webrtc { | 56 namespace webrtc { |
| 57 | 57 |
| 58 // Error messages | 58 // Error messages |
| 59 const char kBundleWithoutRtcpMux[] = "RTCP-MUX must be enabled when BUNDLE " | 59 const char kBundleWithoutRtcpMux[] = "RTCP-MUX must be enabled when BUNDLE " |
| 60 "is enabled."; | 60 "is enabled."; |
| 61 const char kCreateChannelFailed[] = "Failed to create channels."; | 61 const char kCreateChannelFailed[] = "Failed to create channels."; |
| 62 const char kInvalidCandidates[] = "Description contains invalid candidates."; | 62 const char kInvalidCandidates[] = "Description contains invalid candidates."; |
| 63 const char kInvalidSdp[] = "Invalid session description."; | 63 const char kInvalidSdp[] = "Invalid session description."; |
| 64 const char kMlineMismatch[] = | 64 const char kMlineMismatchInAnswer[] = |
| 65 "Offer and answer descriptions m-lines are not matching. Rejecting answer."; | 65 "The order of m-lines in answer doesn't match order in offer. Rejecting " |
| 66 "answer."; |
| 67 const char kMlineMismatchInSubsequentOffer[] = |
| 68 "The order of m-lines in subsequent offer doesn't match order from " |
| 69 "previous offer/answer."; |
| 66 const char kPushDownTDFailed[] = | 70 const char kPushDownTDFailed[] = |
| 67 "Failed to push down transport description:"; | 71 "Failed to push down transport description:"; |
| 68 const char kSdpWithoutDtlsFingerprint[] = | 72 const char kSdpWithoutDtlsFingerprint[] = |
| 69 "Called with SDP without DTLS fingerprint."; | 73 "Called with SDP without DTLS fingerprint."; |
| 70 const char kSdpWithoutSdesCrypto[] = | 74 const char kSdpWithoutSdesCrypto[] = |
| 71 "Called with SDP without SDES crypto."; | 75 "Called with SDP without SDES crypto."; |
| 72 const char kSdpWithoutIceUfragPwd[] = | 76 const char kSdpWithoutIceUfragPwd[] = |
| 73 "Called with SDP without ice-ufrag and ice-pwd."; | 77 "Called with SDP without ice-ufrag and ice-pwd."; |
| 74 const char kSessionError[] = "Session error code: "; | 78 const char kSessionError[] = "Session error code: "; |
| 75 const char kSessionErrorDesc[] = "Session error description: "; | 79 const char kSessionErrorDesc[] = "Session error description: "; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 return kIceCandidatePairRelayPrflx; | 133 return kIceCandidatePairRelayPrflx; |
| 130 if (l == prflx && r == host) | 134 if (l == prflx && r == host) |
| 131 return kIceCandidatePairPrflxHost; | 135 return kIceCandidatePairPrflxHost; |
| 132 if (l == prflx && r == srflx) | 136 if (l == prflx && r == srflx) |
| 133 return kIceCandidatePairPrflxSrflx; | 137 return kIceCandidatePairPrflxSrflx; |
| 134 if (l == prflx && r == relay) | 138 if (l == prflx && r == relay) |
| 135 return kIceCandidatePairPrflxRelay; | 139 return kIceCandidatePairPrflxRelay; |
| 136 return kIceCandidatePairMax; | 140 return kIceCandidatePairMax; |
| 137 } | 141 } |
| 138 | 142 |
| 139 // Compares |answer| against |offer|. Comparision is done | 143 // Verify that the order of media sections in |desc1| matches |desc2|. The |
| 140 // for number of m-lines in answer against offer. If matches true will be | 144 // number of m= sections could be different. |
| 141 // returned otherwise false. | 145 static bool MediaSectionsInSameOrder(const SessionDescription* desc1, |
| 142 static bool VerifyMediaDescriptions( | 146 const SessionDescription* desc2) { |
| 143 const SessionDescription* answer, const SessionDescription* offer) { | 147 if (!desc1 || !desc2) { |
| 144 if (offer->contents().size() != answer->contents().size()) | |
| 145 return false; | 148 return false; |
| 146 | 149 } |
| 147 for (size_t i = 0; i < offer->contents().size(); ++i) { | 150 for (size_t i = 0; |
| 148 if ((offer->contents()[i].name) != answer->contents()[i].name) { | 151 i < desc1->contents().size() && i < desc2->contents().size(); ++i) { |
| 152 if ((desc2->contents()[i].name) != desc1->contents()[i].name) { |
| 149 return false; | 153 return false; |
| 150 } | 154 } |
| 151 const MediaContentDescription* offer_mdesc = | 155 const MediaContentDescription* desc2_mdesc = |
| 152 static_cast<const MediaContentDescription*>( | 156 static_cast<const MediaContentDescription*>( |
| 153 offer->contents()[i].description); | 157 desc2->contents()[i].description); |
| 154 const MediaContentDescription* answer_mdesc = | 158 const MediaContentDescription* desc1_mdesc = |
| 155 static_cast<const MediaContentDescription*>( | 159 static_cast<const MediaContentDescription*>( |
| 156 answer->contents()[i].description); | 160 desc1->contents()[i].description); |
| 157 if (offer_mdesc->type() != answer_mdesc->type()) { | 161 if (desc2_mdesc->type() != desc1_mdesc->type()) { |
| 158 return false; | 162 return false; |
| 159 } | 163 } |
| 160 } | 164 } |
| 161 return true; | 165 return true; |
| 162 } | 166 } |
| 163 | 167 |
| 168 static bool MediaSectionsHaveSameCount(const SessionDescription* desc1, |
| 169 const SessionDescription* desc2) { |
| 170 if (!desc1 || !desc2) { |
| 171 return false; |
| 172 } |
| 173 return desc1->contents().size() == desc2->contents().size(); |
| 174 } |
| 175 |
| 164 // Checks that each non-rejected content has SDES crypto keys or a DTLS | 176 // Checks that each non-rejected content has SDES crypto keys or a DTLS |
| 165 // fingerprint, unless it's in a BUNDLE group, in which case only the | 177 // fingerprint, unless it's in a BUNDLE group, in which case only the |
| 166 // BUNDLE-tag section (first media section/description in the BUNDLE group) | 178 // BUNDLE-tag section (first media section/description in the BUNDLE group) |
| 167 // needs a ufrag and pwd. Mismatches, such as replying with a DTLS fingerprint | 179 // needs a ufrag and pwd. Mismatches, such as replying with a DTLS fingerprint |
| 168 // to SDES keys, will be caught in JsepTransport negotiation, and backstopped | 180 // to SDES keys, will be caught in JsepTransport negotiation, and backstopped |
| 169 // by Channel's |srtp_required| check. | 181 // by Channel's |srtp_required| check. |
| 170 static bool VerifyCrypto(const SessionDescription* desc, | 182 static bool VerifyCrypto(const SessionDescription* desc, |
| 171 bool dtls_enabled, | 183 bool dtls_enabled, |
| 172 std::string* error) { | 184 std::string* error) { |
| 173 const cricket::ContentGroup* bundle = | 185 const cricket::ContentGroup* bundle = |
| (...skipping 1972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2146 } | 2158 } |
| 2147 | 2159 |
| 2148 if (!ValidateBundleSettings(sdesc->description())) { | 2160 if (!ValidateBundleSettings(sdesc->description())) { |
| 2149 return BadSdp(source, type, kBundleWithoutRtcpMux, err_desc); | 2161 return BadSdp(source, type, kBundleWithoutRtcpMux, err_desc); |
| 2150 } | 2162 } |
| 2151 | 2163 |
| 2152 // TODO(skvlad): When the local rtcp-mux policy is Require, reject any | 2164 // TODO(skvlad): When the local rtcp-mux policy is Require, reject any |
| 2153 // m-lines that do not rtcp-mux enabled. | 2165 // m-lines that do not rtcp-mux enabled. |
| 2154 | 2166 |
| 2155 // Verify m-lines in Answer when compared against Offer. | 2167 // Verify m-lines in Answer when compared against Offer. |
| 2156 if (action == kAnswer) { | 2168 if (action == kAnswer || action == kPrAnswer) { |
| 2157 const cricket::SessionDescription* offer_desc = | 2169 const cricket::SessionDescription* offer_desc = |
| 2158 (source == cricket::CS_LOCAL) ? remote_description()->description() | 2170 (source == cricket::CS_LOCAL) ? remote_description()->description() |
| 2159 : local_description()->description(); | 2171 : local_description()->description(); |
| 2160 if (!VerifyMediaDescriptions(sdesc->description(), offer_desc)) { | 2172 if (!MediaSectionsHaveSameCount(sdesc->description(), offer_desc) || |
| 2161 return BadAnswerSdp(source, kMlineMismatch, err_desc); | 2173 !MediaSectionsInSameOrder(sdesc->description(), offer_desc)) { |
| 2174 return BadAnswerSdp(source, kMlineMismatchInAnswer, err_desc); |
| 2175 } |
| 2176 } else { |
| 2177 // The re-offers should respect the order of m= sections in current local |
| 2178 // description. See RFC3264 Section 8 paragraph 4 for more details. |
| 2179 if (local_description() && |
| 2180 !MediaSectionsInSameOrder(sdesc->description(), |
| 2181 local_description()->description())) { |
| 2182 return BadOfferSdp(source, kMlineMismatchInSubsequentOffer, err_desc); |
| 2162 } | 2183 } |
| 2163 } | 2184 } |
| 2164 | 2185 |
| 2165 return true; | 2186 return true; |
| 2166 } | 2187 } |
| 2167 | 2188 |
| 2168 bool WebRtcSession::ExpectSetLocalDescription(Action action) { | 2189 bool WebRtcSession::ExpectSetLocalDescription(Action action) { |
| 2169 return ((action == kOffer && state() == STATE_INIT) || | 2190 return ((action == kOffer && state() == STATE_INIT) || |
| 2170 // update local offer | 2191 // update local offer |
| 2171 (action == kOffer && state() == STATE_SENTOFFER) || | 2192 (action == kOffer && state() == STATE_SENTOFFER) || |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2483 (rtp_data_channel_->rtcp_dtls_transport() != nullptr); | 2504 (rtp_data_channel_->rtcp_dtls_transport() != nullptr); |
| 2484 channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release()); | 2505 channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release()); |
| 2485 transport_controller_->DestroyDtlsTransport( | 2506 transport_controller_->DestroyDtlsTransport( |
| 2486 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); | 2507 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP); |
| 2487 if (need_to_delete_rtcp) { | 2508 if (need_to_delete_rtcp) { |
| 2488 transport_controller_->DestroyDtlsTransport( | 2509 transport_controller_->DestroyDtlsTransport( |
| 2489 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); | 2510 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP); |
| 2490 } | 2511 } |
| 2491 } | 2512 } |
| 2492 } // namespace webrtc | 2513 } // namespace webrtc |
| OLD | NEW |