Chromium Code Reviews| 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 |