Index: net/dns/mdns_client_impl.cc |
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc |
index 2a83193d066b6aaf066c914eca62e5471fcc48ea..de04128cc275759bfe70f2ca3964183a4423a638 100644 |
--- a/net/dns/mdns_client_impl.cc |
+++ b/net/dns/mdns_client_impl.cc |
@@ -27,12 +27,11 @@ namespace { |
const unsigned MDnsTransactionTimeoutSeconds = 3; |
} |
-MDnsConnection::SocketHandler::SocketHandler( |
- MDnsConnection* connection, const IPEndPoint& multicast_addr, |
- MDnsConnection::SocketFactory* socket_factory) |
- : socket_(socket_factory->CreateSocket()), connection_(connection), |
- response_(new DnsResponse(dns_protocol::kMaxMulticastSize)), |
- multicast_addr_(multicast_addr) { |
+MDnsConnection::SocketHandler::SocketHandler(scoped_ptr<Socket> socket, |
+ MDnsConnection* connection) |
+ : socket_(socket.Pass()), |
+ connection_(connection), |
+ response_(dns_protocol::kMaxMulticastSize) { |
} |
MDnsConnection::SocketHandler::~SocketHandler() { |
@@ -45,11 +44,11 @@ int MDnsConnection::SocketHandler::Start() { |
int MDnsConnection::SocketHandler::DoLoop(int rv) { |
do { |
if (rv > 0) |
- connection_->OnDatagramReceived(response_.get(), recv_addr_, rv); |
+ connection_->OnDatagramReceived(&response_, recv_addr_, rv); |
rv = socket_->RecvFrom( |
- response_->io_buffer(), |
- response_->io_buffer()->size(), |
+ response_.io_buffer(), |
+ response_.io_buffer()->size(), |
&recv_addr_, |
base::Bind(&MDnsConnection::SocketHandler::OnDatagramReceived, |
base::Unretained(this))); |
@@ -70,31 +69,15 @@ void MDnsConnection::SocketHandler::OnDatagramReceived(int rv) { |
} |
int MDnsConnection::SocketHandler::Send(IOBuffer* buffer, unsigned size) { |
- return socket_->SendTo( |
- buffer, size, multicast_addr_, |
- base::Bind(&MDnsConnection::SocketHandler::SendDone, |
- base::Unretained(this) )); |
+ return socket_->SendTo(buffer, size, |
+ base::Bind(&MDnsConnection::SocketHandler::SendDone, |
+ base::Unretained(this) )); |
} |
void MDnsConnection::SocketHandler::SendDone(int rv) { |
// TODO(noamsml): Retry logic. |
} |
-int MDnsConnection::SocketHandler::Bind() { |
- IPAddressNumber address_any(multicast_addr_.address().size()); |
- |
- IPEndPoint bind_endpoint(address_any, multicast_addr_.port()); |
- |
- socket_->AllowAddressReuse(); |
- int rv = socket_->Listen(bind_endpoint); |
- |
- if (rv < OK) return rv; |
- |
- socket_->SetMulticastLoopbackMode(false); |
- |
- return socket_->JoinGroup(multicast_addr_.address()); |
-} |
- |
MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) : |
delegate_(delegate) { |
} |
@@ -103,24 +86,14 @@ MDnsConnection::~MDnsConnection() { |
} |
bool MDnsConnection::Init(MDnsConnection::SocketFactory* socket_factory) { |
- // TODO(vitalybuka): crbug.com/297690 Make socket_factory return list |
- // of initialized sockets. |
- socket_handlers_.push_back( |
- new SocketHandler(this, GetMDnsIPEndPoint(ADDRESS_FAMILY_IPV4), |
- socket_factory)); |
- socket_handlers_.push_back( |
- new SocketHandler(this, GetMDnsIPEndPoint(ADDRESS_FAMILY_IPV6), |
- socket_factory)); |
+ ScopedVector<Socket> sockets; |
+ socket_factory->CreateSockets(&sockets); |
- for (size_t i = 0; i < socket_handlers_.size();) { |
- int rv = socket_handlers_[i]->Bind(); |
- if (rv != OK) { |
- socket_handlers_.erase(socket_handlers_.begin() + i); |
- VLOG(1) << "Bind failed, socket=" << i << ", error=" << rv; |
- } else { |
- ++i; |
- } |
+ for (size_t i = 0; i < sockets.size(); ++i) { |
+ socket_handlers_.push_back( |
szym
2013/11/27 00:28:09
Empty sockets (which failed to bind in CreateSocke
Vitaly Buka (NO REVIEWS)
2013/11/27 00:45:45
CreateSockets should filter. That was initial idea
|
+ new MDnsConnection::SocketHandler(make_scoped_ptr(sockets[i]), this)); |
} |
+ sockets.weak_clear(); |
// All unbound sockets need to be bound before processing untrusted input. |
// This is done for security reasons, so that an attacker can't get an unbound |
@@ -167,26 +140,73 @@ void MDnsConnection::OnDatagramReceived( |
delegate_->HandlePacket(response, bytes_read); |
} |
-class MDnsConnectionSocketFactoryImpl |
- : public MDnsConnection::SocketFactory { |
+class SocketImpl : public MDnsConnection::Socket { |
public: |
- MDnsConnectionSocketFactoryImpl(); |
- virtual ~MDnsConnectionSocketFactoryImpl(); |
+ explicit SocketImpl(const IPEndPoint& multicast_addr) |
+ : multicast_addr_(multicast_addr), |
+ socket_(NULL, NetLog::Source()) {}; |
+ virtual ~SocketImpl() {}; |
+ |
+ int Bind() { |
+ IPAddressNumber address_any(multicast_addr_.address().size()); |
+ IPEndPoint bind_endpoint(address_any, multicast_addr_.port()); |
+ |
+ socket_.AllowAddressReuse(); |
+ int rv = socket_.Listen(bind_endpoint); |
+ if (rv < OK) |
+ return rv; |
+ |
+ socket_.SetMulticastLoopbackMode(false); |
+ return socket_.JoinGroup(multicast_addr_.address()); |
+ } |
- virtual scoped_ptr<DatagramServerSocket> CreateSocket() OVERRIDE; |
+ virtual int RecvFrom(IOBuffer* buf, |
+ int buf_len, |
+ IPEndPoint* address, |
+ const CompletionCallback& callback) OVERRIDE { |
+ return socket_.RecvFrom(buf, buf_len, address, callback); |
+ } |
+ |
+ virtual int SendTo(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) OVERRIDE { |
+ return socket_.SendTo(buf, buf_len, multicast_addr_, callback); |
+ } |
+ |
+ private: |
+ IPEndPoint multicast_addr_; |
+ UDPServerSocket socket_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SocketImpl); |
}; |
-MDnsConnectionSocketFactoryImpl::MDnsConnectionSocketFactoryImpl() { |
-} |
+class MDnsConnectionSocketFactoryImpl |
+ : public MDnsConnection::SocketFactory { |
+ public: |
+ MDnsConnectionSocketFactoryImpl() {}; |
+ virtual ~MDnsConnectionSocketFactoryImpl() {}; |
-MDnsConnectionSocketFactoryImpl::~MDnsConnectionSocketFactoryImpl() { |
-} |
+ virtual void CreateSockets( |
+ ScopedVector<MDnsConnection::Socket>* sockets) OVERRIDE { |
+ sockets->push_back(CreateSocket(ADDRESS_FAMILY_IPV4).release()); |
+ sockets->push_back(CreateSocket(ADDRESS_FAMILY_IPV6).release()); |
+ } |
-scoped_ptr<DatagramServerSocket> |
-MDnsConnectionSocketFactoryImpl::CreateSocket() { |
- return scoped_ptr<DatagramServerSocket>(new UDPServerSocket( |
- NULL, NetLog::Source())); |
-} |
+ private: |
+ scoped_ptr<MDnsConnection::Socket> CreateSocket( |
+ AddressFamily address_family) { |
+ scoped_ptr<SocketImpl> socket( |
+ new SocketImpl(GetMDnsIPEndPoint(address_family))); |
+ int rv = socket->Bind(); |
+ if (rv != OK) { |
+ VLOG(1) << "Bind failed, family=" << address_family << ", error=" << rv; |
+ socket.reset(); |
+ } |
+ return socket.PassAs<MDnsConnection::Socket>(); |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MDnsConnectionSocketFactoryImpl); |
+}; |
// static |
scoped_ptr<MDnsConnection::SocketFactory> |