| Index: webrtc/pc/jsepsessiondescription.cc
|
| diff --git a/webrtc/pc/jsepsessiondescription.cc b/webrtc/pc/jsepsessiondescription.cc
|
| index 02919b6bf8b7328e7fd99338815a5ba205af1158..e2bae7a86400a6b9f77f1c2e9851ea5169dae4e6 100644
|
| --- a/webrtc/pc/jsepsessiondescription.cc
|
| +++ b/webrtc/pc/jsepsessiondescription.cc
|
| @@ -38,6 +38,75 @@ 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 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,
|
| + int mediasection_index) {
|
| + int port = 9;
|
| + std::string ip = "0.0.0.0";
|
| + 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 +185,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 +205,8 @@ size_t JsepSessionDescription::RemoveCandidates(
|
| continue;
|
| }
|
| num_removed += candidate_collection_[mediasection_index].remove(candidate);
|
| + UpdateConnectionAddress(description_.get(), candidate_collection_,
|
| + mediasection_index);
|
| }
|
| return num_removed;
|
| }
|
|
|