Chromium Code Reviews| Index: webrtc/pc/jsepsessiondescription.cc |
| diff --git a/webrtc/pc/jsepsessiondescription.cc b/webrtc/pc/jsepsessiondescription.cc |
| index 02919b6bf8b7328e7fd99338815a5ba205af1158..971d403f7352f07d16210b4cf093484b741e315a 100644 |
| --- a/webrtc/pc/jsepsessiondescription.cc |
| +++ b/webrtc/pc/jsepsessiondescription.cc |
| @@ -38,6 +38,78 @@ static bool IsTypeSupported(const std::string& type) { |
| return type_supported; |
| } |
| +// RFC 5245 |
| +// It is RECOMMENDED that default candidates be chosen based on the |
| +// likelihood of those candidates to work with the peer that is being |
| +// contacted. It is RECOMMENDED that relayed > reflexive > host. |
| +static const int kPreferenceUnknown = 0; |
| +static const int kPreferenceHost = 1; |
| +static const int kPreferenceReflexive = 2; |
| +static const int kPreferenceRelayed = 3; |
| + |
| +static const char kDummyAddress[] = "0.0.0.0"; |
| +static const int kDummyPort = 9; |
| + |
| +static int GetCandidatePreferenceFromType(const std::string& type) { |
| + int preference = kPreferenceUnknown; |
| + if (type == cricket::LOCAL_PORT_TYPE) { |
| + preference = kPreferenceHost; |
| + } else if (type == cricket::STUN_PORT_TYPE) { |
| + preference = kPreferenceReflexive; |
| + } else if (type == cricket::RELAY_PORT_TYPE) { |
| + preference = kPreferenceRelayed; |
| + } else { |
| + RTC_NOTREACHED(); |
| + } |
| + return preference; |
| +} |
| + |
| +// Update the connection address for the MediaContentDescription based on the |
| +// candidates. |
| +static void UpdateConnectionAddress( |
| + cricket::SessionDescription* description, |
| + const std::vector<JsepCandidateCollection>& candidate_collections, |
|
Taylor Brandstetter
2017/03/20 18:29:58
nit: I believe this method could take a single Jse
Zhi Huang
2017/03/21 03:43:12
I'll change it to take a single JsepCandidateColle
|
| + size_t mediasection_index) { |
| + int port = kDummyPort; |
| + std::string ip = kDummyAddress; |
| + int current_preference = kPreferenceUnknown; |
| + int current_family = AF_UNSPEC; |
| + for (size_t i = 0; i < candidate_collections[mediasection_index].count(); |
| + ++i) { |
| + const IceCandidateInterface* jsep_candidate = |
| + candidate_collections[mediasection_index].at(i); |
| + if (jsep_candidate->candidate().component() != |
| + cricket::ICE_CANDIDATE_COMPONENT_RTP) { |
| + continue; |
| + } |
| + // Default destination should be UDP only. |
| + if (jsep_candidate->candidate().protocol() != cricket::UDP_PROTOCOL_NAME) { |
| + continue; |
| + } |
| + const int preference = |
| + GetCandidatePreferenceFromType(jsep_candidate->candidate().type()); |
| + const int family = jsep_candidate->candidate().address().ipaddr().family(); |
| + // See if this candidate is more preferable then the current one if it's the |
| + // same family. Or if the current family is IPv4 already so we could safely |
| + // ignore all IPv6 ones. WebRTC bug 4269. |
| + // http://code.google.com/p/webrtc/issues/detail?id=4269 |
| + if ((preference <= current_preference && current_family == family) || |
| + (current_family == AF_INET && family == AF_INET6)) { |
| + continue; |
| + } |
| + current_preference = preference; |
| + current_family = family; |
| + port = jsep_candidate->candidate().address().port(); |
| + ip = jsep_candidate->candidate().address().ipaddr().ToString(); |
| + } |
| + rtc::SocketAddress connection_addr; |
| + connection_addr.SetIP(ip); |
| + connection_addr.SetPort(port); |
| + auto content_description = static_cast<cricket::MediaContentDescription*>( |
| + description->contents()[mediasection_index].description); |
| + content_description->set_connection_address(connection_addr); |
| +} |
| + |
| const char SessionDescriptionInterface::kOffer[] = "offer"; |
| const char SessionDescriptionInterface::kPrAnswer[] = "pranswer"; |
| const char SessionDescriptionInterface::kAnswer[] = "answer"; |
| @@ -116,9 +188,12 @@ bool JsepSessionDescription::AddCandidate( |
| static_cast<int>(mediasection_index), |
| updated_candidate)); |
| if (!candidate_collection_[mediasection_index].HasCandidate( |
| - updated_candidate_wrapper.get())) |
| + updated_candidate_wrapper.get())) { |
| candidate_collection_[mediasection_index].add( |
| updated_candidate_wrapper.release()); |
| + UpdateConnectionAddress(description_.get(), candidate_collection_, |
| + mediasection_index); |
| + } |
| return true; |
| } |
| @@ -133,6 +208,8 @@ size_t JsepSessionDescription::RemoveCandidates( |
| continue; |
| } |
| num_removed += candidate_collection_[mediasection_index].remove(candidate); |
| + UpdateConnectionAddress(description_.get(), candidate_collection_, |
| + mediasection_index); |
| } |
| return num_removed; |
| } |