blob: ad88fe6b6fb8cf2003beef81539c3e222382d10f [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef RTC_BASE_SOCKETADAPTERS_H_
12#define RTC_BASE_SOCKETADAPTERS_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020014#include <map>
15#include <string>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "rtc_base/asyncsocket.h"
18#include "rtc_base/constructormagic.h"
19#include "rtc_base/cryptstring.h"
20#include "rtc_base/logging.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020021
22namespace rtc {
23
24struct HttpAuthContext;
25class ByteBufferReader;
26class ByteBufferWriter;
27
28///////////////////////////////////////////////////////////////////////////////
29
30// Implements a socket adapter that can buffer and process data internally,
31// as in the case of connecting to a proxy, where you must speak the proxy
32// protocol before commencing normal socket behavior.
33class BufferedReadAdapter : public AsyncSocketAdapter {
34 public:
35 BufferedReadAdapter(AsyncSocket* socket, size_t buffer_size);
36 ~BufferedReadAdapter() override;
37
38 int Send(const void* pv, size_t cb) override;
39 int Recv(void* pv, size_t cb, int64_t* timestamp) override;
40
41 protected:
42 int DirectSend(const void* pv, size_t cb) {
43 return AsyncSocketAdapter::Send(pv, cb);
44 }
45
46 void BufferInput(bool on = true);
47 virtual void ProcessInput(char* data, size_t* len) = 0;
48
49 void OnReadEvent(AsyncSocket* socket) override;
50
51 private:
Yves Gerey665174f2018-06-19 15:03:05 +020052 char* buffer_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020053 size_t buffer_size_, data_len_;
54 bool buffering_;
55 RTC_DISALLOW_COPY_AND_ASSIGN(BufferedReadAdapter);
56};
57
58///////////////////////////////////////////////////////////////////////////////
59
60// Interface for implementing proxy server sockets.
61class AsyncProxyServerSocket : public BufferedReadAdapter {
62 public:
63 AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size);
64 ~AsyncProxyServerSocket() override;
Yves Gerey665174f2018-06-19 15:03:05 +020065 sigslot::signal2<AsyncProxyServerSocket*, const SocketAddress&>
66 SignalConnectRequest;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020067 virtual void SendConnectResult(int err, const SocketAddress& addr) = 0;
68};
69
70///////////////////////////////////////////////////////////////////////////////
71
72// Implements a socket adapter that performs the client side of a
73// fake SSL handshake. Used for "ssltcp" P2P functionality.
74class AsyncSSLSocket : public BufferedReadAdapter {
75 public:
76 explicit AsyncSSLSocket(AsyncSocket* socket);
77
78 int Connect(const SocketAddress& addr) override;
79
80 protected:
81 void OnConnectEvent(AsyncSocket* socket) override;
82 void ProcessInput(char* data, size_t* len) override;
83 RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSSLSocket);
84};
85
86// Implements a socket adapter that performs the server side of a
87// fake SSL handshake. Used when implementing a relay server that does "ssltcp".
88class AsyncSSLServerSocket : public BufferedReadAdapter {
89 public:
90 explicit AsyncSSLServerSocket(AsyncSocket* socket);
91
92 protected:
93 void ProcessInput(char* data, size_t* len) override;
94 RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSSLServerSocket);
95};
96
97///////////////////////////////////////////////////////////////////////////////
98
99// Implements a socket adapter that speaks the HTTP/S proxy protocol.
100class AsyncHttpsProxySocket : public BufferedReadAdapter {
101 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200102 AsyncHttpsProxySocket(AsyncSocket* socket,
103 const std::string& user_agent,
104 const SocketAddress& proxy,
105 const std::string& username,
106 const CryptString& password);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200107 ~AsyncHttpsProxySocket() override;
108
109 // If connect is forced, the adapter will always issue an HTTP CONNECT to the
110 // target address. Otherwise, it will connect only if the destination port
111 // is not port 80.
112 void SetForceConnect(bool force) { force_connect_ = force; }
113
114 int Connect(const SocketAddress& addr) override;
115 SocketAddress GetRemoteAddress() const override;
116 int Close() override;
117 ConnState GetState() const override;
118
119 protected:
120 void OnConnectEvent(AsyncSocket* socket) override;
121 void OnCloseEvent(AsyncSocket* socket, int err) override;
122 void ProcessInput(char* data, size_t* len) override;
123
124 bool ShouldIssueConnect() const;
125 void SendRequest();
126 void ProcessLine(char* data, size_t len);
127 void EndResponse();
128 void Error(int error);
129
130 private:
131 SocketAddress proxy_, dest_;
132 std::string agent_, user_, headers_;
133 CryptString pass_;
134 bool force_connect_;
135 size_t content_length_;
136 int defer_error_;
137 bool expect_close_;
138 enum ProxyState {
Yves Gerey665174f2018-06-19 15:03:05 +0200139 PS_INIT,
140 PS_LEADER,
141 PS_AUTHENTICATE,
142 PS_SKIP_HEADERS,
143 PS_ERROR_HEADERS,
144 PS_TUNNEL_HEADERS,
145 PS_SKIP_BODY,
146 PS_TUNNEL,
147 PS_WAIT_CLOSE,
148 PS_ERROR
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200149 } state_;
Yves Gerey665174f2018-06-19 15:03:05 +0200150 HttpAuthContext* context_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200151 std::string unknown_mechanisms_;
152 RTC_DISALLOW_COPY_AND_ASSIGN(AsyncHttpsProxySocket);
153};
154
155///////////////////////////////////////////////////////////////////////////////
156
157// Implements a socket adapter that speaks the SOCKS proxy protocol.
158class AsyncSocksProxySocket : public BufferedReadAdapter {
159 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200160 AsyncSocksProxySocket(AsyncSocket* socket,
161 const SocketAddress& proxy,
162 const std::string& username,
163 const CryptString& password);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200164 ~AsyncSocksProxySocket() override;
165
166 int Connect(const SocketAddress& addr) override;
167 SocketAddress GetRemoteAddress() const override;
168 int Close() override;
169 ConnState GetState() const override;
170
171 protected:
172 void OnConnectEvent(AsyncSocket* socket) override;
173 void ProcessInput(char* data, size_t* len) override;
174
175 void SendHello();
176 void SendConnect();
177 void SendAuth();
178 void Error(int error);
179
180 private:
Yves Gerey665174f2018-06-19 15:03:05 +0200181 enum State { SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR };
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200182 State state_;
183 SocketAddress proxy_, dest_;
184 std::string user_;
185 CryptString pass_;
186 RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSocksProxySocket);
187};
188
189// Implements a proxy server socket for the SOCKS protocol.
190class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket {
191 public:
192 explicit AsyncSocksProxyServerSocket(AsyncSocket* socket);
193
194 private:
195 void ProcessInput(char* data, size_t* len) override;
196 void DirectSend(const ByteBufferWriter& buf);
197
198 void HandleHello(ByteBufferReader* request);
199 void SendHelloReply(uint8_t method);
200 void HandleAuth(ByteBufferReader* request);
201 void SendAuthReply(uint8_t result);
202 void HandleConnect(ByteBufferReader* request);
203 void SendConnectResult(int result, const SocketAddress& addr) override;
204
205 void Error(int error);
206
207 static const int kBufferSize = 1024;
208 enum State {
Yves Gerey665174f2018-06-19 15:03:05 +0200209 SS_HELLO,
210 SS_AUTH,
211 SS_CONNECT,
212 SS_CONNECT_PENDING,
213 SS_TUNNEL,
214 SS_ERROR
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200215 };
216 State state_;
217 RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSocksProxyServerSocket);
218};
219
220} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000221
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200222#endif // RTC_BASE_SOCKETADAPTERS_H_