OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/jingle_session_manager.h" | 5 #include "remoting/protocol/jingle_session_manager.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
| 9 #include "base/base64.h" |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/message_loop_proxy.h" | 11 #include "base/message_loop_proxy.h" |
11 #include "base/string_util.h" | 12 #include "base/string_util.h" |
12 #include "base/task.h" | 13 #include "base/task.h" |
13 #include "remoting/base/constants.h" | 14 #include "remoting/base/constants.h" |
14 #include "remoting/jingle_glue/jingle_info_request.h" | 15 #include "remoting/jingle_glue/jingle_info_request.h" |
15 #include "remoting/jingle_glue/jingle_signaling_connector.h" | 16 #include "remoting/jingle_glue/jingle_signaling_connector.h" |
16 #include "remoting/jingle_glue/signal_strategy.h" | 17 #include "remoting/jingle_glue/signal_strategy.h" |
| 18 #include "remoting/protocol/authenticator.h" |
17 #include "third_party/libjingle/source/talk/base/basicpacketsocketfactory.h" | 19 #include "third_party/libjingle/source/talk/base/basicpacketsocketfactory.h" |
18 #include "third_party/libjingle/source/talk/p2p/base/constants.h" | 20 #include "third_party/libjingle/source/talk/p2p/base/constants.h" |
19 #include "third_party/libjingle/source/talk/p2p/base/sessionmanager.h" | 21 #include "third_party/libjingle/source/talk/p2p/base/sessionmanager.h" |
20 #include "third_party/libjingle/source/talk/p2p/base/transport.h" | 22 #include "third_party/libjingle/source/talk/p2p/base/transport.h" |
21 #include "third_party/libjingle/source/talk/p2p/client/httpportallocator.h" | 23 #include "third_party/libjingle/source/talk/p2p/client/httpportallocator.h" |
22 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 24 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
23 | 25 |
24 using buzz::XmlElement; | 26 using buzz::XmlElement; |
25 | 27 |
26 namespace remoting { | 28 namespace remoting { |
(...skipping 12 matching lines...) Expand all Loading... |
39 JingleSessionManager::~JingleSessionManager() { | 41 JingleSessionManager::~JingleSessionManager() { |
40 // Session manager can be destroyed only after all sessions are destroyed. | 42 // Session manager can be destroyed only after all sessions are destroyed. |
41 DCHECK(sessions_.empty()); | 43 DCHECK(sessions_.empty()); |
42 Close(); | 44 Close(); |
43 } | 45 } |
44 | 46 |
45 void JingleSessionManager::Init( | 47 void JingleSessionManager::Init( |
46 const std::string& local_jid, | 48 const std::string& local_jid, |
47 SignalStrategy* signal_strategy, | 49 SignalStrategy* signal_strategy, |
48 Listener* listener, | 50 Listener* listener, |
49 crypto::RSAPrivateKey* private_key, | |
50 const std::string& certificate, | |
51 bool allow_nat_traversal) { | 51 bool allow_nat_traversal) { |
52 DCHECK(CalledOnValidThread()); | 52 DCHECK(CalledOnValidThread()); |
53 | 53 |
54 DCHECK(signal_strategy); | 54 DCHECK(signal_strategy); |
55 DCHECK(listener); | 55 DCHECK(listener); |
56 | 56 |
57 local_jid_ = local_jid; | 57 local_jid_ = local_jid; |
58 signal_strategy_ = signal_strategy; | 58 signal_strategy_ = signal_strategy; |
59 listener_ = listener; | 59 listener_ = listener; |
60 private_key_.reset(private_key); | |
61 certificate_ = certificate; | |
62 allow_nat_traversal_ = allow_nat_traversal; | 60 allow_nat_traversal_ = allow_nat_traversal; |
63 | 61 |
64 if (!network_manager_.get()) { | 62 if (!network_manager_.get()) { |
65 VLOG(1) << "Creating talk_base::NetworkManager."; | 63 VLOG(1) << "Creating talk_base::NetworkManager."; |
66 network_manager_.reset(new talk_base::BasicNetworkManager()); | 64 network_manager_.reset(new talk_base::BasicNetworkManager()); |
67 } | 65 } |
68 if (!socket_factory_.get()) { | 66 if (!socket_factory_.get()) { |
69 VLOG(1) << "Creating talk_base::BasicPacketSocketFactory."; | 67 VLOG(1) << "Creating talk_base::BasicPacketSocketFactory."; |
70 socket_factory_.reset(new talk_base::BasicPacketSocketFactory( | 68 socket_factory_.reset(new talk_base::BasicPacketSocketFactory( |
71 talk_base::Thread::Current())); | 69 talk_base::Thread::Current())); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 void JingleSessionManager::Close() { | 110 void JingleSessionManager::Close() { |
113 DCHECK(CalledOnValidThread()); | 111 DCHECK(CalledOnValidThread()); |
114 | 112 |
115 if (!closed_) { | 113 if (!closed_) { |
116 cricket_session_manager_->RemoveClient(kChromotingXmlNamespace); | 114 cricket_session_manager_->RemoveClient(kChromotingXmlNamespace); |
117 jingle_signaling_connector_.reset(); | 115 jingle_signaling_connector_.reset(); |
118 closed_ = true; | 116 closed_ = true; |
119 } | 117 } |
120 } | 118 } |
121 | 119 |
| 120 void JingleSessionManager::set_authenticator_factory( |
| 121 AuthenticatorFactory* authenticator_factory) { |
| 122 DCHECK(CalledOnValidThread()); |
| 123 authenticator_factory_.reset(authenticator_factory); |
| 124 } |
| 125 |
122 Session* JingleSessionManager::Connect( | 126 Session* JingleSessionManager::Connect( |
123 const std::string& host_jid, | 127 const std::string& host_jid, |
124 const std::string& host_public_key, | 128 Authenticator* authenticator, |
125 const std::string& receiver_token, | |
126 CandidateSessionConfig* candidate_config, | 129 CandidateSessionConfig* candidate_config, |
127 const Session::StateChangeCallback& state_change_callback) { | 130 const Session::StateChangeCallback& state_change_callback) { |
128 DCHECK(CalledOnValidThread()); | 131 DCHECK(CalledOnValidThread()); |
129 | 132 |
130 // Can be called from any thread. | |
131 JingleSession* jingle_session = | |
132 JingleSession::CreateClientSession(this, host_public_key); | |
133 jingle_session->set_candidate_config(candidate_config); | |
134 jingle_session->set_receiver_token(receiver_token); | |
135 | |
136 cricket::Session* cricket_session = cricket_session_manager_->CreateSession( | 133 cricket::Session* cricket_session = cricket_session_manager_->CreateSession( |
137 local_jid_, kChromotingXmlNamespace); | 134 local_jid_, kChromotingXmlNamespace); |
| 135 cricket_session->set_remote_name(host_jid); |
138 | 136 |
139 // Initialize connection object before we send initiate stanza. | 137 JingleSession* jingle_session = |
| 138 new JingleSession(this, cricket_session, authenticator); |
| 139 jingle_session->set_candidate_config(candidate_config); |
140 jingle_session->SetStateChangeCallback(state_change_callback); | 140 jingle_session->SetStateChangeCallback(state_change_callback); |
141 jingle_session->Init(cricket_session); | |
142 sessions_.push_back(jingle_session); | 141 sessions_.push_back(jingle_session); |
143 | 142 |
144 cricket_session->Initiate(host_jid, CreateClientSessionDescription( | 143 jingle_session->SendSessionInitiate(); |
145 jingle_session->candidate_config()->Clone(), receiver_token)); | |
146 | 144 |
147 return jingle_session; | 145 return jingle_session; |
148 } | 146 } |
149 | 147 |
150 void JingleSessionManager::OnSessionCreate( | 148 void JingleSessionManager::OnSessionCreate( |
151 cricket::Session* cricket_session, bool incoming) { | 149 cricket::Session* cricket_session, bool incoming) { |
152 DCHECK(CalledOnValidThread()); | 150 DCHECK(CalledOnValidThread()); |
153 | 151 |
154 // Allow local connections. | 152 // Allow local connections. |
155 cricket_session->set_allow_local_ips(true); | 153 cricket_session->set_allow_local_ips(true); |
156 | 154 |
157 // If this is an incoming session, create a JingleSession on top of it. | |
158 if (incoming) { | 155 if (incoming) { |
159 DCHECK(!certificate_.empty()); | 156 JingleSession* jingle_session = |
160 DCHECK(private_key_.get()); | 157 new JingleSession(this, cricket_session, NULL); |
161 | |
162 JingleSession* jingle_session = JingleSession::CreateServerSession( | |
163 this, certificate_, private_key_.get()); | |
164 sessions_.push_back(jingle_session); | 158 sessions_.push_back(jingle_session); |
165 jingle_session->Init(cricket_session); | |
166 } | 159 } |
167 } | 160 } |
168 | 161 |
169 void JingleSessionManager::OnSessionDestroy(cricket::Session* cricket_session) { | 162 void JingleSessionManager::OnSessionDestroy(cricket::Session* cricket_session) { |
170 DCHECK(CalledOnValidThread()); | 163 DCHECK(CalledOnValidThread()); |
171 | 164 |
172 std::list<JingleSession*>::iterator it; | 165 std::list<JingleSession*>::iterator it; |
173 for (it = sessions_.begin(); it != sessions_.end(); ++it) { | 166 for (it = sessions_.begin(); it != sessions_.end(); ++it) { |
174 if ((*it)->HasSession(cricket_session)) { | 167 if ((*it)->HasSession(cricket_session)) { |
175 (*it)->ReleaseSession(); | 168 (*it)->ReleaseSession(); |
176 return; | 169 return; |
177 } | 170 } |
178 } | 171 } |
179 } | 172 } |
180 | 173 |
181 bool JingleSessionManager::AcceptConnection( | 174 SessionManager::IncomingSessionResponse JingleSessionManager::AcceptConnection( |
182 JingleSession* jingle_session, | 175 JingleSession* jingle_session) { |
183 cricket::Session* cricket_session) { | |
184 DCHECK(CalledOnValidThread()); | 176 DCHECK(CalledOnValidThread()); |
185 | 177 |
186 // Reject connection if we are closed. | 178 // Reject connection if we are closed. |
187 if (closed_) { | 179 if (closed_) |
188 cricket_session->Reject(cricket::STR_TERMINATE_DECLINE); | 180 return SessionManager::DECLINE; |
189 return false; | |
190 } | |
191 | 181 |
192 const cricket::SessionDescription* session_description = | 182 IncomingSessionResponse response = SessionManager::DECLINE; |
193 cricket_session->remote_description(); | 183 listener_->OnIncomingSession(jingle_session, &response); |
194 const cricket::ContentInfo* content = | 184 return response; |
195 session_description->FirstContentByType(kChromotingXmlNamespace); | 185 } |
196 | 186 |
197 CHECK(content); | 187 Authenticator* JingleSessionManager::CreateAuthenticator( |
| 188 const std::string& jid, const buzz::XmlElement* auth_message) { |
| 189 DCHECK(CalledOnValidThread()); |
198 | 190 |
199 const ContentDescription* content_description = | 191 if (!authenticator_factory_.get()) |
200 static_cast<const ContentDescription*>(content->description); | 192 return NULL; |
201 jingle_session->set_candidate_config(content_description->config()->Clone()); | 193 return authenticator_factory_->CreateAuthenticator(jid, auth_message); |
202 jingle_session->set_initiator_token(content_description->auth_token()); | |
203 | |
204 // Always reject connection if there is no callback. | |
205 IncomingSessionResponse response = protocol::SessionManager::DECLINE; | |
206 | |
207 // Use the callback to generate a response. | |
208 listener_->OnIncomingSession(jingle_session, &response); | |
209 | |
210 switch (response) { | |
211 case SessionManager::ACCEPT: { | |
212 // Connection must be configured by the callback. | |
213 CandidateSessionConfig* candidate_config = | |
214 CandidateSessionConfig::CreateFrom(jingle_session->config()); | |
215 cricket_session->Accept( | |
216 CreateHostSessionDescription(candidate_config, | |
217 jingle_session->local_certificate())); | |
218 break; | |
219 } | |
220 | |
221 case SessionManager::INCOMPATIBLE: { | |
222 cricket_session->TerminateWithReason( | |
223 cricket::STR_TERMINATE_INCOMPATIBLE_PARAMETERS); | |
224 return false; | |
225 } | |
226 | |
227 case SessionManager::DECLINE: { | |
228 cricket_session->TerminateWithReason(cricket::STR_TERMINATE_DECLINE); | |
229 return false; | |
230 } | |
231 | |
232 default: { | |
233 NOTREACHED(); | |
234 } | |
235 } | |
236 | |
237 return true; | |
238 } | 194 } |
239 | 195 |
240 void JingleSessionManager::SessionDestroyed(JingleSession* jingle_session) { | 196 void JingleSessionManager::SessionDestroyed(JingleSession* jingle_session) { |
241 std::list<JingleSession*>::iterator it = | 197 std::list<JingleSession*>::iterator it = |
242 std::find(sessions_.begin(), sessions_.end(), jingle_session); | 198 std::find(sessions_.begin(), sessions_.end(), jingle_session); |
243 CHECK(it != sessions_.end()); | 199 CHECK(it != sessions_.end()); |
244 cricket::Session* cricket_session = jingle_session->ReleaseSession(); | 200 cricket::Session* cricket_session = jingle_session->ReleaseSession(); |
245 cricket_session_manager_->DestroySession(cricket_session); | 201 cricket_session_manager_->DestroySession(cricket_session); |
246 sessions_.erase(it); | 202 sessions_.erase(it); |
247 } | 203 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 const cricket::ContentDescription* content, | 242 const cricket::ContentDescription* content, |
287 XmlElement** elem, | 243 XmlElement** elem, |
288 cricket::WriteError* error) { | 244 cricket::WriteError* error) { |
289 const ContentDescription* desc = | 245 const ContentDescription* desc = |
290 static_cast<const ContentDescription*>(content); | 246 static_cast<const ContentDescription*>(content); |
291 | 247 |
292 *elem = desc->ToXml(); | 248 *elem = desc->ToXml(); |
293 return true; | 249 return true; |
294 } | 250 } |
295 | 251 |
296 // static | |
297 cricket::SessionDescription* | |
298 JingleSessionManager::CreateClientSessionDescription( | |
299 const CandidateSessionConfig* config, | |
300 const std::string& auth_token) { | |
301 cricket::SessionDescription* desc = new cricket::SessionDescription(); | |
302 desc->AddContent( | |
303 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, | |
304 new ContentDescription(config, auth_token, "")); | |
305 return desc; | |
306 } | |
307 | |
308 // static | |
309 cricket::SessionDescription* JingleSessionManager::CreateHostSessionDescription( | |
310 const CandidateSessionConfig* config, | |
311 const std::string& certificate) { | |
312 cricket::SessionDescription* desc = new cricket::SessionDescription(); | |
313 desc->AddContent( | |
314 ContentDescription::kChromotingContentName, kChromotingXmlNamespace, | |
315 new ContentDescription(config, "", certificate)); | |
316 return desc; | |
317 } | |
318 | |
319 } // namespace protocol | 252 } // namespace protocol |
320 } // namespace remoting | 253 } // namespace remoting |
OLD | NEW |