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