• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "rtc_base/proxy_server.h"
12 
13 #include <stddef.h>
14 
15 #include <memory>
16 #include "rtc_base/checks.h"
17 #include "rtc_base/logging.h"
18 #include "rtc_base/socket_factory.h"
19 
20 namespace rtc {
21 
22 // ProxyServer
ProxyServer(SocketFactory * int_factory,const SocketAddress & int_addr,SocketFactory * ext_factory,const SocketAddress & ext_ip)23 ProxyServer::ProxyServer(SocketFactory* int_factory,
24                          const SocketAddress& int_addr,
25                          SocketFactory* ext_factory,
26                          const SocketAddress& ext_ip)
27     : ext_factory_(ext_factory),
28       ext_ip_(ext_ip.ipaddr(), 0),  // strip off port
29       server_socket_(
30           int_factory->CreateAsyncSocket(int_addr.family(), SOCK_STREAM)) {
31   RTC_DCHECK(server_socket_.get() != nullptr);
32   RTC_DCHECK(int_addr.family() == AF_INET || int_addr.family() == AF_INET6);
33   server_socket_->Bind(int_addr);
34   server_socket_->Listen(5);
35   server_socket_->SignalReadEvent.connect(this, &ProxyServer::OnAcceptEvent);
36 }
37 
38 ProxyServer::~ProxyServer() = default;
39 
GetServerAddress()40 SocketAddress ProxyServer::GetServerAddress() {
41   return server_socket_->GetLocalAddress();
42 }
43 
OnAcceptEvent(AsyncSocket * socket)44 void ProxyServer::OnAcceptEvent(AsyncSocket* socket) {
45   RTC_DCHECK(socket);
46   RTC_DCHECK_EQ(socket, server_socket_.get());
47   AsyncSocket* int_socket = socket->Accept(nullptr);
48   AsyncProxyServerSocket* wrapped_socket = WrapSocket(int_socket);
49   AsyncSocket* ext_socket =
50       ext_factory_->CreateAsyncSocket(ext_ip_.family(), SOCK_STREAM);
51   if (ext_socket) {
52     ext_socket->Bind(ext_ip_);
53     bindings_.emplace_back(
54         std::make_unique<ProxyBinding>(wrapped_socket, ext_socket));
55   } else {
56     RTC_LOG(LS_ERROR)
57         << "Unable to create external socket on proxy accept event";
58   }
59 }
60 
61 // ProxyBinding
ProxyBinding(AsyncProxyServerSocket * int_socket,AsyncSocket * ext_socket)62 ProxyBinding::ProxyBinding(AsyncProxyServerSocket* int_socket,
63                            AsyncSocket* ext_socket)
64     : int_socket_(int_socket),
65       ext_socket_(ext_socket),
66       connected_(false),
67       out_buffer_(kBufferSize),
68       in_buffer_(kBufferSize) {
69   int_socket_->SignalConnectRequest.connect(this,
70                                             &ProxyBinding::OnConnectRequest);
71   int_socket_->SignalReadEvent.connect(this, &ProxyBinding::OnInternalRead);
72   int_socket_->SignalWriteEvent.connect(this, &ProxyBinding::OnInternalWrite);
73   int_socket_->SignalCloseEvent.connect(this, &ProxyBinding::OnInternalClose);
74   ext_socket_->SignalConnectEvent.connect(this,
75                                           &ProxyBinding::OnExternalConnect);
76   ext_socket_->SignalReadEvent.connect(this, &ProxyBinding::OnExternalRead);
77   ext_socket_->SignalWriteEvent.connect(this, &ProxyBinding::OnExternalWrite);
78   ext_socket_->SignalCloseEvent.connect(this, &ProxyBinding::OnExternalClose);
79 }
80 
81 ProxyBinding::~ProxyBinding() = default;
82 
OnConnectRequest(AsyncProxyServerSocket * socket,const SocketAddress & addr)83 void ProxyBinding::OnConnectRequest(AsyncProxyServerSocket* socket,
84                                     const SocketAddress& addr) {
85   RTC_DCHECK(!connected_);
86   RTC_DCHECK(ext_socket_);
87   ext_socket_->Connect(addr);
88   // TODO: handle errors here
89 }
90 
OnInternalRead(AsyncSocket * socket)91 void ProxyBinding::OnInternalRead(AsyncSocket* socket) {
92   Read(int_socket_.get(), &out_buffer_);
93   Write(ext_socket_.get(), &out_buffer_);
94 }
95 
OnInternalWrite(AsyncSocket * socket)96 void ProxyBinding::OnInternalWrite(AsyncSocket* socket) {
97   Write(int_socket_.get(), &in_buffer_);
98 }
99 
OnInternalClose(AsyncSocket * socket,int err)100 void ProxyBinding::OnInternalClose(AsyncSocket* socket, int err) {
101   Destroy();
102 }
103 
OnExternalConnect(AsyncSocket * socket)104 void ProxyBinding::OnExternalConnect(AsyncSocket* socket) {
105   RTC_DCHECK(socket != nullptr);
106   connected_ = true;
107   int_socket_->SendConnectResult(0, socket->GetRemoteAddress());
108 }
109 
OnExternalRead(AsyncSocket * socket)110 void ProxyBinding::OnExternalRead(AsyncSocket* socket) {
111   Read(ext_socket_.get(), &in_buffer_);
112   Write(int_socket_.get(), &in_buffer_);
113 }
114 
OnExternalWrite(AsyncSocket * socket)115 void ProxyBinding::OnExternalWrite(AsyncSocket* socket) {
116   Write(ext_socket_.get(), &out_buffer_);
117 }
118 
OnExternalClose(AsyncSocket * socket,int err)119 void ProxyBinding::OnExternalClose(AsyncSocket* socket, int err) {
120   if (!connected_) {
121     int_socket_->SendConnectResult(err, SocketAddress());
122   }
123   Destroy();
124 }
125 
Read(AsyncSocket * socket,FifoBuffer * buffer)126 void ProxyBinding::Read(AsyncSocket* socket, FifoBuffer* buffer) {
127   // Only read if the buffer is empty.
128   RTC_DCHECK(socket != nullptr);
129   size_t size;
130   int read;
131   if (buffer->GetBuffered(&size) && size == 0) {
132     void* p = buffer->GetWriteBuffer(&size);
133     read = socket->Recv(p, size, nullptr);
134     buffer->ConsumeWriteBuffer(std::max(read, 0));
135   }
136 }
137 
Write(AsyncSocket * socket,FifoBuffer * buffer)138 void ProxyBinding::Write(AsyncSocket* socket, FifoBuffer* buffer) {
139   RTC_DCHECK(socket != nullptr);
140   size_t size;
141   int written;
142   const void* p = buffer->GetReadData(&size);
143   written = socket->Send(p, size);
144   buffer->ConsumeReadData(std::max(written, 0));
145 }
146 
Destroy()147 void ProxyBinding::Destroy() {
148   SignalDestroyed(this);
149 }
150 
WrapSocket(AsyncSocket * socket)151 AsyncProxyServerSocket* SocksProxyServer::WrapSocket(AsyncSocket* socket) {
152   return new AsyncSocksProxyServerSocket(socket);
153 }
154 
155 }  // namespace rtc
156