Chromium Code Reviews| Index: cloud_print/gcp20/prototype/dns_sd.cc |
| diff --git a/cloud_print/gcp20/prototype/dns_sd.cc b/cloud_print/gcp20/prototype/dns_sd.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e51de03a8bdcc9e2bed57c8c782f7bf5f67f271a |
| --- /dev/null |
| +++ b/cloud_print/gcp20/prototype/dns_sd.cc |
| @@ -0,0 +1,186 @@ |
| +// 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.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 |
| + |
| +DnsSd::DnsSd(): is_online_(false) { |
| + // Do nothing |
| +} |
| + |
| +DnsSd::~DnsSd() { |
| + Shutdown(); |
| +} |
| + |
| +bool DnsSd::Start() { |
| + if (is_online_) |
| + return true; |
| + |
| + if (!BindSocket()) |
| + return false; |
| + |
| + LOG(INFO) << "DNS server started"; |
| + |
| + SendAnnouncement(kDefaultTTL); |
| + |
| + is_online_ = true; |
| + return true; |
| +} |
| + |
| +void DnsSd::Update() { |
| + if (!is_online_) |
| + return; |
| + |
| + SendAnnouncement(kDefaultTTL); |
| +} |
| + |
| +void DnsSd::Shutdown() { |
| + if (!is_online_) |
| + return; |
| + |
| + SendAnnouncement(0); // ttl is 0 |
| + socket_->Close(); |
| + is_online_ = false; |
| + LOG(INFO) << "DNS server stopped"; |
| +} |
| + |
| +bool DnsSd::BindSocket() { |
|
gene
2013/06/06 00:13:51
BindSocket -> CreateSocket ?
maksymb
2013/06/06 01:52:46
Done.
|
| + 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 DnsSd::CheckPendingQueries() { |
| + // write code |
| + return false; |
| +} |
| + |
| +void DoNothing(int /*var*/) { |
| + // Do nothing |
| +} |
| + |
| +void DnsSd::SendAnnouncement(uint32 ttl) { |
| + // Create a message with allocated space for header. |
| + scoped_ptr<std::vector<uint8> > message( |
| + new std::vector<uint8>(sizeof(net::dns_protocol::Header))); |
| + |
| + // These variables will be autimaticaly calculated in |Append*| methods. |
| + question_count_ = 0; |
|
gene
2013/06/06 00:13:51
I think it is better not to make question_count_ a
maksymb
2013/06/06 01:52:46
Done.
|
| + answers_count_ = 0; |
| + |
| + // AppendSrv(ttl, message.get()); |
| + // AppendPtr(ttl, message.get()); |
| + // AppendTxt(ttl, message.get()); |
| + // AppendA(ttl, message.get()); |
| + UpdateHeader(false/*no question*/, message.get()); |
|
gene
2013/06/06 00:13:51
It is better to create header here, or pass all pa
maksymb
2013/06/06 01:52:46
Cleared. Created temporary dump.
|
| + |
| + |
|
gene
2013/06/06 00:13:51
extra empty line
maksymb
2013/06/06 01:52:46
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; |
| +} |
| + |
| +void DnsSd::UpdateHeader(bool is_question, std::vector<uint8>* message) { |
| + net::dns_protocol::Header header; |
| + header.id = 0; |
| + header.flags = 0; // setting flags is below |
| + header.qdcount = question_count_; |
| + header.ancount = answers_count_; |
| + header.nscount = 0; |
| + header.arcount = 0; |
| + |
| + // Setting flags |
| + header.flags = 0; |
| + if (is_question) |
| + header.flags |= net::dns_protocol::kFlagResponse; |
| + |
| + // Putting into message (place for header already should be allocated) |
| + net::BigEndianWriter writer(message->data(), message->size()); |
| + bool success = writer.WriteU16(header.id) && |
| + writer.WriteU16(header.flags) && |
| + writer.WriteU16(header.qdcount) && |
| + writer.WriteU16(header.ancount) && |
| + writer.WriteU16(header.nscount) && |
| + writer.WriteU16(header.arcount); |
| + DCHECK(success); |
| +} |
| + |
| +void DnsSd::AppendSrv(uint32 /*ttl*/, std::vector<uint8>* /* message*/) { |
| + ++answers_count_; |
| +// write code |
|
gene
2013/06/06 00:13:51
"// write code" -> "NOTIMPLEMENTED(); // implemen
maksymb
2013/06/06 01:52:46
Done.
|
| +} |
| + |
| +void DnsSd::AppendPtr(uint32 /*ttl*/, std::vector<uint8>* /* message*/) { |
| + ++answers_count_; |
| +// write code |
| +} |
| + |
| +void DnsSd::AppendTxt(uint32 /*ttl*/, std::vector<uint8>* /* message*/) { |
| + ++answers_count_; |
| +// write code |
| +} |
| + |
| +void DnsSd::AppendA(uint32 /*ttl*/, std::vector<uint8>* /* message*/) { |
| + ++answers_count_; |
| +// write code |
| +} |
| + |