Chromium Code Reviews| Index: remoting/jingle_glue/jingle_info_request.cc |
| diff --git a/remoting/jingle_glue/jingle_info_request.cc b/remoting/jingle_glue/jingle_info_request.cc |
| index b8866b5bc46976f604acfc8fe6a10a9c0b266219..37437299c3ea889dc09990d11368c1bdb58793df 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_address_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,31 @@ |
| namespace remoting { |
| -JingleInfoRequest::JingleInfoRequest(IqRequest* request) |
| - : request_(request) { |
| +struct JingleInfoRequest::PendingDnsRequest { |
|
Wez
2011/08/08 23:07:59
If you made the HostAddressResolver interface more
Sergey Ulanov
2011/08/09 01:42:16
Done.
|
| + PendingDnsRequest(HostAddressRequest* request_value, int port_value) |
| + : request(request_value), |
| + port(port_value) { |
| + } |
| + |
| + scoped_ptr<HostAddressRequest> request; |
| + int port; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(PendingDnsRequest); |
| +}; |
| + |
| +JingleInfoRequest::JingleInfoRequest(IqRequest* request, |
| + HostAddressResolver* host_resolver) |
| + : host_resolver_(host_resolver), |
| + request_(request) { |
| request_->set_callback(NewCallback(this, &JingleInfoRequest::OnResponse)); |
| } |
| JingleInfoRequest::~JingleInfoRequest() { |
| + STLDeleteContainerPairSecondPointers(stun_dns_requests_.begin(), |
| + stun_dns_requests_.end()); |
| + STLDeleteContainerPointers(relay_dns_requests_.begin(), |
| + relay_dns_requests_.end()); |
| } |
| void JingleInfoRequest::Send(const OnJingleInfoCallback& callback) { |
| @@ -28,10 +51,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 +72,17 @@ 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; |
| + if (host_resolver_ == NULL || |
| + net::ParseIPLiteralToNumber(host, &ip_number)) { |
| + stun_hosts_.push_back(talk_base::SocketAddress(host, port)); |
|
Wez
2011/08/08 23:07:59
It might be simpler to mandate that HostAddressReq
Sergey Ulanov
2011/08/09 01:42:16
Done.
|
| + } else { |
| + HostAddressRequest* request = host_resolver_->CreateRequest(); |
| + stun_dns_requests_[request] = new PendingDnsRequest(request, port); |
| + request->SignalDone.connect( |
| + this, &JingleInfoRequest::OnStunAddressResponse); |
| + request->Request(host); |
| + } |
| } |
| } |
| } |
| @@ -61,19 +90,63 @@ 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); |
| + net::IPAddressNumber ip_number; |
| + if (host_resolver_ == NULL || |
| + net::ParseIPLiteralToNumber(host, &ip_number)) { |
| + relay_hosts_.push_back(host); |
|
Wez
2011/08/08 23:07:59
Same here.
Sergey Ulanov
2011/08/09 01:42:16
Actually we don't need to resolve relay hosts.
|
| + } else { |
| + HostAddressRequest* request = host_resolver_->CreateRequest(); |
| + relay_dns_requests_.insert(request); |
| + request->SignalDone.connect( |
| + this, &JingleInfoRequest::OnRelayAddressResponse); |
| + request->Request(host); |
| + } |
| } |
| } |
| } |
| - on_jingle_info_cb_.Run(relay_token, relay_hosts, stun_hosts); |
| + VerifyAllAddressesResolved(); |
| +} |
| + |
| +void JingleInfoRequest::OnStunAddressResponse( |
| + HostAddressRequest* request, |
| + const talk_base::SocketAddress& address) { |
| + RequestsMap::iterator it = stun_dns_requests_.find(request); |
| + DCHECK(it != stun_dns_requests_.end()); |
| + |
| + if (!address.IsNil()) { |
| + stun_hosts_.push_back(talk_base::SocketAddress( |
| + address.ip(), it->second->port)); |
| + } |
| + |
| + MessageLoop::current()->DeleteSoon(FROM_HERE, it->second); |
| + stun_dns_requests_.erase(it); |
| + |
| + VerifyAllAddressesResolved(); |
| +} |
| + |
| +void JingleInfoRequest::OnRelayAddressResponse( |
| + HostAddressRequest* request, |
| + const talk_base::SocketAddress& address) { |
| + if (!address.IsNil()) |
| + relay_hosts_.push_back(address.IPAsString()); |
| + |
| + MessageLoop::current()->DeleteSoon(FROM_HERE, request); |
| + relay_dns_requests_.erase(request); |
| + |
| + VerifyAllAddressesResolved(); |
| +} |
| + |
| +void JingleInfoRequest::VerifyAllAddressesResolved() { |
| + if (stun_dns_requests_.empty() && relay_dns_requests_.empty()) |
| + on_jingle_info_cb_.Run(relay_token_, relay_hosts_, stun_hosts_); |
| } |
| } // namespace remoting |