Chromium Code Reviews| Index: cloud_print/gcp20/prototype/dns_sd_server.cc |
| diff --git a/cloud_print/gcp20/prototype/dns_sd_server.cc b/cloud_print/gcp20/prototype/dns_sd_server.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a0fcda4a6ae2c1179b5e627dc5ae6d7ca16531f7 |
| --- /dev/null |
| +++ b/cloud_print/gcp20/prototype/dns_sd_server.cc |
| @@ -0,0 +1,137 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "cloud_print/gcp20/prototype/dns_sd_server.h" |
| + |
| +#include <string.h> |
| + |
| +#include "base/basictypes.h" |
| +#include "net/base/big_endian.h" |
| +#include "net/base/net_util.h" |
| +#include "net/dns/dns_protocol.h" |
| + |
| +namespace { |
| + |
| +const char* kDefaultIpAddressMulticast = "224.0.0.251"; |
| +const uint16 kDefaultPortMulticast = 5353; |
| + |
| +// TODO(maksymb): Add possibility to set constants via command line arguments |
| +const uint32 kDefaultTTL = 60*60; // in seconds |
| + |
| +} // namespace |
| + |
| +DnsSdServer::DnsSdServer(): is_online_(false) { |
| + // Do nothing |
| +} |
| + |
| +DnsSdServer::~DnsSdServer() { |
| + Shutdown(); |
| +} |
| + |
| +bool DnsSdServer::Start() { |
| + if (is_online_) |
| + return true; |
| + |
| + if (!CreateSocket()) |
| + return false; |
| + |
| + LOG(INFO) << "DNS server started"; |
| + |
| + SendAnnouncement(kDefaultTTL); |
| + |
| + is_online_ = true; |
| + return true; |
| +} |
| + |
| +void DnsSdServer::Update() { |
| + if (!is_online_) |
| + return; |
| + |
| + SendAnnouncement(kDefaultTTL); |
| +} |
| + |
| +void DnsSdServer::Shutdown() { |
| + if (!is_online_) |
| + return; |
| + |
| + SendAnnouncement(0); // ttl is 0 |
| + socket_->Close(); |
| + is_online_ = false; |
| + LOG(INFO) << "DNS server stopped"; |
| +} |
| + |
| +void DnsSdServer::ProcessMessages() { |
| + NOTIMPLEMENTED(); // implement this |
| +} |
| + |
| +bool DnsSdServer::CreateSocket() { |
| + net::IPAddressNumber local_ip_any; |
| + bool success = net::ParseIPLiteralToNumber("0.0.0.0", &local_ip_any); |
| + DCHECK(success); |
| + |
| + net::IPAddressNumber multicast_dns_ip_address; |
| + success = net::ParseIPLiteralToNumber(kDefaultIpAddressMulticast, |
| + &multicast_dns_ip_address); |
| + DCHECK(success); |
| + |
| + |
| + socket_.reset(new net::UDPSocket(net::DatagramSocket::DEFAULT_BIND, |
| + net::RandIntCallback(), |
| + NULL, |
| + net::NetLog::Source())); |
| + |
| + net::IPEndPoint local_address = net::IPEndPoint(local_ip_any, |
| + kDefaultPortMulticast); |
| + multicast_address_ = net::IPEndPoint(multicast_dns_ip_address, |
| + kDefaultPortMulticast); |
| + |
| + socket_->AllowAddressReuse(); |
| + |
| + int status = socket_->Bind(local_address); |
| + if (status < 0) |
| + return false; |
| + |
| + socket_->SetMulticastLoopbackMode(false); |
| + status = socket_->JoinGroup(multicast_dns_ip_address); |
| + |
| + if (status < 0) |
| + return false; |
| + |
| + DCHECK(socket_->is_connected()); |
| + |
| + return true; |
| +} |
| + |
| +bool DnsSdServer::CheckPendingQueries() { |
| + NOTIMPLEMENTED(); // implement this |
| + return false; |
| +} |
| + |
| +void DoNothing(int /*var*/) { |
| + // Do nothing |
| +} |
| + |
| +void DnsSdServer::SendAnnouncement(uint32 ttl) { |
| + // Create a message with allocated space for header. |
| + // DNS header is temporary empty. |
| + scoped_ptr<std::vector<uint8> > message( |
| + new std::vector<uint8>(sizeof(net::dns_protocol::Header), 0)); // all is 0 |
| + |
| + // TODO(maksymb): Create and implement DnsResponce class |
|
gene
2013/06/06 02:41:20
DnsResponce -> DnsResponse
maksymb
2013/06/06 16:43:34
Done.
|
| + |
| + // Preparing for sending |
| + scoped_refptr<net::IOBufferWithSize> buffer = |
| + new net::IOBufferWithSize(message.get()->size()); |
| + memcpy(buffer.get()->data(), message.get()->data(), message.get()->size()); |
| + |
| + // Create empty callback (we don't need it at all) and send packet |
| + net::CompletionCallback callback = base::Bind(DoNothing); |
| + socket_->SendTo(buffer.get(), |
| + buffer.get()->size(), |
| + multicast_address_, |
| + callback); |
| + |
| + LOG(INFO) << "Announcement was sent with TTL: " << ttl; |
| +} |
| + |