1/* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#ifndef TALK_BASE_SOCKETADAPTERS_H_ 29#define TALK_BASE_SOCKETADAPTERS_H_ 30 31#include <map> 32#include <string> 33 34#include "talk/base/asyncsocket.h" 35#include "talk/base/cryptstring.h" 36#include "talk/base/logging.h" 37 38namespace talk_base { 39 40struct HttpAuthContext; 41class ByteBuffer; 42 43/////////////////////////////////////////////////////////////////////////////// 44 45// Implements a socket adapter that can buffer and process data internally, 46// as in the case of connecting to a proxy, where you must speak the proxy 47// protocol before commencing normal socket behavior. 48class BufferedReadAdapter : public AsyncSocketAdapter { 49 public: 50 BufferedReadAdapter(AsyncSocket* socket, size_t buffer_size); 51 virtual ~BufferedReadAdapter(); 52 53 virtual int Send(const void* pv, size_t cb); 54 virtual int Recv(void* pv, size_t cb); 55 56 protected: 57 int DirectSend(const void* pv, size_t cb) { 58 return AsyncSocketAdapter::Send(pv, cb); 59 } 60 61 void BufferInput(bool on = true); 62 virtual void ProcessInput(char* data, size_t* len) = 0; 63 64 virtual void OnReadEvent(AsyncSocket * socket); 65 66 private: 67 char * buffer_; 68 size_t buffer_size_, data_len_; 69 bool buffering_; 70 DISALLOW_EVIL_CONSTRUCTORS(BufferedReadAdapter); 71}; 72 73/////////////////////////////////////////////////////////////////////////////// 74 75// Interface for implementing proxy server sockets. 76class AsyncProxyServerSocket : public BufferedReadAdapter { 77 public: 78 AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size) 79 : BufferedReadAdapter(socket, buffer_size) {} 80 sigslot::signal2<AsyncProxyServerSocket*, 81 const SocketAddress&> SignalConnectRequest; 82 virtual void SendConnectResult(int err, const SocketAddress& addr) = 0; 83}; 84 85/////////////////////////////////////////////////////////////////////////////// 86 87// Implements a socket adapter that performs the client side of a 88// fake SSL handshake. Used for "ssltcp" P2P functionality. 89class AsyncSSLSocket : public BufferedReadAdapter { 90 public: 91 explicit AsyncSSLSocket(AsyncSocket* socket); 92 93 virtual int Connect(const SocketAddress& addr); 94 95 protected: 96 virtual void OnConnectEvent(AsyncSocket* socket); 97 virtual void ProcessInput(char* data, size_t* len); 98 DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLSocket); 99}; 100 101// Implements a socket adapter that performs the server side of a 102// fake SSL handshake. Used when implementing a relay server that does "ssltcp". 103class AsyncSSLServerSocket : public BufferedReadAdapter { 104 public: 105 explicit AsyncSSLServerSocket(AsyncSocket* socket); 106 107 protected: 108 virtual void ProcessInput(char* data, size_t* len); 109 DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLServerSocket); 110}; 111 112/////////////////////////////////////////////////////////////////////////////// 113 114// Implements a socket adapter that speaks the HTTP/S proxy protocol. 115class AsyncHttpsProxySocket : public BufferedReadAdapter { 116 public: 117 AsyncHttpsProxySocket(AsyncSocket* socket, const std::string& user_agent, 118 const SocketAddress& proxy, 119 const std::string& username, const CryptString& password); 120 virtual ~AsyncHttpsProxySocket(); 121 122 // If connect is forced, the adapter will always issue an HTTP CONNECT to the 123 // target address. Otherwise, it will connect only if the destination port 124 // is not port 80. 125 void SetForceConnect(bool force) { force_connect_ = force; } 126 127 virtual int Connect(const SocketAddress& addr); 128 virtual SocketAddress GetRemoteAddress() const; 129 virtual int Close(); 130 virtual ConnState GetState() const; 131 132 protected: 133 virtual void OnConnectEvent(AsyncSocket* socket); 134 virtual void OnCloseEvent(AsyncSocket* socket, int err); 135 virtual void ProcessInput(char* data, size_t* len); 136 137 bool ShouldIssueConnect() const; 138 void SendRequest(); 139 void ProcessLine(char* data, size_t len); 140 void EndResponse(); 141 void Error(int error); 142 143 private: 144 SocketAddress proxy_, dest_; 145 std::string agent_, user_, headers_; 146 CryptString pass_; 147 bool force_connect_; 148 size_t content_length_; 149 int defer_error_; 150 bool expect_close_; 151 enum ProxyState { 152 PS_INIT, PS_LEADER, PS_AUTHENTICATE, PS_SKIP_HEADERS, PS_ERROR_HEADERS, 153 PS_TUNNEL_HEADERS, PS_SKIP_BODY, PS_TUNNEL, PS_WAIT_CLOSE, PS_ERROR 154 } state_; 155 HttpAuthContext * context_; 156 std::string unknown_mechanisms_; 157 DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxySocket); 158}; 159 160/* TODO: Implement this. 161class AsyncHttpsProxyServerSocket : public AsyncProxyServerSocket { 162 public: 163 explicit AsyncHttpsProxyServerSocket(AsyncSocket* socket); 164 165 private: 166 virtual void ProcessInput(char * data, size_t& len); 167 void Error(int error); 168 DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxyServerSocket); 169}; 170*/ 171 172/////////////////////////////////////////////////////////////////////////////// 173 174// Implements a socket adapter that speaks the SOCKS proxy protocol. 175class AsyncSocksProxySocket : public BufferedReadAdapter { 176 public: 177 AsyncSocksProxySocket(AsyncSocket* socket, const SocketAddress& proxy, 178 const std::string& username, const CryptString& password); 179 180 virtual int Connect(const SocketAddress& addr); 181 virtual SocketAddress GetRemoteAddress() const; 182 virtual int Close(); 183 virtual ConnState GetState() const; 184 185 protected: 186 virtual void OnConnectEvent(AsyncSocket* socket); 187 virtual void ProcessInput(char* data, size_t* len); 188 189 void SendHello(); 190 void SendConnect(); 191 void SendAuth(); 192 void Error(int error); 193 194 private: 195 enum State { 196 SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR 197 }; 198 State state_; 199 SocketAddress proxy_, dest_; 200 std::string user_; 201 CryptString pass_; 202 DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxySocket); 203}; 204 205// Implements a proxy server socket for the SOCKS protocol. 206class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket { 207 public: 208 explicit AsyncSocksProxyServerSocket(AsyncSocket* socket); 209 210 private: 211 virtual void ProcessInput(char* data, size_t* len); 212 void DirectSend(const ByteBuffer& buf); 213 214 void HandleHello(ByteBuffer* request); 215 void SendHelloReply(int method); 216 void HandleAuth(ByteBuffer* request); 217 void SendAuthReply(int result); 218 void HandleConnect(ByteBuffer* request); 219 virtual void SendConnectResult(int result, const SocketAddress& addr); 220 221 void Error(int error); 222 223 static const int kBufferSize = 1024; 224 enum State { 225 SS_HELLO, SS_AUTH, SS_CONNECT, SS_CONNECT_PENDING, SS_TUNNEL, SS_ERROR 226 }; 227 State state_; 228 DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxyServerSocket); 229}; 230 231/////////////////////////////////////////////////////////////////////////////// 232 233// Implements a socket adapter that logs everything that it sends and receives. 234class LoggingSocketAdapter : public AsyncSocketAdapter { 235 public: 236 LoggingSocketAdapter(AsyncSocket* socket, LoggingSeverity level, 237 const char * label, bool hex_mode = false); 238 239 virtual int Send(const void *pv, size_t cb); 240 virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr); 241 virtual int Recv(void *pv, size_t cb); 242 virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr); 243 virtual int Close(); 244 245 protected: 246 virtual void OnConnectEvent(AsyncSocket * socket); 247 virtual void OnCloseEvent(AsyncSocket * socket, int err); 248 249 private: 250 LoggingSeverity level_; 251 std::string label_; 252 bool hex_mode_; 253 LogMultilineState lms_; 254 DISALLOW_EVIL_CONSTRUCTORS(LoggingSocketAdapter); 255}; 256 257/////////////////////////////////////////////////////////////////////////////// 258 259} // namespace talk_base 260 261#endif // TALK_BASE_SOCKETADAPTERS_H_ 262