diff options
Diffstat (limited to 'remoting/jingle_glue')
-rw-r--r-- | remoting/jingle_glue/host_resolver.cc | 13 | ||||
-rw-r--r-- | remoting/jingle_glue/host_resolver.h | 45 | ||||
-rw-r--r-- | remoting/jingle_glue/jingle_info_request.cc | 46 | ||||
-rw-r--r-- | remoting/jingle_glue/jingle_info_request.h | 22 |
4 files changed, 111 insertions, 15 deletions
diff --git a/remoting/jingle_glue/host_resolver.cc b/remoting/jingle_glue/host_resolver.cc new file mode 100644 index 0000000..5ad3316 --- /dev/null +++ b/remoting/jingle_glue/host_resolver.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/jingle_glue/host_resolver.h" + +namespace remoting { + +HostResolver::HostResolver() { } + +HostResolver::~HostResolver() { } + +} // namespace remoting diff --git a/remoting/jingle_glue/host_resolver.h b/remoting/jingle_glue/host_resolver.h new file mode 100644 index 0000000..d74ae2b --- /dev/null +++ b/remoting/jingle_glue/host_resolver.h @@ -0,0 +1,45 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_JINGLE_GLUE_HOST_RESOLVER_H_ +#define REMOTING_JINGLE_GLUE_HOST_RESOLVER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "third_party/libjingle/source/talk/base/sigslot.h" +#include "third_party/libjingle/source/talk/base/socketaddress.h" + +namespace remoting { + +// TODO(sergeyu): Move HostResolver and HostResolverFactory to +// libjingle and use them in StunPort. + +class HostResolver { + public: + HostResolver(); + virtual ~HostResolver(); + + virtual void Resolve(const talk_base::SocketAddress& address) = 0; + + sigslot::signal2<HostResolver*, const talk_base::SocketAddress&> SignalDone; + + private: + DISALLOW_COPY_AND_ASSIGN(HostResolver); +}; + +class HostResolverFactory { + public: + HostResolverFactory() { } + virtual ~HostResolverFactory() { } + + virtual HostResolver* CreateHostResolver() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(HostResolverFactory); +}; + +} // namespace remoting + +#endif // REMOTING_JINGLE_GLUE_HOST_RESOLVER_H_ diff --git a/remoting/jingle_glue/jingle_info_request.cc b/remoting/jingle_glue/jingle_info_request.cc index b8866b5..1dabf26 100644 --- a/remoting/jingle_glue/jingle_info_request.cc +++ b/remoting/jingle_glue/jingle_info_request.cc @@ -5,7 +5,11 @@ #include "remoting/jingle_glue/jingle_info_request.h" #include "base/task.h" +#include "base/message_loop.h" +#include "base/stl_util.h" #include "base/string_number_conversions.h" +#include "net/base/net_util.h" +#include "remoting/jingle_glue/host_resolver.h" #include "remoting/jingle_glue/iq_request.h" #include "third_party/libjingle/source/talk/base/socketaddress.h" #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" @@ -13,12 +17,17 @@ namespace remoting { -JingleInfoRequest::JingleInfoRequest(IqRequest* request) - : request_(request) { + +JingleInfoRequest::JingleInfoRequest(IqRequest* request, + HostResolverFactory* host_resolver_factory) + : host_resolver_factory_(host_resolver_factory), + request_(request) { request_->set_callback(NewCallback(this, &JingleInfoRequest::OnResponse)); } JingleInfoRequest::~JingleInfoRequest() { + STLDeleteContainerPointers(stun_dns_requests_.begin(), + stun_dns_requests_.end()); } void JingleInfoRequest::Send(const OnJingleInfoCallback& callback) { @@ -28,10 +37,6 @@ void JingleInfoRequest::Send(const OnJingleInfoCallback& callback) { } void JingleInfoRequest::OnResponse(const buzz::XmlElement* stanza) { - std::vector<std::string> relay_hosts; - std::vector<talk_base::SocketAddress> stun_hosts; - std::string relay_token; - const buzz::XmlElement* query = stanza->FirstNamed(buzz::QN_JINGLE_INFO_QUERY); if (query == NULL) { @@ -53,7 +58,12 @@ void JingleInfoRequest::OnResponse(const buzz::XmlElement* stanza) { if (!base::StringToInt(port_str, &port)) { LOG(WARNING) << "Unable to parse port in stanza" << stanza->Str(); } else { - stun_hosts.push_back(talk_base::SocketAddress(host, port)); + net::IPAddressNumber ip_number; + HostResolver* resolver = host_resolver_factory_->CreateHostResolver(); + stun_dns_requests_.insert(resolver); + resolver->SignalDone.connect( + this, &JingleInfoRequest::OnStunAddressResponse); + resolver->Resolve(talk_base::SocketAddress(host, port)); } } } @@ -61,19 +71,31 @@ void JingleInfoRequest::OnResponse(const buzz::XmlElement* stanza) { const buzz::XmlElement* relay = query->FirstNamed(buzz::QN_JINGLE_INFO_RELAY); if (relay) { - relay_token = relay->TextNamed(buzz::QN_JINGLE_INFO_TOKEN); + relay_token_ = relay->TextNamed(buzz::QN_JINGLE_INFO_TOKEN); for (const buzz::XmlElement* server = relay->FirstNamed(buzz::QN_JINGLE_INFO_SERVER); server != NULL; server = server->NextNamed(buzz::QN_JINGLE_INFO_SERVER)) { std::string host = server->Attr(buzz::QN_JINGLE_INFO_HOST); - if (host != buzz::STR_EMPTY) { - relay_hosts.push_back(host); - } + if (host != buzz::STR_EMPTY) + relay_hosts_.push_back(host); } } - on_jingle_info_cb_.Run(relay_token, relay_hosts, stun_hosts); + if (stun_dns_requests_.empty()) + on_jingle_info_cb_.Run(relay_token_, relay_hosts_, stun_hosts_); +} + +void JingleInfoRequest::OnStunAddressResponse( + HostResolver* resolver, const talk_base::SocketAddress& address) { + if (!address.IsNil()) + stun_hosts_.push_back(address); + + MessageLoop::current()->DeleteSoon(FROM_HERE, resolver); + stun_dns_requests_.erase(resolver); + + if (stun_dns_requests_.empty()) + on_jingle_info_cb_.Run(relay_token_, relay_hosts_, stun_hosts_); } } // namespace remoting diff --git a/remoting/jingle_glue/jingle_info_request.h b/remoting/jingle_glue/jingle_info_request.h index 9a63f82..df7552f 100644 --- a/remoting/jingle_glue/jingle_info_request.h +++ b/remoting/jingle_glue/jingle_info_request.h @@ -5,12 +5,14 @@ #ifndef REMOTING_JINGLE_GLUE_JINGLE_INFO_REQUEST_H_ #define REMOTING_JINGLE_GLUE_JINGLE_INFO_REQUEST_H_ +#include <set> #include <string> #include <vector> #include "base/basictypes.h" #include "base/callback.h" #include "base/memory/scoped_ptr.h" +#include "third_party/libjingle/source/talk/base/sigslot.h" class Task; @@ -25,6 +27,8 @@ class SocketAddress; namespace remoting { class IqRequest; +class HostResolver; +class HostResolverFactory; // JingleInfoRequest handles requesting STUN/Relay infromation from // the Google Talk network. The query is made when Send() is @@ -35,7 +39,7 @@ class IqRequest; // created on. // // TODO(ajwong): Add support for a timeout. -class JingleInfoRequest { +class JingleInfoRequest : public sigslot::has_slots<> { public: // Callback to receive the Jingle configuration settings. The argumetns are // passed by pointer so the receive may call swap on them. The receiver does @@ -45,17 +49,29 @@ class JingleInfoRequest { const std::string&, const std::vector<std::string>&, const std::vector<talk_base::SocketAddress>&)> OnJingleInfoCallback; - explicit JingleInfoRequest(IqRequest* request); - ~JingleInfoRequest(); + explicit JingleInfoRequest(IqRequest* request, + HostResolverFactory* host_resolver_factory); + virtual ~JingleInfoRequest(); void Send(const OnJingleInfoCallback& callback); private: + struct PendingDnsRequest; + void OnResponse(const buzz::XmlElement* stanza); + void OnStunAddressResponse(HostResolver* resolver, + const talk_base::SocketAddress& address); + HostResolverFactory* host_resolver_factory_; scoped_ptr<IqRequest> request_; OnJingleInfoCallback on_jingle_info_cb_; + std::vector<std::string> relay_hosts_; + std::vector<talk_base::SocketAddress> stun_hosts_; + std::string relay_token_; + + std::set<HostResolver*> stun_dns_requests_; + DISALLOW_COPY_AND_ASSIGN(JingleInfoRequest); }; |