diff options
author | maksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-07 08:23:20 +0000 |
---|---|---|
committer | maksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-07 08:23:20 +0000 |
commit | fda3b119daf1a351d53a2e5eb01ff3cb78d00cef (patch) | |
tree | 77aae154f21901d072797aae2d27e99c28b414f2 | |
parent | b9beabbf7ff8dab6b53091b8fbf6ba1d12836b15 (diff) | |
download | chromium_src-fda3b119daf1a351d53a2e5eb01ff3cb78d00cef.zip chromium_src-fda3b119daf1a351d53a2e5eb01ff3cb78d00cef.tar.gz chromium_src-fda3b119daf1a351d53a2e5eb01ff3cb78d00cef.tar.bz2 |
GCP2.0 Device: mDNS basics
Socket binding and sending empty announcements
BUG=
Review URL: https://chromiumcodereview.appspot.com/16389002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204754 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cloud_print/cloud_print.gyp | 1 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/dns_sd_server.cc | 137 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/dns_sd_server.h | 62 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/gcp20_device.cc | 28 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/gcp20_device.gyp | 41 |
5 files changed, 269 insertions, 0 deletions
diff --git a/cloud_print/cloud_print.gyp b/cloud_print/cloud_print.gyp index b746f41..cf3c543 100644 --- a/cloud_print/cloud_print.gyp +++ b/cloud_print/cloud_print.gyp @@ -58,6 +58,7 @@ 'type': 'none', 'dependencies': [ 'service/service.gyp:*', + 'gcp20/prototype/gcp20_device.gyp:*', ], 'conditions': [ ['OS=="win"', { 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 0000000..0ca8b43 --- /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 DnsResponse class + + // Preparing for sending + scoped_refptr<net::IOBufferWithSize> buffer = + new net::IOBufferWithSize(static_cast<int>(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; +} + diff --git a/cloud_print/gcp20/prototype/dns_sd_server.h b/cloud_print/gcp20/prototype/dns_sd_server.h new file mode 100644 index 0000000..9c8ed96 --- /dev/null +++ b/cloud_print/gcp20/prototype/dns_sd_server.h @@ -0,0 +1,62 @@ +// 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. + +#ifndef GCP20_PROTOTYPE_DNS_SD_H_ +#define GCP20_PROTOTYPE_DNS_SD_H_ + +#include <vector> + +#include "net/dns/dns_protocol.h" +#include "net/udp/udp_socket.h" + +// Class for sending multicast announcements, receiving queries and answering on +// them. Client should call |ProccessMessages| periodically to make server work. +class DnsSdServer { + public: + // Constructs unstarted server. + DnsSdServer(); + + // Stops server. + ~DnsSdServer(); + + // Starts the server. Returns |true| if server works. Also sends + // announcement. + bool Start(); + + // Sends announcement if server works. + void Update(); + + // Stops server with announcement. + void Shutdown(); + + // Process pending queries for the server. + void ProcessMessages(); + + // Returns |true| if server works. + bool is_online() { return is_online_; } + + private: + // Binds a socket to multicast address. Returns |true| on success. + bool CreateSocket(); + + // Sends announcement. + void SendAnnouncement(uint32 ttl); + + // Returns |true| if server received some questions. + bool CheckPendingQueries(); + + // Stores |true| if server was started. + bool is_online_; + + // Stores socket to multicast address. + scoped_ptr<net::UDPSocket> socket_; + + // Stores multicast address end point. + net::IPEndPoint multicast_address_; + + DISALLOW_COPY_AND_ASSIGN(DnsSdServer); +}; + +#endif // GCP20_PROTOTYPE_DNS_SD_H_ + diff --git a/cloud_print/gcp20/prototype/gcp20_device.cc b/cloud_print/gcp20/prototype/gcp20_device.cc new file mode 100644 index 0000000..f210063 --- /dev/null +++ b/cloud_print/gcp20/prototype/gcp20_device.cc @@ -0,0 +1,28 @@ +// 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 <stdio.h> + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/threading/platform_thread.h" +#include "cloud_print/gcp20/prototype/dns_sd_server.h" + +int main(int argc, char* argv[]) { + CommandLine::Init(argc, argv); + + logging::InitLogging(NULL, + logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, + logging::LOCK_LOG_FILE, + logging::APPEND_TO_OLD_LOG_FILE, + logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); + + DnsSdServer dns_sd_server; + dns_sd_server.Start(); + base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(2)); + dns_sd_server.Shutdown(); + + return 0; +} + diff --git a/cloud_print/gcp20/prototype/gcp20_device.gyp b/cloud_print/gcp20/prototype/gcp20_device.gyp new file mode 100644 index 0000000..7946960 --- /dev/null +++ b/cloud_print/gcp20/prototype/gcp20_device.gyp @@ -0,0 +1,41 @@ +# 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. + +{ + 'target_defaults': { + 'variables': { + 'chromium_code': 1, + 'enable_wexit_time_destructors': 1, + }, + 'include_dirs': [ + '<(DEPTH)', + # To allow including "version.h" + '<(SHARED_INTERMEDIATE_DIR)', + ], + }, + 'targets': [ + { + 'target_name': 'gcp20_device', + 'type': 'executable', + 'dependencies': [ + '<(DEPTH)/base/base.gyp:base', + '<(DEPTH)/net/net.gyp:net', + ], + 'sources': [ + 'dns_sd_server.cc', + 'gcp20_device.cc', + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'SubSystem': '1', # Set /SUBSYSTEM:CONSOLE + 'AdditionalDependencies': [ + 'secur32.lib', + 'httpapi.lib', + 'Ws2_32.lib', + ], + }, + }, + }, + ], +} |