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