summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-07 08:23:20 +0000
committermaksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-07 08:23:20 +0000
commitfda3b119daf1a351d53a2e5eb01ff3cb78d00cef (patch)
tree77aae154f21901d072797aae2d27e99c28b414f2
parentb9beabbf7ff8dab6b53091b8fbf6ba1d12836b15 (diff)
downloadchromium_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.gyp1
-rw-r--r--cloud_print/gcp20/prototype/dns_sd_server.cc137
-rw-r--r--cloud_print/gcp20/prototype/dns_sd_server.h62
-rw-r--r--cloud_print/gcp20/prototype/gcp20_device.cc28
-rw-r--r--cloud_print/gcp20/prototype/gcp20_device.gyp41
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',
+ ],
+ },
+ },
+ },
+ ],
+}