Index: remoting/host/gnubby_advertiser.cc |
diff --git a/remoting/host/gnubby_advertiser.cc b/remoting/host/gnubby_advertiser.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c33f2f2e65e1d1779ddb146f3366d199a3b8865a |
--- /dev/null |
+++ b/remoting/host/gnubby_advertiser.cc |
@@ -0,0 +1,135 @@ |
+// Copyright 2014 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 "remoting/host/gnubby_advertiser.h" |
+ |
+#include <string> |
+ |
+#include "base/bind.h" |
+#include "base/strings/stringprintf.h" |
+#include "net/base/address_list.h" |
+#include "net/base/io_buffer.h" |
+#include "net/base/ip_endpoint.h" |
+#include "net/base/net_errors.h" |
+#include "net/base/net_util.h" |
+#include "remoting/base/logging.h" |
+ |
+namespace { |
+ |
+const int kLocalGnubbydPort = 1817; |
+const char kGnubbydProxyHost[] = "localhost"; |
+const char kLocalGnubbydAddress[] = "127.0.0.1"; |
+ |
+} // namespace |
+ |
+namespace remoting { |
+ |
+GnubbyAdvertiser::GnubbyAdvertiser( |
+ scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, |
Sergey Ulanov
2014/01/25 02:03:33
It looks like you are using network_task_runner ju
psj
2014/01/29 09:07:15
Done.
|
+ net::ClientSocketFactory* client_socket_factory) |
+ : network_task_runner_(network_task_runner), |
+ client_socket_factory_(client_socket_factory), |
+ proxy_port_(0) { |
+ |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ DCHECK(client_socket_factory_); |
+ |
+ in_buffer_ = new net::IOBufferWithSize(64); |
+} |
+ |
+void GnubbyAdvertiser::Advertise(int proxy_port) { |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ proxy_port_ = proxy_port; |
+ |
+ // Increment reference to ensure object isn't deleted before final callback. |
+ AddRef(); |
+ |
+ net::IPAddressNumber gnubbyd_ip; |
+ if (!net::ParseIPLiteralToNumber(kLocalGnubbydAddress, &gnubbyd_ip)) { |
+ Close(net::ERR_FAILED); |
+ } |
+ |
+ net::AddressList addresses(net::IPEndPoint(gnubbyd_ip, kLocalGnubbydPort)); |
+ net::NetLog::Source source; |
+ |
+ socket_ = client_socket_factory_->CreateTransportClientSocket( |
+ addresses, NULL, source); |
+ int result = socket_->Connect( |
+ base::Bind(&GnubbyAdvertiser::OnConnect, base::Unretained(this))); |
+ if (result != net::ERR_IO_PENDING) { |
+ OnConnect(result); |
+ } |
+} |
+ |
+GnubbyAdvertiser::~GnubbyAdvertiser() {} |
+ |
+void GnubbyAdvertiser::Close(int result) { |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ |
+ socket_->Disconnect(); |
+ // All done. Decrement reference to balance the increment in Advertise. |
+ Release(); |
+} |
+ |
+void GnubbyAdvertiser::OnConnect(int result) { |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ |
+ if (result == net::OK) { |
+ Write(); |
+ } else { |
+ HOST_LOG << "Failed to connect to gnubbyd: " << result; |
+ Close(result); |
+ } |
+} |
+ |
+void GnubbyAdvertiser::Write() { |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ |
+ std::string listener = |
+ base::StringPrintf("%s: %d\r\n\r\n", kGnubbydProxyHost, proxy_port_); |
+ HOST_LOG << "Advertising [" << listener << "] with local gnubbyd"; |
+ |
+ scoped_refptr<net::StringIOBuffer> buffer = new net::StringIOBuffer(listener); |
+ int result = socket_->Write( |
+ buffer.get(), |
+ buffer->size(), |
+ base::Bind(&GnubbyAdvertiser::OnWrite, base::Unretained(this))); |
+ if (result != net::ERR_IO_PENDING) { |
+ OnWrite(result); |
+ } |
+} |
+ |
+void GnubbyAdvertiser::OnWrite(int result) { |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ |
+ if (result > 0) { |
+ Read(); |
+ } else { |
+ if (result < 0) { |
+ HOST_LOG << "Failed to write to gnubbyd: " << result; |
+ } |
+ Close(result); |
+ } |
+} |
+ |
+void GnubbyAdvertiser::Read() { |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ |
+ int result = socket_->Read( |
+ in_buffer_.get(), |
+ in_buffer_->size(), |
+ base::Bind(&GnubbyAdvertiser::OnRead, base::Unretained(this))); |
+ if (result != net::ERR_IO_PENDING) { |
+ OnRead(result); |
+ } |
+} |
+ |
+void GnubbyAdvertiser::OnRead(int result) { |
+ DCHECK(network_task_runner_->BelongsToCurrentThread()); |
+ |
+ // The advertiser is done once a reply has been received. |
+ Close(result); |
+} |
+ |
+} // namespace remoting |