| 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..f2bbc5b0ff4efd6e83dd4640d2393db8c75e99ba 100644
|
| --- a/net/dns/mdns_client_impl.cc
|
| +++ b/net/dns/mdns_client_impl.cc
|
| @@ -24,32 +24,77 @@
|
| namespace net {
|
|
|
| namespace {
|
| +
|
| const unsigned MDnsTransactionTimeoutSeconds = 3;
|
| +
|
| +int Bind(const IPEndPoint& multicast_addr, DatagramServerSocket* socket) {
|
| + 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());
|
| +}
|
| +
|
| +void CreateAndBindSocket(AddressFamily address_family,
|
| + ScopedVector<DatagramServerSocket>* sockets) {
|
| + scoped_ptr<DatagramServerSocket> socket(
|
| + new UDPServerSocket(NULL, NetLog::Source()));
|
| +
|
| + IPEndPoint multicast_addr = GetMDnsIPEndPoint(address_family);
|
| + int rv = Bind(multicast_addr, socket.get());
|
| + if (rv == OK) {
|
| + sockets->push_back(socket.release());
|
| + } else {
|
| + VLOG(1) << "Bind failed, endpoint=" << multicast_addr.ToStringWithoutPort()
|
| + << ", error=" << rv;
|
| + }
|
| }
|
|
|
| +} // namespace
|
| +
|
| +void MDnsSocketFactoryImpl::CreateSockets(
|
| + ScopedVector<DatagramServerSocket>* sockets) {
|
| + CreateAndBindSocket(ADDRESS_FAMILY_IPV4, sockets);
|
| + CreateAndBindSocket(ADDRESS_FAMILY_IPV6, sockets);
|
| +}
|
| +
|
| +
|
| +
|
| 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 +115,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,25 +131,15 @@ 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();) {
|
| - 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(
|
| + 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,34 +186,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)) {
|
| }
|
| @@ -203,7 +194,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);
|
| }
|
|
|
| @@ -434,18 +425,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;
|
| }
|
|
|