| Index: webrtc/p2p/base/transport.cc
|
| diff --git a/webrtc/p2p/base/transport.cc b/webrtc/p2p/base/transport.cc
|
| index 8b68a976b68d2ca8a4c040a6902ac59082761ead..b96ae842b445c8b2c4e1215542f325a2fb2e3f7c 100644
|
| --- a/webrtc/p2p/base/transport.cc
|
| +++ b/webrtc/p2p/base/transport.cc
|
| @@ -56,6 +56,25 @@ struct ChannelParams : public rtc::MessageData {
|
| Candidate* candidate;
|
| };
|
|
|
| +static std::string IceProtoToString(TransportProtocol proto) {
|
| + std::string proto_str;
|
| + switch (proto) {
|
| + case ICEPROTO_GOOGLE:
|
| + proto_str = "gice";
|
| + break;
|
| + case ICEPROTO_HYBRID:
|
| + proto_str = "hybrid";
|
| + break;
|
| + case ICEPROTO_RFC5245:
|
| + proto_str = "ice";
|
| + break;
|
| + default:
|
| + ASSERT(false);
|
| + break;
|
| + }
|
| + return proto_str;
|
| +}
|
| +
|
| static bool VerifyIceParams(const TransportDescription& desc) {
|
| // For legacy protocols.
|
| if (desc.ice_ufrag.empty() && desc.ice_pwd.empty())
|
| @@ -100,10 +119,12 @@ static bool IceCredentialsChanged(const TransportDescription& old_desc,
|
| Transport::Transport(rtc::Thread* signaling_thread,
|
| rtc::Thread* worker_thread,
|
| const std::string& content_name,
|
| + const std::string& type,
|
| PortAllocator* allocator)
|
| : signaling_thread_(signaling_thread),
|
| worker_thread_(worker_thread),
|
| content_name_(content_name),
|
| + type_(type),
|
| allocator_(allocator),
|
| destroyed_(false),
|
| readable_(TRANSPORT_STATE_NONE),
|
| @@ -113,6 +134,7 @@ Transport::Transport(rtc::Thread* signaling_thread,
|
| connect_requested_(false),
|
| ice_role_(ICEROLE_UNKNOWN),
|
| tiebreaker_(0),
|
| + protocol_(ICEPROTO_HYBRID),
|
| remote_ice_mode_(ICEMODE_FULL),
|
| channel_receiving_timeout_(-1) {
|
| }
|
| @@ -330,7 +352,7 @@ void Transport::ConnectChannels_w() {
|
| // initiate request initiated by the remote.
|
| LOG(LS_INFO) << "Transport::ConnectChannels_w: No local description has "
|
| << "been set. Will generate one.";
|
| - TransportDescription desc(std::vector<std::string>(),
|
| + TransportDescription desc(NS_GINGLE_P2P, std::vector<std::string>(),
|
| rtc::CreateRandomString(ICE_UFRAG_LENGTH),
|
| rtc::CreateRandomString(ICE_PWD_LENGTH),
|
| ICEMODE_FULL, CONNECTIONROLE_NONE, NULL,
|
| @@ -806,6 +828,21 @@ bool Transport::SetRemoteTransportDescription_w(
|
| bool Transport::ApplyLocalTransportDescription_w(TransportChannelImpl* ch,
|
| std::string* error_desc) {
|
| ASSERT(worker_thread()->IsCurrent());
|
| + // If existing protocol_type is HYBRID, we may have not chosen the final
|
| + // protocol type, so update the channel protocol type from the
|
| + // local description. Otherwise, skip updating the protocol type.
|
| + // We check for HYBRID to avoid accidental changes; in the case of a
|
| + // session renegotiation, the new offer will have the google-ice ICE option,
|
| + // so we need to make sure we don't switch back from ICE mode to HYBRID
|
| + // when this happens.
|
| + // There are some other ways we could have solved this, but this is the
|
| + // simplest. The ultimate solution will be to get rid of GICE altogether.
|
| + IceProtocolType protocol_type;
|
| + if (ch->GetIceProtocolType(&protocol_type) &&
|
| + protocol_type == ICEPROTO_HYBRID) {
|
| + ch->SetIceProtocolType(
|
| + TransportProtocolFromDescription(local_description()));
|
| + }
|
| ch->SetIceCredentials(local_description_->ice_ufrag,
|
| local_description_->ice_pwd);
|
| return true;
|
| @@ -821,6 +858,7 @@ bool Transport::ApplyRemoteTransportDescription_w(TransportChannelImpl* ch,
|
| bool Transport::ApplyNegotiatedTransportDescription_w(
|
| TransportChannelImpl* channel, std::string* error_desc) {
|
| ASSERT(worker_thread()->IsCurrent());
|
| + channel->SetIceProtocolType(protocol_);
|
| channel->SetRemoteIceMode(remote_ice_mode_);
|
| return true;
|
| }
|
| @@ -830,6 +868,39 @@ bool Transport::NegotiateTransportDescription_w(ContentAction local_role,
|
| ASSERT(worker_thread()->IsCurrent());
|
| // TODO(ekr@rtfm.com): This is ICE-specific stuff. Refactor into
|
| // P2PTransport.
|
| + const TransportDescription* offer;
|
| + const TransportDescription* answer;
|
| +
|
| + if (local_role == CA_OFFER) {
|
| + offer = local_description_.get();
|
| + answer = remote_description_.get();
|
| + } else {
|
| + offer = remote_description_.get();
|
| + answer = local_description_.get();
|
| + }
|
| +
|
| + TransportProtocol offer_proto = TransportProtocolFromDescription(offer);
|
| + TransportProtocol answer_proto = TransportProtocolFromDescription(answer);
|
| +
|
| + // If offered protocol is gice/ice, then we expect to receive matching
|
| + // protocol in answer, anything else is treated as an error.
|
| + // HYBRID is not an option when offered specific protocol.
|
| + // If offered protocol is HYBRID and answered protocol is HYBRID then
|
| + // gice is preferred protocol.
|
| + // TODO(mallinath) - Answer from local or remote should't have both ice
|
| + // and gice support. It should always pick which protocol it wants to use.
|
| + // Once WebRTC stops supporting gice (for backward compatibility), HYBRID in
|
| + // answer must be treated as error.
|
| + if ((offer_proto == ICEPROTO_GOOGLE || offer_proto == ICEPROTO_RFC5245) &&
|
| + (offer_proto != answer_proto)) {
|
| + std::ostringstream desc;
|
| + desc << "Offer and answer protocol mismatch: "
|
| + << IceProtoToString(offer_proto)
|
| + << " vs "
|
| + << IceProtoToString(answer_proto);
|
| + return BadTransportDescription(desc.str(), error_desc);
|
| + }
|
| + protocol_ = answer_proto == ICEPROTO_HYBRID ? ICEPROTO_GOOGLE : answer_proto;
|
|
|
| // If transport is in ICEROLE_CONTROLLED and remote end point supports only
|
| // ice_lite, this local end point should take CONTROLLING role.
|
| @@ -903,4 +974,16 @@ void Transport::OnMessage(rtc::Message* msg) {
|
| }
|
| }
|
|
|
| +// We're GICE if the namespace is NS_GOOGLE_P2P, or if NS_JINGLE_ICE_UDP is
|
| +// used and the GICE ice-option is set.
|
| +TransportProtocol TransportProtocolFromDescription(
|
| + const TransportDescription* desc) {
|
| + ASSERT(desc != NULL);
|
| + if (desc->transport_type == NS_JINGLE_ICE_UDP) {
|
| + return (desc->HasOption(ICE_OPTION_GICE)) ?
|
| + ICEPROTO_HYBRID : ICEPROTO_RFC5245;
|
| + }
|
| + return ICEPROTO_GOOGLE;
|
| +}
|
| +
|
| } // namespace cricket
|
|
|