| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/host/register_support_host_request.h" | 5 #include "remoting/host/register_support_host_request.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/stringize_macros.h" | 14 #include "base/strings/stringize_macros.h" |
| 15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 16 #include "remoting/base/constants.h" | 16 #include "remoting/base/constants.h" |
| 17 #include "remoting/host/host_config.h" | 17 #include "remoting/host/host_config.h" |
| 18 #include "remoting/host/host_details.h" | 18 #include "remoting/host/host_details.h" |
| 19 #include "remoting/protocol/errors.h" |
| 19 #include "remoting/signaling/iq_sender.h" | 20 #include "remoting/signaling/iq_sender.h" |
| 20 #include "remoting/signaling/jid_util.h" | 21 #include "remoting/signaling/jid_util.h" |
| 21 #include "remoting/signaling/signal_strategy.h" | 22 #include "remoting/signaling/signal_strategy.h" |
| 22 #include "remoting/signaling/signaling_address.h" | 23 #include "remoting/signaling/signaling_address.h" |
| 23 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" | 24 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h" |
| 24 #include "third_party/libjingle_xmpp/xmpp/constants.h" | 25 #include "third_party/libjingle_xmpp/xmpp/constants.h" |
| 25 | 26 |
| 26 using buzz::QName; | 27 using buzz::QName; |
| 27 using buzz::XmlElement; | 28 using buzz::XmlElement; |
| 28 | 29 |
| 29 namespace remoting { | 30 namespace remoting { |
| 30 | 31 |
| 31 namespace { | 32 namespace { |
| 32 // Strings used in the request message we send to the bot. | 33 // Strings used in the request message we send to the bot. |
| 33 const char kRegisterQueryTag[] = "register-support-host"; | 34 const char kRegisterQueryTag[] = "register-support-host"; |
| 34 const char kPublicKeyTag[] = "public-key"; | 35 const char kPublicKeyTag[] = "public-key"; |
| 35 const char kSignatureTag[] = "signature"; | 36 const char kSignatureTag[] = "signature"; |
| 36 const char kSignatureTimeAttr[] = "time"; | 37 const char kSignatureTimeAttr[] = "time"; |
| 37 const char kHostVersionTag[] = "host-version"; | 38 const char kHostVersionTag[] = "host-version"; |
| 38 const char kHostOsNameTag[] = "host-os-name"; | 39 const char kHostOsNameTag[] = "host-os-name"; |
| 39 const char kHostOsVersionTag[] = "host-os-version"; | 40 const char kHostOsVersionTag[] = "host-os-version"; |
| 40 | 41 |
| 41 // Strings used to parse responses received from the bot. | 42 // Strings used to parse responses received from the bot. |
| 42 const char kRegisterQueryResultTag[] = "register-support-host-result"; | 43 const char kRegisterQueryResultTag[] = "register-support-host-result"; |
| 43 const char kSupportIdTag[] = "support-id"; | 44 const char kSupportIdTag[] = "support-id"; |
| 44 const char kSupportIdLifetimeTag[] = "support-id-lifetime"; | 45 const char kSupportIdLifetimeTag[] = "support-id-lifetime"; |
| 46 |
| 47 // The signaling timeout for register support host requests. |
| 48 constexpr int kRegisterRequestTimeoutInSeconds = 10; |
| 45 } | 49 } |
| 46 | 50 |
| 47 RegisterSupportHostRequest::RegisterSupportHostRequest( | 51 RegisterSupportHostRequest::RegisterSupportHostRequest( |
| 48 SignalStrategy* signal_strategy, | 52 SignalStrategy* signal_strategy, |
| 49 scoped_refptr<RsaKeyPair> key_pair, | 53 scoped_refptr<RsaKeyPair> key_pair, |
| 50 const std::string& directory_bot_jid, | 54 const std::string& directory_bot_jid, |
| 51 const RegisterCallback& callback) | 55 const RegisterCallback& callback) |
| 52 : signal_strategy_(signal_strategy), | 56 : signal_strategy_(signal_strategy), |
| 53 key_pair_(key_pair), | 57 key_pair_(key_pair), |
| 54 directory_bot_jid_(directory_bot_jid), | 58 directory_bot_jid_(directory_bot_jid), |
| 55 callback_(callback) { | 59 callback_(callback) { |
| 56 DCHECK(signal_strategy_); | 60 DCHECK(signal_strategy_); |
| 57 DCHECK(key_pair_.get()); | 61 DCHECK(key_pair_.get()); |
| 58 signal_strategy_->AddListener(this); | 62 signal_strategy_->AddListener(this); |
| 59 iq_sender_.reset(new IqSender(signal_strategy_)); | 63 iq_sender_.reset(new IqSender(signal_strategy_)); |
| 60 } | 64 } |
| 61 | 65 |
| 62 RegisterSupportHostRequest::~RegisterSupportHostRequest() { | 66 RegisterSupportHostRequest::~RegisterSupportHostRequest() { |
| 63 if (signal_strategy_) | 67 if (signal_strategy_) |
| 64 signal_strategy_->RemoveListener(this); | 68 signal_strategy_->RemoveListener(this); |
| 65 } | 69 } |
| 66 | 70 |
| 67 void RegisterSupportHostRequest::OnSignalStrategyStateChange( | 71 void RegisterSupportHostRequest::OnSignalStrategyStateChange( |
| 68 SignalStrategy::State state) { | 72 SignalStrategy::State state) { |
| 69 if (state == SignalStrategy::CONNECTED) { | 73 if (state == SignalStrategy::CONNECTED) { |
| 70 DCHECK(!callback_.is_null()); | 74 DCHECK(!callback_.is_null()); |
| 71 | |
| 72 request_ = iq_sender_->SendIq( | 75 request_ = iq_sender_->SendIq( |
| 73 buzz::STR_SET, directory_bot_jid_, | 76 buzz::STR_SET, directory_bot_jid_, |
| 74 CreateRegistrationRequest(signal_strategy_->GetLocalAddress().jid()), | 77 CreateRegistrationRequest(signal_strategy_->GetLocalAddress().jid()), |
| 75 base::Bind(&RegisterSupportHostRequest::ProcessResponse, | 78 base::Bind(&RegisterSupportHostRequest::ProcessResponse, |
| 76 base::Unretained(this))); | 79 base::Unretained(this))); |
| 80 if (!request_) { |
| 81 std::string error_message = |
| 82 "Error sending the register-support-host request."; |
| 83 LOG(ERROR) << error_message; |
| 84 CallCallback(std::string(), base::TimeDelta(), error_message); |
| 85 return; |
| 86 } |
| 87 |
| 88 request_->SetTimeout( |
| 89 base::TimeDelta::FromSeconds(kRegisterRequestTimeoutInSeconds)); |
| 90 |
| 77 } else if (state == SignalStrategy::DISCONNECTED) { | 91 } else if (state == SignalStrategy::DISCONNECTED) { |
| 78 // We will reach here if signaling fails to connect. | 92 // We will reach here if signaling fails to connect. |
| 79 std::string error_message = "Signal strategy disconnected."; | 93 std::string error_message = "Signal strategy disconnected."; |
| 80 LOG(ERROR) << error_message; | 94 LOG(ERROR) << error_message; |
| 81 CallCallback(std::string(), base::TimeDelta(), error_message); | 95 CallCallback(std::string(), base::TimeDelta(), error_message); |
| 82 } | 96 } |
| 83 } | 97 } |
| 84 | 98 |
| 85 bool RegisterSupportHostRequest::OnSignalStrategyIncomingStanza( | 99 bool RegisterSupportHostRequest::OnSignalStrategyIncomingStanza( |
| 86 const buzz::XmlElement* stanza) { | 100 const buzz::XmlElement* stanza) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 150 |
| 137 return signature_tag; | 151 return signature_tag; |
| 138 } | 152 } |
| 139 | 153 |
| 140 void RegisterSupportHostRequest::ParseResponse(const XmlElement* response, | 154 void RegisterSupportHostRequest::ParseResponse(const XmlElement* response, |
| 141 std::string* support_id, | 155 std::string* support_id, |
| 142 base::TimeDelta* lifetime, | 156 base::TimeDelta* lifetime, |
| 143 std::string* error_message) { | 157 std::string* error_message) { |
| 144 std::ostringstream error; | 158 std::ostringstream error; |
| 145 | 159 |
| 160 if (!response) { |
| 161 *error_message = "register-support-host request timed out."; |
| 162 return; |
| 163 } |
| 164 |
| 146 std::string type = response->Attr(buzz::QN_TYPE); | 165 std::string type = response->Attr(buzz::QN_TYPE); |
| 147 if (type == buzz::STR_ERROR) { | 166 if (type == buzz::STR_ERROR) { |
| 148 error << "Received error in response to heartbeat: " << response->Str(); | 167 error << "Received error in response to heartbeat: " << response->Str(); |
| 149 *error_message = error.str(); | 168 *error_message = error.str(); |
| 150 LOG(ERROR) << *error_message; | |
| 151 return; | 169 return; |
| 152 } | 170 } |
| 153 | 171 |
| 154 // This method must only be called for error or result stanzas. | 172 // This method must only be called for error or result stanzas. |
| 155 if (type != buzz::STR_RESULT) { | 173 if (type != buzz::STR_RESULT) { |
| 156 error << "Received unexpect stanza of type \"" << type << "\""; | 174 error << "Received unexpect stanza of type \"" << type << "\""; |
| 157 *error_message = error.str(); | 175 *error_message = error.str(); |
| 158 LOG(ERROR) << *error_message; | |
| 159 return; | 176 return; |
| 160 } | 177 } |
| 161 | 178 |
| 162 const XmlElement* result_element = response->FirstNamed(QName( | 179 const XmlElement* result_element = response->FirstNamed(QName( |
| 163 kChromotingXmlNamespace, kRegisterQueryResultTag)); | 180 kChromotingXmlNamespace, kRegisterQueryResultTag)); |
| 164 if (!result_element) { | 181 if (!result_element) { |
| 165 error << "<" << kRegisterQueryResultTag | 182 error << "<" << kRegisterQueryResultTag |
| 166 << "> is missing in the host registration response: " | 183 << "> is missing in the host registration response: " |
| 167 << response->Str(); | 184 << response->Str(); |
| 168 *error_message = error.str(); | 185 *error_message = error.str(); |
| 169 LOG(ERROR) << *error_message; | |
| 170 return; | 186 return; |
| 171 } | 187 } |
| 172 | 188 |
| 173 const XmlElement* support_id_element = | 189 const XmlElement* support_id_element = |
| 174 result_element->FirstNamed(QName(kChromotingXmlNamespace, kSupportIdTag)); | 190 result_element->FirstNamed(QName(kChromotingXmlNamespace, kSupportIdTag)); |
| 175 if (!support_id_element) { | 191 if (!support_id_element) { |
| 176 error << "<" << kSupportIdTag | 192 error << "<" << kSupportIdTag |
| 177 << "> is missing in the host registration response: " | 193 << "> is missing in the host registration response: " |
| 178 << response->Str(); | 194 << response->Str(); |
| 179 *error_message = error.str(); | 195 *error_message = error.str(); |
| 180 LOG(ERROR) << *error_message; | |
| 181 return; | 196 return; |
| 182 } | 197 } |
| 183 | 198 |
| 184 const XmlElement* lifetime_element = | 199 const XmlElement* lifetime_element = |
| 185 result_element->FirstNamed(QName(kChromotingXmlNamespace, | 200 result_element->FirstNamed(QName(kChromotingXmlNamespace, |
| 186 kSupportIdLifetimeTag)); | 201 kSupportIdLifetimeTag)); |
| 187 if (!lifetime_element) { | 202 if (!lifetime_element) { |
| 188 error << "<" << kSupportIdLifetimeTag | 203 error << "<" << kSupportIdLifetimeTag |
| 189 << "> is missing in the host registration response: " | 204 << "> is missing in the host registration response: " |
| 190 << response->Str(); | 205 << response->Str(); |
| 191 *error_message = error.str(); | 206 *error_message = error.str(); |
| 192 LOG(ERROR) << *error_message; | |
| 193 return; | 207 return; |
| 194 } | 208 } |
| 195 | 209 |
| 196 int lifetime_int; | 210 int lifetime_int; |
| 197 if (!base::StringToInt(lifetime_element->BodyText(), &lifetime_int) || | 211 if (!base::StringToInt(lifetime_element->BodyText(), &lifetime_int) || |
| 198 lifetime_int <= 0) { | 212 lifetime_int <= 0) { |
| 199 error << "<" << kSupportIdLifetimeTag | 213 error << "<" << kSupportIdLifetimeTag |
| 200 << "> is malformed in the host registration response: " | 214 << "> is malformed in the host registration response: " |
| 201 << response->Str(); | 215 << response->Str(); |
| 202 *error_message = error.str(); | 216 *error_message = error.str(); |
| 203 LOG(ERROR) << *error_message; | |
| 204 return; | 217 return; |
| 205 } | 218 } |
| 206 | 219 |
| 207 *support_id = support_id_element->BodyText(); | 220 *support_id = support_id_element->BodyText(); |
| 208 *lifetime = base::TimeDelta::FromSeconds(lifetime_int); | 221 *lifetime = base::TimeDelta::FromSeconds(lifetime_int); |
| 209 return; | 222 return; |
| 210 } | 223 } |
| 211 | 224 |
| 212 void RegisterSupportHostRequest::ProcessResponse(IqRequest* request, | 225 void RegisterSupportHostRequest::ProcessResponse(IqRequest* request, |
| 213 const XmlElement* response) { | 226 const XmlElement* response) { |
| 214 std::string support_id; | 227 std::string support_id; |
| 215 base::TimeDelta lifetime; | 228 base::TimeDelta lifetime; |
| 216 std::string error_message; | 229 std::string error_message; |
| 217 ParseResponse(response, &support_id, &lifetime, &error_message); | 230 ParseResponse(response, &support_id, &lifetime, &error_message); |
| 231 if (!error_message.empty()) { |
| 232 LOG(ERROR) << error_message; |
| 233 } |
| 218 CallCallback(support_id, lifetime, error_message); | 234 CallCallback(support_id, lifetime, error_message); |
| 219 } | 235 } |
| 220 | 236 |
| 221 void RegisterSupportHostRequest::CallCallback( | 237 void RegisterSupportHostRequest::CallCallback( |
| 222 const std::string& support_id, | 238 const std::string& support_id, |
| 223 base::TimeDelta lifetime, | 239 base::TimeDelta lifetime, |
| 224 const std::string& error_message) { | 240 const std::string& error_message) { |
| 225 // Cleanup state before calling the callback. | 241 // Cleanup state before calling the callback. |
| 226 request_.reset(); | 242 request_.reset(); |
| 227 iq_sender_.reset(); | 243 iq_sender_.reset(); |
| 228 signal_strategy_->RemoveListener(this); | 244 signal_strategy_->RemoveListener(this); |
| 229 signal_strategy_ = nullptr; | 245 signal_strategy_ = nullptr; |
| 230 | 246 |
| 231 base::ResetAndReturn(&callback_).Run(support_id, lifetime, error_message); | 247 base::ResetAndReturn(&callback_).Run(support_id, lifetime, error_message); |
| 232 } | 248 } |
| 233 | 249 |
| 234 } // namespace remoting | 250 } // namespace remoting |
| OLD | NEW |