diff options
Diffstat (limited to 'chromium/net/dns/mdns_client_impl.cc')
-rw-r--r-- | chromium/net/dns/mdns_client_impl.cc | 131 |
1 files changed, 53 insertions, 78 deletions
diff --git a/chromium/net/dns/mdns_client_impl.cc b/chromium/net/dns/mdns_client_impl.cc index 1dfc21b37c6..c95b86c6d17 100644 --- a/chromium/net/dns/mdns_client_impl.cc +++ b/chromium/net/dns/mdns_client_impl.cc @@ -24,32 +24,54 @@ namespace net { namespace { + const unsigned MDnsTransactionTimeoutSeconds = 3; + +} // namespace + +void MDnsSocketFactoryImpl::CreateSockets( + ScopedVector<DatagramServerSocket>* sockets) { + InterfaceIndexFamilyList interfaces(GetMDnsInterfacesToBind()); + for (size_t i = 0; i < interfaces.size(); ++i) { + DCHECK(interfaces[i].second == net::ADDRESS_FAMILY_IPV4 || + interfaces[i].second == net::ADDRESS_FAMILY_IPV6); + scoped_ptr<DatagramServerSocket> socket( + CreateAndBindMDnsSocket(interfaces[i].second, interfaces[i].first)); + if (socket) + sockets->push_back(socket.release()); + } } 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) { + scoped_ptr<DatagramServerSocket> socket, + MDnsConnection* connection) + : socket_(socket.Pass()), + connection_(connection), + response_(dns_protocol::kMaxMulticastSize) { } MDnsConnection::SocketHandler::~SocketHandler() { } int MDnsConnection::SocketHandler::Start() { + IPEndPoint end_point; + int rv = socket_->GetLocalAddress(&end_point); + if (rv != OK) + return rv; + DCHECK(end_point.GetFamily() == ADDRESS_FAMILY_IPV4 || + end_point.GetFamily() == ADDRESS_FAMILY_IPV6); + multicast_addr_ = GetMDnsIPEndPoint(end_point.GetFamily()); return DoLoop(0); } 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 +92,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, multicast_addr_, + 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) { } @@ -102,34 +108,29 @@ MDnsConnection::MDnsConnection(MDnsConnection::Delegate* delegate) : 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)); +bool MDnsConnection::Init(MDnsSocketFactory* socket_factory) { + ScopedVector<DatagramServerSocket> sockets; + socket_factory->CreateSockets(&sockets); - for (size_t i = 0; i < socket_handlers_.size();) { - if (socket_handlers_[i]->Bind() != OK) { - socket_handlers_.erase(socket_handlers_.begin() + i); - } else { - ++i; - } + for (size_t i = 0; i < sockets.size(); ++i) { + socket_handlers_.push_back( + 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 // socket. for (size_t i = 0; i < socket_handlers_.size();) { - if (socket_handlers_[i]->Start() != OK) { + int rv = socket_handlers_[i]->Start(); + if (rv != OK) { socket_handlers_.erase(socket_handlers_.begin() + i); + VLOG(1) << "Start failed, socket=" << i << ", error=" << rv; } else { ++i; } } + VLOG(1) << "Sockets ready:" << socket_handlers_.size(); return !socket_handlers_.empty(); } @@ -137,7 +138,11 @@ 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); + if (rv >= OK || rv == ERR_IO_PENDING) { + success = true; + } else { + VLOG(1) << "Send failed, socket=" << i << ", error=" << rv; + } } return success; } @@ -158,34 +163,6 @@ void MDnsConnection::OnDatagramReceived( delegate_->HandlePacket(response, bytes_read); } -class MDnsConnectionSocketFactoryImpl - : public MDnsConnection::SocketFactory { - public: - MDnsConnectionSocketFactoryImpl(); - virtual ~MDnsConnectionSocketFactoryImpl(); - - virtual scoped_ptr<DatagramServerSocket> CreateSocket() OVERRIDE; -}; - -MDnsConnectionSocketFactoryImpl::MDnsConnectionSocketFactoryImpl() { -} - -MDnsConnectionSocketFactoryImpl::~MDnsConnectionSocketFactoryImpl() { -} - -scoped_ptr<DatagramServerSocket> -MDnsConnectionSocketFactoryImpl::CreateSocket() { - return scoped_ptr<DatagramServerSocket>(new UDPServerSocket( - NULL, NetLog::Source())); -} - -// static -scoped_ptr<MDnsConnection::SocketFactory> -MDnsConnection::SocketFactory::CreateDefault() { - return scoped_ptr<MDnsConnection::SocketFactory>( - new MDnsConnectionSocketFactoryImpl); -} - MDnsClientImpl::Core::Core(MDnsClientImpl* client) : client_(client), connection_(new MDnsConnection(this)) { } @@ -194,7 +171,7 @@ MDnsClientImpl::Core::~Core() { STLDeleteValues(&listeners_); } -bool MDnsClientImpl::Core::Init(MDnsConnection::SocketFactory* socket_factory) { +bool MDnsClientImpl::Core::Init(MDnsSocketFactory* socket_factory) { return connection_->Init(socket_factory); } @@ -425,18 +402,16 @@ void MDnsClientImpl::Core::QueryCache( cache_.FindDnsRecords(rrtype, name, records, base::Time::Now()); } -MDnsClientImpl::MDnsClientImpl( - scoped_ptr<MDnsConnection::SocketFactory> socket_factory) - : socket_factory_(socket_factory.Pass()) { +MDnsClientImpl::MDnsClientImpl() { } MDnsClientImpl::~MDnsClientImpl() { } -bool MDnsClientImpl::StartListening() { +bool MDnsClientImpl::StartListening(MDnsSocketFactory* socket_factory) { DCHECK(!core_.get()); core_.reset(new Core(this)); - if (!core_->Init(socket_factory_.get())) { + if (!core_->Init(socket_factory)) { core_.reset(); return false; } |