OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 ~ChannelParams() { | 49 ~ChannelParams() { |
50 delete candidate; | 50 delete candidate; |
51 } | 51 } |
52 | 52 |
53 std::string name; | 53 std::string name; |
54 int component; | 54 int component; |
55 TransportChannelImpl* channel; | 55 TransportChannelImpl* channel; |
56 Candidate* candidate; | 56 Candidate* candidate; |
57 }; | 57 }; |
58 | 58 |
| 59 static std::string IceProtoToString(TransportProtocol proto) { |
| 60 std::string proto_str; |
| 61 switch (proto) { |
| 62 case ICEPROTO_GOOGLE: |
| 63 proto_str = "gice"; |
| 64 break; |
| 65 case ICEPROTO_HYBRID: |
| 66 proto_str = "hybrid"; |
| 67 break; |
| 68 case ICEPROTO_RFC5245: |
| 69 proto_str = "ice"; |
| 70 break; |
| 71 default: |
| 72 ASSERT(false); |
| 73 break; |
| 74 } |
| 75 return proto_str; |
| 76 } |
| 77 |
59 static bool VerifyIceParams(const TransportDescription& desc) { | 78 static bool VerifyIceParams(const TransportDescription& desc) { |
60 // For legacy protocols. | 79 // For legacy protocols. |
61 if (desc.ice_ufrag.empty() && desc.ice_pwd.empty()) | 80 if (desc.ice_ufrag.empty() && desc.ice_pwd.empty()) |
62 return true; | 81 return true; |
63 | 82 |
64 if (desc.ice_ufrag.length() < ICE_UFRAG_MIN_LENGTH || | 83 if (desc.ice_ufrag.length() < ICE_UFRAG_MIN_LENGTH || |
65 desc.ice_ufrag.length() > ICE_UFRAG_MAX_LENGTH) { | 84 desc.ice_ufrag.length() > ICE_UFRAG_MAX_LENGTH) { |
66 return false; | 85 return false; |
67 } | 86 } |
68 if (desc.ice_pwd.length() < ICE_PWD_MIN_LENGTH || | 87 if (desc.ice_pwd.length() < ICE_PWD_MIN_LENGTH || |
(...skipping 24 matching lines...) Expand all Loading... |
93 | 112 |
94 static bool IceCredentialsChanged(const TransportDescription& old_desc, | 113 static bool IceCredentialsChanged(const TransportDescription& old_desc, |
95 const TransportDescription& new_desc) { | 114 const TransportDescription& new_desc) { |
96 return IceCredentialsChanged(old_desc.ice_ufrag, old_desc.ice_pwd, | 115 return IceCredentialsChanged(old_desc.ice_ufrag, old_desc.ice_pwd, |
97 new_desc.ice_ufrag, new_desc.ice_pwd); | 116 new_desc.ice_ufrag, new_desc.ice_pwd); |
98 } | 117 } |
99 | 118 |
100 Transport::Transport(rtc::Thread* signaling_thread, | 119 Transport::Transport(rtc::Thread* signaling_thread, |
101 rtc::Thread* worker_thread, | 120 rtc::Thread* worker_thread, |
102 const std::string& content_name, | 121 const std::string& content_name, |
| 122 const std::string& type, |
103 PortAllocator* allocator) | 123 PortAllocator* allocator) |
104 : signaling_thread_(signaling_thread), | 124 : signaling_thread_(signaling_thread), |
105 worker_thread_(worker_thread), | 125 worker_thread_(worker_thread), |
106 content_name_(content_name), | 126 content_name_(content_name), |
| 127 type_(type), |
107 allocator_(allocator), | 128 allocator_(allocator), |
108 destroyed_(false), | 129 destroyed_(false), |
109 readable_(TRANSPORT_STATE_NONE), | 130 readable_(TRANSPORT_STATE_NONE), |
110 writable_(TRANSPORT_STATE_NONE), | 131 writable_(TRANSPORT_STATE_NONE), |
111 receiving_(TRANSPORT_STATE_NONE), | 132 receiving_(TRANSPORT_STATE_NONE), |
112 was_writable_(false), | 133 was_writable_(false), |
113 connect_requested_(false), | 134 connect_requested_(false), |
114 ice_role_(ICEROLE_UNKNOWN), | 135 ice_role_(ICEROLE_UNKNOWN), |
115 tiebreaker_(0), | 136 tiebreaker_(0), |
| 137 protocol_(ICEPROTO_HYBRID), |
116 remote_ice_mode_(ICEMODE_FULL), | 138 remote_ice_mode_(ICEMODE_FULL), |
117 channel_receiving_timeout_(-1) { | 139 channel_receiving_timeout_(-1) { |
118 } | 140 } |
119 | 141 |
120 Transport::~Transport() { | 142 Transport::~Transport() { |
121 ASSERT(signaling_thread_->IsCurrent()); | 143 ASSERT(signaling_thread_->IsCurrent()); |
122 ASSERT(destroyed_); | 144 ASSERT(destroyed_); |
123 } | 145 } |
124 | 146 |
125 void Transport::SetIceRole(IceRole role) { | 147 void Transport::SetIceRole(IceRole role) { |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 | 348 |
327 if (!local_description_) { | 349 if (!local_description_) { |
328 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here. | 350 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here. |
329 // As Transport must know TD is offer or answer and cricket::Transport | 351 // As Transport must know TD is offer or answer and cricket::Transport |
330 // doesn't have the capability to decide it. This should be set by the | 352 // doesn't have the capability to decide it. This should be set by the |
331 // Session. | 353 // Session. |
332 // Session must generate local TD before remote candidates pushed when | 354 // Session must generate local TD before remote candidates pushed when |
333 // initiate request initiated by the remote. | 355 // initiate request initiated by the remote. |
334 LOG(LS_INFO) << "Transport::ConnectChannels_w: No local description has " | 356 LOG(LS_INFO) << "Transport::ConnectChannels_w: No local description has " |
335 << "been set. Will generate one."; | 357 << "been set. Will generate one."; |
336 TransportDescription desc(std::vector<std::string>(), | 358 TransportDescription desc(NS_GINGLE_P2P, std::vector<std::string>(), |
337 rtc::CreateRandomString(ICE_UFRAG_LENGTH), | 359 rtc::CreateRandomString(ICE_UFRAG_LENGTH), |
338 rtc::CreateRandomString(ICE_PWD_LENGTH), | 360 rtc::CreateRandomString(ICE_PWD_LENGTH), |
339 ICEMODE_FULL, CONNECTIONROLE_NONE, NULL, | 361 ICEMODE_FULL, CONNECTIONROLE_NONE, NULL, |
340 Candidates()); | 362 Candidates()); |
341 SetLocalTransportDescription_w(desc, CA_OFFER, NULL); | 363 SetLocalTransportDescription_w(desc, CA_OFFER, NULL); |
342 } | 364 } |
343 | 365 |
344 CallChannels_w(&TransportChannelImpl::Connect); | 366 CallChannels_w(&TransportChannelImpl::Connect); |
345 if (!channels_.empty()) { | 367 if (!channels_.empty()) { |
346 signaling_thread()->Post(this, MSG_CONNECTING, NULL); | 368 signaling_thread()->Post(this, MSG_CONNECTING, NULL); |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 // If PRANSWER/ANSWER is set, we should decide transport protocol type. | 824 // If PRANSWER/ANSWER is set, we should decide transport protocol type. |
803 if (action == CA_PRANSWER || action == CA_ANSWER) { | 825 if (action == CA_PRANSWER || action == CA_ANSWER) { |
804 ret = NegotiateTransportDescription_w(CA_OFFER, error_desc); | 826 ret = NegotiateTransportDescription_w(CA_OFFER, error_desc); |
805 } | 827 } |
806 return ret; | 828 return ret; |
807 } | 829 } |
808 | 830 |
809 bool Transport::ApplyLocalTransportDescription_w(TransportChannelImpl* ch, | 831 bool Transport::ApplyLocalTransportDescription_w(TransportChannelImpl* ch, |
810 std::string* error_desc) { | 832 std::string* error_desc) { |
811 ASSERT(worker_thread()->IsCurrent()); | 833 ASSERT(worker_thread()->IsCurrent()); |
| 834 // If existing protocol_type is HYBRID, we may have not chosen the final |
| 835 // protocol type, so update the channel protocol type from the |
| 836 // local description. Otherwise, skip updating the protocol type. |
| 837 // We check for HYBRID to avoid accidental changes; in the case of a |
| 838 // session renegotiation, the new offer will have the google-ice ICE option, |
| 839 // so we need to make sure we don't switch back from ICE mode to HYBRID |
| 840 // when this happens. |
| 841 // There are some other ways we could have solved this, but this is the |
| 842 // simplest. The ultimate solution will be to get rid of GICE altogether. |
| 843 IceProtocolType protocol_type; |
| 844 if (ch->GetIceProtocolType(&protocol_type) && |
| 845 protocol_type == ICEPROTO_HYBRID) { |
| 846 ch->SetIceProtocolType( |
| 847 TransportProtocolFromDescription(local_description())); |
| 848 } |
812 ch->SetIceCredentials(local_description_->ice_ufrag, | 849 ch->SetIceCredentials(local_description_->ice_ufrag, |
813 local_description_->ice_pwd); | 850 local_description_->ice_pwd); |
814 return true; | 851 return true; |
815 } | 852 } |
816 | 853 |
817 bool Transport::ApplyRemoteTransportDescription_w(TransportChannelImpl* ch, | 854 bool Transport::ApplyRemoteTransportDescription_w(TransportChannelImpl* ch, |
818 std::string* error_desc) { | 855 std::string* error_desc) { |
819 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag, | 856 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag, |
820 remote_description_->ice_pwd); | 857 remote_description_->ice_pwd); |
821 return true; | 858 return true; |
822 } | 859 } |
823 | 860 |
824 bool Transport::ApplyNegotiatedTransportDescription_w( | 861 bool Transport::ApplyNegotiatedTransportDescription_w( |
825 TransportChannelImpl* channel, std::string* error_desc) { | 862 TransportChannelImpl* channel, std::string* error_desc) { |
826 ASSERT(worker_thread()->IsCurrent()); | 863 ASSERT(worker_thread()->IsCurrent()); |
| 864 channel->SetIceProtocolType(protocol_); |
827 channel->SetRemoteIceMode(remote_ice_mode_); | 865 channel->SetRemoteIceMode(remote_ice_mode_); |
828 return true; | 866 return true; |
829 } | 867 } |
830 | 868 |
831 bool Transport::NegotiateTransportDescription_w(ContentAction local_role, | 869 bool Transport::NegotiateTransportDescription_w(ContentAction local_role, |
832 std::string* error_desc) { | 870 std::string* error_desc) { |
833 ASSERT(worker_thread()->IsCurrent()); | 871 ASSERT(worker_thread()->IsCurrent()); |
834 // TODO(ekr@rtfm.com): This is ICE-specific stuff. Refactor into | 872 // TODO(ekr@rtfm.com): This is ICE-specific stuff. Refactor into |
835 // P2PTransport. | 873 // P2PTransport. |
| 874 const TransportDescription* offer; |
| 875 const TransportDescription* answer; |
| 876 |
| 877 if (local_role == CA_OFFER) { |
| 878 offer = local_description_.get(); |
| 879 answer = remote_description_.get(); |
| 880 } else { |
| 881 offer = remote_description_.get(); |
| 882 answer = local_description_.get(); |
| 883 } |
| 884 |
| 885 TransportProtocol offer_proto = TransportProtocolFromDescription(offer); |
| 886 TransportProtocol answer_proto = TransportProtocolFromDescription(answer); |
| 887 |
| 888 // If offered protocol is gice/ice, then we expect to receive matching |
| 889 // protocol in answer, anything else is treated as an error. |
| 890 // HYBRID is not an option when offered specific protocol. |
| 891 // If offered protocol is HYBRID and answered protocol is HYBRID then |
| 892 // gice is preferred protocol. |
| 893 // TODO(mallinath) - Answer from local or remote should't have both ice |
| 894 // and gice support. It should always pick which protocol it wants to use. |
| 895 // Once WebRTC stops supporting gice (for backward compatibility), HYBRID in |
| 896 // answer must be treated as error. |
| 897 if ((offer_proto == ICEPROTO_GOOGLE || offer_proto == ICEPROTO_RFC5245) && |
| 898 (offer_proto != answer_proto)) { |
| 899 std::ostringstream desc; |
| 900 desc << "Offer and answer protocol mismatch: " |
| 901 << IceProtoToString(offer_proto) |
| 902 << " vs " |
| 903 << IceProtoToString(answer_proto); |
| 904 return BadTransportDescription(desc.str(), error_desc); |
| 905 } |
| 906 protocol_ = answer_proto == ICEPROTO_HYBRID ? ICEPROTO_GOOGLE : answer_proto; |
836 | 907 |
837 // If transport is in ICEROLE_CONTROLLED and remote end point supports only | 908 // If transport is in ICEROLE_CONTROLLED and remote end point supports only |
838 // ice_lite, this local end point should take CONTROLLING role. | 909 // ice_lite, this local end point should take CONTROLLING role. |
839 if (ice_role_ == ICEROLE_CONTROLLED && | 910 if (ice_role_ == ICEROLE_CONTROLLED && |
840 remote_description_->ice_mode == ICEMODE_LITE) { | 911 remote_description_->ice_mode == ICEMODE_LITE) { |
841 SetIceRole_w(ICEROLE_CONTROLLING); | 912 SetIceRole_w(ICEROLE_CONTROLLING); |
842 } | 913 } |
843 | 914 |
844 // Update remote ice_mode to all existing channels. | 915 // Update remote ice_mode to all existing channels. |
845 remote_ice_mode_ = remote_description_->ice_mode; | 916 remote_ice_mode_ = remote_description_->ice_mode; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 break; | 970 break; |
900 case MSG_COMPLETED: | 971 case MSG_COMPLETED: |
901 SignalCompleted(this); | 972 SignalCompleted(this); |
902 break; | 973 break; |
903 case MSG_FAILED: | 974 case MSG_FAILED: |
904 SignalFailed(this); | 975 SignalFailed(this); |
905 break; | 976 break; |
906 } | 977 } |
907 } | 978 } |
908 | 979 |
| 980 // We're GICE if the namespace is NS_GOOGLE_P2P, or if NS_JINGLE_ICE_UDP is |
| 981 // used and the GICE ice-option is set. |
| 982 TransportProtocol TransportProtocolFromDescription( |
| 983 const TransportDescription* desc) { |
| 984 ASSERT(desc != NULL); |
| 985 if (desc->transport_type == NS_JINGLE_ICE_UDP) { |
| 986 return (desc->HasOption(ICE_OPTION_GICE)) ? |
| 987 ICEPROTO_HYBRID : ICEPROTO_RFC5245; |
| 988 } |
| 989 return ICEPROTO_GOOGLE; |
| 990 } |
| 991 |
909 } // namespace cricket | 992 } // namespace cricket |
OLD | NEW |