OLD | NEW |
| (Empty) |
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 "webrtc/base/proxyserver.h" | |
12 | |
13 #include <algorithm> | |
14 | |
15 #include "webrtc/base/checks.h" | |
16 #include "webrtc/base/socketfactory.h" | |
17 | |
18 namespace rtc { | |
19 | |
20 // ProxyServer | |
21 ProxyServer::ProxyServer( | |
22 SocketFactory* int_factory, const SocketAddress& int_addr, | |
23 SocketFactory* ext_factory, const SocketAddress& ext_ip) | |
24 : ext_factory_(ext_factory), ext_ip_(ext_ip.ipaddr(), 0), // strip off port | |
25 server_socket_(int_factory->CreateAsyncSocket(int_addr.family(), | |
26 SOCK_STREAM)) { | |
27 RTC_DCHECK(server_socket_.get() != nullptr); | |
28 RTC_DCHECK(int_addr.family() == AF_INET || int_addr.family() == AF_INET6); | |
29 server_socket_->Bind(int_addr); | |
30 server_socket_->Listen(5); | |
31 server_socket_->SignalReadEvent.connect(this, &ProxyServer::OnAcceptEvent); | |
32 } | |
33 | |
34 ProxyServer::~ProxyServer() { | |
35 for (BindingList::iterator it = bindings_.begin(); | |
36 it != bindings_.end(); ++it) { | |
37 delete (*it); | |
38 } | |
39 } | |
40 | |
41 SocketAddress ProxyServer::GetServerAddress() { | |
42 return server_socket_->GetLocalAddress(); | |
43 } | |
44 | |
45 void ProxyServer::OnAcceptEvent(AsyncSocket* socket) { | |
46 RTC_DCHECK(socket != nullptr && socket == server_socket_.get()); | |
47 AsyncSocket* int_socket = socket->Accept(nullptr); | |
48 AsyncProxyServerSocket* wrapped_socket = WrapSocket(int_socket); | |
49 AsyncSocket* ext_socket = ext_factory_->CreateAsyncSocket(ext_ip_.family(), | |
50 SOCK_STREAM); | |
51 if (ext_socket) { | |
52 ext_socket->Bind(ext_ip_); | |
53 bindings_.push_back(new ProxyBinding(wrapped_socket, ext_socket)); | |
54 } else { | |
55 LOG(LS_ERROR) << "Unable to create external socket on proxy accept event"; | |
56 } | |
57 } | |
58 | |
59 void ProxyServer::OnBindingDestroyed(ProxyBinding* binding) { | |
60 BindingList::iterator it = | |
61 std::find(bindings_.begin(), bindings_.end(), binding); | |
62 delete (*it); | |
63 bindings_.erase(it); | |
64 } | |
65 | |
66 // ProxyBinding | |
67 ProxyBinding::ProxyBinding(AsyncProxyServerSocket* int_socket, | |
68 AsyncSocket* ext_socket) | |
69 : int_socket_(int_socket), ext_socket_(ext_socket), connected_(false), | |
70 out_buffer_(kBufferSize), in_buffer_(kBufferSize) { | |
71 int_socket_->SignalConnectRequest.connect(this, | |
72 &ProxyBinding::OnConnectRequest); | |
73 int_socket_->SignalReadEvent.connect(this, &ProxyBinding::OnInternalRead); | |
74 int_socket_->SignalWriteEvent.connect(this, &ProxyBinding::OnInternalWrite); | |
75 int_socket_->SignalCloseEvent.connect(this, &ProxyBinding::OnInternalClose); | |
76 ext_socket_->SignalConnectEvent.connect(this, | |
77 &ProxyBinding::OnExternalConnect); | |
78 ext_socket_->SignalReadEvent.connect(this, &ProxyBinding::OnExternalRead); | |
79 ext_socket_->SignalWriteEvent.connect(this, &ProxyBinding::OnExternalWrite); | |
80 ext_socket_->SignalCloseEvent.connect(this, &ProxyBinding::OnExternalClose); | |
81 } | |
82 | |
83 ProxyBinding::~ProxyBinding() = default; | |
84 | |
85 void ProxyBinding::OnConnectRequest(AsyncProxyServerSocket* socket, | |
86 const SocketAddress& addr) { | |
87 RTC_DCHECK(!connected_ && ext_socket_.get() != nullptr); | |
88 ext_socket_->Connect(addr); | |
89 // TODO: handle errors here | |
90 } | |
91 | |
92 void ProxyBinding::OnInternalRead(AsyncSocket* socket) { | |
93 Read(int_socket_.get(), &out_buffer_); | |
94 Write(ext_socket_.get(), &out_buffer_); | |
95 } | |
96 | |
97 void ProxyBinding::OnInternalWrite(AsyncSocket* socket) { | |
98 Write(int_socket_.get(), &in_buffer_); | |
99 } | |
100 | |
101 void ProxyBinding::OnInternalClose(AsyncSocket* socket, int err) { | |
102 Destroy(); | |
103 } | |
104 | |
105 void ProxyBinding::OnExternalConnect(AsyncSocket* socket) { | |
106 RTC_DCHECK(socket != nullptr); | |
107 connected_ = true; | |
108 int_socket_->SendConnectResult(0, socket->GetRemoteAddress()); | |
109 } | |
110 | |
111 void ProxyBinding::OnExternalRead(AsyncSocket* socket) { | |
112 Read(ext_socket_.get(), &in_buffer_); | |
113 Write(int_socket_.get(), &in_buffer_); | |
114 } | |
115 | |
116 void ProxyBinding::OnExternalWrite(AsyncSocket* socket) { | |
117 Write(ext_socket_.get(), &out_buffer_); | |
118 } | |
119 | |
120 void ProxyBinding::OnExternalClose(AsyncSocket* socket, int err) { | |
121 if (!connected_) { | |
122 int_socket_->SendConnectResult(err, SocketAddress()); | |
123 } | |
124 Destroy(); | |
125 } | |
126 | |
127 void ProxyBinding::Read(AsyncSocket* socket, FifoBuffer* buffer) { | |
128 // Only read if the buffer is empty. | |
129 RTC_DCHECK(socket != nullptr); | |
130 size_t size; | |
131 int read; | |
132 if (buffer->GetBuffered(&size) && size == 0) { | |
133 void* p = buffer->GetWriteBuffer(&size); | |
134 read = socket->Recv(p, size, nullptr); | |
135 buffer->ConsumeWriteBuffer(std::max(read, 0)); | |
136 } | |
137 } | |
138 | |
139 void ProxyBinding::Write(AsyncSocket* socket, FifoBuffer* buffer) { | |
140 RTC_DCHECK(socket != nullptr); | |
141 size_t size; | |
142 int written; | |
143 const void* p = buffer->GetReadData(&size); | |
144 written = socket->Send(p, size); | |
145 buffer->ConsumeReadData(std::max(written, 0)); | |
146 } | |
147 | |
148 void ProxyBinding::Destroy() { | |
149 SignalDestroyed(this); | |
150 } | |
151 | |
152 AsyncProxyServerSocket* SocksProxyServer::WrapSocket(AsyncSocket* socket) { | |
153 return new AsyncSocksProxyServerSocket(socket); | |
154 } | |
155 | |
156 } // namespace rtc | |
OLD | NEW |