Revert 225492 "Revert 225155 "Keep running mdns client even if e..."
> Revert 225155 "Keep running mdns client even if either IPv4 or I..."
>
> BUG=298768
>
> > Keep running mdns client even if either IPv4 or IPv6 bind failed.
> >
> > BUG=297212
> > NOTRY=true
> >
> > Review URL: https://chromiumcodereview.appspot.com/23498056
>
> [email protected]
>
> Review URL: https://codereview.chromium.org/24486005
[email protected]
Review URL: https://codereview.chromium.org/24813006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225566 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc
index 4a304684..1dfc21b 100644
--- a/net/dns/mdns_client_impl.cc
+++ b/net/dns/mdns_client_impl.cc
@@ -95,44 +95,51 @@
return socket_->JoinGroup(multicast_addr_.address());
}
-MDnsConnection::MDnsConnection(MDnsConnection::SocketFactory* socket_factory,
- MDnsConnection::Delegate* delegate)
- : socket_handler_ipv4_(this, GetMDnsIPEndPoint(ADDRESS_FAMILY_IPV4),
- socket_factory),
- socket_handler_ipv6_(this, GetMDnsIPEndPoint(ADDRESS_FAMILY_IPV6),
- socket_factory),
+MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) :
delegate_(delegate) {
}
MDnsConnection::~MDnsConnection() {
}
-int MDnsConnection::Init() {
- int rv = socket_handler_ipv4_.Bind();
- if (rv != OK) return rv;
- rv = socket_handler_ipv6_.Bind();
- if (rv != OK) return rv;
+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));
+
+ for (size_t i = 0; i < socket_handlers_.size();) {
+ if (socket_handlers_[i]->Bind() != OK) {
+ socket_handlers_.erase(socket_handlers_.begin() + i);
+ } else {
+ ++i;
+ }
+ }
+
// 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
// socket.
- rv = socket_handler_ipv4_.Start();
- if (rv != OK) return rv;
- rv = socket_handler_ipv6_.Start();
- if (rv != OK) return rv;
-
- return OK;
+ for (size_t i = 0; i < socket_handlers_.size();) {
+ if (socket_handlers_[i]->Start() != OK) {
+ socket_handlers_.erase(socket_handlers_.begin() + i);
+ } else {
+ ++i;
+ }
+ }
+ return !socket_handlers_.empty();
}
-int MDnsConnection::Send(IOBuffer* buffer, unsigned size) {
- int rv;
-
- rv = socket_handler_ipv4_.Send(buffer, size);
- if (rv < OK && rv != ERR_IO_PENDING) return rv;
-
- rv = socket_handler_ipv6_.Send(buffer, size);
- if (rv < OK && rv != ERR_IO_PENDING) return rv;
-
- return OK;
+bool MDnsConnection::Send(IOBuffer* buffer, unsigned size) {
+ bool success = false;
+ for (size_t i = 0; i < socket_handlers_.size(); ++i) {
+ int rv = socket_handlers_[i]->Send(buffer, size);
+ success = success || (rv >= OK || rv == ERR_IO_PENDING);
+ }
+ return success;
}
void MDnsConnection::OnError(SocketHandler* loop,
@@ -179,17 +186,16 @@
new MDnsConnectionSocketFactoryImpl);
}
-MDnsClientImpl::Core::Core(MDnsClientImpl* client,
- MDnsConnection::SocketFactory* socket_factory)
- : client_(client), connection_(new MDnsConnection(socket_factory, this)) {
+MDnsClientImpl::Core::Core(MDnsClientImpl* client)
+ : client_(client), connection_(new MDnsConnection(this)) {
}
MDnsClientImpl::Core::~Core() {
STLDeleteValues(&listeners_);
}
-bool MDnsClientImpl::Core::Init() {
- return connection_->Init() == OK;
+bool MDnsClientImpl::Core::Init(MDnsConnection::SocketFactory* socket_factory) {
+ return connection_->Init(socket_factory);
}
bool MDnsClientImpl::Core::SendQuery(uint16 rrtype, std::string name) {
@@ -200,7 +206,7 @@
DnsQuery query(0, name_dns, rrtype);
query.set_flags(0); // Remove the RD flag from the query. It is unneeded.
- return connection_->Send(query.io_buffer(), query.io_buffer()->size()) == OK;
+ return connection_->Send(query.io_buffer(), query.io_buffer()->size());
}
void MDnsClientImpl::Core::HandlePacket(DnsResponse* response,
@@ -429,8 +435,8 @@
bool MDnsClientImpl::StartListening() {
DCHECK(!core_.get());
- core_.reset(new Core(this, socket_factory_.get()));
- if (!core_->Init()) {
+ core_.reset(new Core(this));
+ if (!core_->Init(socket_factory_.get())) {
core_.reset();
return false;
}
diff --git a/net/dns/mdns_client_impl.h b/net/dns/mdns_client_impl.h
index cbb9f6d..b69677b 100644
--- a/net/dns/mdns_client_impl.h
+++ b/net/dns/mdns_client_impl.h
@@ -11,6 +11,7 @@
#include <vector>
#include "base/cancelable_callback.h"
+#include "base/memory/scoped_vector.h"
#include "base/observer_list.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
@@ -43,13 +44,13 @@
virtual ~Delegate() {}
};
- explicit MDnsConnection(SocketFactory* socket_factory,
- MDnsConnection::Delegate* delegate);
+ explicit MDnsConnection(MDnsConnection::Delegate* delegate);
virtual ~MDnsConnection();
- int Init();
- int Send(IOBuffer* buffer, unsigned size);
+ // Both methods return true if at least one of the socket handlers succeeded.
+ bool Init(MDnsConnection::SocketFactory* socket_factory);
+ bool Send(IOBuffer* buffer, unsigned size);
private:
class SocketHandler {
@@ -85,8 +86,8 @@
void OnError(SocketHandler* loop, int error);
- SocketHandler socket_handler_ipv4_;
- SocketHandler socket_handler_ipv6_;
+ // Only socket handlers which successfully bound and started are kept.
+ ScopedVector<SocketHandler> socket_handlers_;
Delegate* delegate_;
@@ -103,12 +104,11 @@
// invalidate the core.
class Core : public base::SupportsWeakPtr<Core>, MDnsConnection::Delegate {
public:
- Core(MDnsClientImpl* client,
- MDnsConnection::SocketFactory* socket_factory);
+ explicit Core(MDnsClientImpl* client);
virtual ~Core();
// Initialize the core. Returns true on success.
- bool Init();
+ bool Init(MDnsConnection::SocketFactory* socket_factory);
// Send a query with a specific rrtype and name. Returns true on success.
bool SendQuery(uint16 rrtype, std::string name);
diff --git a/net/dns/mdns_client_unittest.cc b/net/dns/mdns_client_unittest.cc
index 324b4df..f524a54 100644
--- a/net/dns/mdns_client_unittest.cc
+++ b/net/dns/mdns_client_unittest.cc
@@ -1025,24 +1025,17 @@
}
virtual scoped_ptr<DatagramServerSocket> CreateSocket() OVERRIDE {
- scoped_ptr<MockMDnsDatagramServerSocket> socket(
- new StrictMock<MockMDnsDatagramServerSocket>);
- sockets_.push(socket.get());
- return socket.PassAs<DatagramServerSocket>();
+ MockMDnsDatagramServerSocket* socket = sockets_.back();
+ sockets_.weak_erase(sockets_.end() - 1);
+ return scoped_ptr<DatagramServerSocket>(socket);
}
- MockMDnsDatagramServerSocket* PopFirstSocket() {
- MockMDnsDatagramServerSocket* socket = sockets_.front();
- sockets_.pop();
- return socket;
- }
-
- size_t num_sockets() {
- return sockets_.size();
+ void PushSocket(MockMDnsDatagramServerSocket* socket) {
+ sockets_.push_back(socket);
}
private:
- std::queue<MockMDnsDatagramServerSocket*> sockets_;
+ ScopedVector<MockMDnsDatagramServerSocket> sockets_;
};
class MockMDnsConnectionDelegate : public MDnsConnection::Delegate {
@@ -1058,16 +1051,16 @@
class MDnsConnectionTest : public ::testing::Test {
public:
- MDnsConnectionTest() : connection_(&factory_, &delegate_) {
+ MDnsConnectionTest() : connection_(&delegate_) {
}
protected:
// Follow successful connection initialization.
virtual void SetUp() OVERRIDE {
- ASSERT_EQ(2u, factory_.num_sockets());
-
- socket_ipv4_ = factory_.PopFirstSocket();
- socket_ipv6_ = factory_.PopFirstSocket();
+ socket_ipv4_ = new MockMDnsDatagramServerSocket;
+ socket_ipv6_ = new MockMDnsDatagramServerSocket;
+ factory_.PushSocket(socket_ipv6_);
+ factory_.PushSocket(socket_ipv4_);
}
bool InitConnection() {
@@ -1087,7 +1080,7 @@
EXPECT_CALL(*socket_ipv6_, JoinGroupInternal("ff02::fb"))
.WillOnce(Return(OK));
- return connection_.Init() == OK;
+ return connection_.Init(&factory_);
}
StrictMock<MockMDnsConnectionDelegate> delegate_;