| /* | 
 |  *  Copyright 2004 The WebRTC Project Authors. All rights reserved. | 
 |  * | 
 |  *  Use of this source code is governed by a BSD-style license | 
 |  *  that can be found in the LICENSE file in the root of the source | 
 |  *  tree. An additional intellectual property rights grant can be found | 
 |  *  in the file PATENTS.  All contributing project authors may | 
 |  *  be found in the AUTHORS file in the root of the source tree. | 
 |  */ | 
 |  | 
 | #ifndef WEBRTC_BASE_SOCKETADAPTERS_H_ | 
 | #define WEBRTC_BASE_SOCKETADAPTERS_H_ | 
 |  | 
 | #include <map> | 
 | #include <string> | 
 |  | 
 | #include "webrtc/base/asyncsocket.h" | 
 | #include "webrtc/base/cryptstring.h" | 
 | #include "webrtc/base/logging.h" | 
 |  | 
 | namespace rtc { | 
 |  | 
 | struct HttpAuthContext; | 
 | class ByteBuffer; | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | // Implements a socket adapter that can buffer and process data internally, | 
 | // as in the case of connecting to a proxy, where you must speak the proxy | 
 | // protocol before commencing normal socket behavior. | 
 | class BufferedReadAdapter : public AsyncSocketAdapter { | 
 |  public: | 
 |   BufferedReadAdapter(AsyncSocket* socket, size_t buffer_size); | 
 |   virtual ~BufferedReadAdapter(); | 
 |  | 
 |   virtual int Send(const void* pv, size_t cb); | 
 |   virtual int Recv(void* pv, size_t cb); | 
 |  | 
 |  protected: | 
 |   int DirectSend(const void* pv, size_t cb) { | 
 |     return AsyncSocketAdapter::Send(pv, cb); | 
 |   } | 
 |  | 
 |   void BufferInput(bool on = true); | 
 |   virtual void ProcessInput(char* data, size_t* len) = 0; | 
 |  | 
 |   virtual void OnReadEvent(AsyncSocket * socket); | 
 |  | 
 |  private: | 
 |   char * buffer_; | 
 |   size_t buffer_size_, data_len_; | 
 |   bool buffering_; | 
 |   DISALLOW_EVIL_CONSTRUCTORS(BufferedReadAdapter); | 
 | }; | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | // Interface for implementing proxy server sockets. | 
 | class AsyncProxyServerSocket : public BufferedReadAdapter { | 
 |  public: | 
 |   AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size) | 
 |       : BufferedReadAdapter(socket, buffer_size) {} | 
 |   sigslot::signal2<AsyncProxyServerSocket*, | 
 |                    const SocketAddress&>  SignalConnectRequest; | 
 |   virtual void SendConnectResult(int err, const SocketAddress& addr) = 0; | 
 | }; | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | // Implements a socket adapter that performs the client side of a | 
 | // fake SSL handshake. Used for "ssltcp" P2P functionality. | 
 | class AsyncSSLSocket : public BufferedReadAdapter { | 
 |  public: | 
 |   explicit AsyncSSLSocket(AsyncSocket* socket); | 
 |  | 
 |   virtual int Connect(const SocketAddress& addr); | 
 |  | 
 |  protected: | 
 |   virtual void OnConnectEvent(AsyncSocket* socket); | 
 |   virtual void ProcessInput(char* data, size_t* len); | 
 |   DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLSocket); | 
 | }; | 
 |  | 
 | // Implements a socket adapter that performs the server side of a | 
 | // fake SSL handshake. Used when implementing a relay server that does "ssltcp". | 
 | class AsyncSSLServerSocket : public BufferedReadAdapter { | 
 |  public: | 
 |   explicit AsyncSSLServerSocket(AsyncSocket* socket); | 
 |  | 
 |  protected: | 
 |   virtual void ProcessInput(char* data, size_t* len); | 
 |   DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLServerSocket); | 
 | }; | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | // Implements a socket adapter that speaks the HTTP/S proxy protocol. | 
 | class AsyncHttpsProxySocket : public BufferedReadAdapter { | 
 |  public: | 
 |   AsyncHttpsProxySocket(AsyncSocket* socket, const std::string& user_agent, | 
 |     const SocketAddress& proxy, | 
 |     const std::string& username, const CryptString& password); | 
 |   virtual ~AsyncHttpsProxySocket(); | 
 |  | 
 |   // If connect is forced, the adapter will always issue an HTTP CONNECT to the | 
 |   // target address.  Otherwise, it will connect only if the destination port | 
 |   // is not port 80. | 
 |   void SetForceConnect(bool force) { force_connect_ = force; } | 
 |  | 
 |   virtual int Connect(const SocketAddress& addr); | 
 |   virtual SocketAddress GetRemoteAddress() const; | 
 |   virtual int Close(); | 
 |   virtual ConnState GetState() const; | 
 |  | 
 |  protected: | 
 |   virtual void OnConnectEvent(AsyncSocket* socket); | 
 |   virtual void OnCloseEvent(AsyncSocket* socket, int err); | 
 |   virtual void ProcessInput(char* data, size_t* len); | 
 |  | 
 |   bool ShouldIssueConnect() const; | 
 |   void SendRequest(); | 
 |   void ProcessLine(char* data, size_t len); | 
 |   void EndResponse(); | 
 |   void Error(int error); | 
 |  | 
 |  private: | 
 |   SocketAddress proxy_, dest_; | 
 |   std::string agent_, user_, headers_; | 
 |   CryptString pass_; | 
 |   bool force_connect_; | 
 |   size_t content_length_; | 
 |   int defer_error_; | 
 |   bool expect_close_; | 
 |   enum ProxyState { | 
 |     PS_INIT, PS_LEADER, PS_AUTHENTICATE, PS_SKIP_HEADERS, PS_ERROR_HEADERS, | 
 |     PS_TUNNEL_HEADERS, PS_SKIP_BODY, PS_TUNNEL, PS_WAIT_CLOSE, PS_ERROR | 
 |   } state_; | 
 |   HttpAuthContext * context_; | 
 |   std::string unknown_mechanisms_; | 
 |   DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxySocket); | 
 | }; | 
 |  | 
 | /* TODO: Implement this. | 
 | class AsyncHttpsProxyServerSocket : public AsyncProxyServerSocket { | 
 |  public: | 
 |   explicit AsyncHttpsProxyServerSocket(AsyncSocket* socket); | 
 |  | 
 |  private: | 
 |   virtual void ProcessInput(char * data, size_t& len); | 
 |   void Error(int error); | 
 |   DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxyServerSocket); | 
 | }; | 
 | */ | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | // Implements a socket adapter that speaks the SOCKS proxy protocol. | 
 | class AsyncSocksProxySocket : public BufferedReadAdapter { | 
 |  public: | 
 |   AsyncSocksProxySocket(AsyncSocket* socket, const SocketAddress& proxy, | 
 |     const std::string& username, const CryptString& password); | 
 |  | 
 |   virtual int Connect(const SocketAddress& addr); | 
 |   virtual SocketAddress GetRemoteAddress() const; | 
 |   virtual int Close(); | 
 |   virtual ConnState GetState() const; | 
 |  | 
 |  protected: | 
 |   virtual void OnConnectEvent(AsyncSocket* socket); | 
 |   virtual void ProcessInput(char* data, size_t* len); | 
 |  | 
 |   void SendHello(); | 
 |   void SendConnect(); | 
 |   void SendAuth(); | 
 |   void Error(int error); | 
 |  | 
 |  private: | 
 |   enum State { | 
 |     SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR | 
 |   }; | 
 |   State state_; | 
 |   SocketAddress proxy_, dest_; | 
 |   std::string user_; | 
 |   CryptString pass_; | 
 |   DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxySocket); | 
 | }; | 
 |  | 
 | // Implements a proxy server socket for the SOCKS protocol. | 
 | class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket { | 
 |  public: | 
 |   explicit AsyncSocksProxyServerSocket(AsyncSocket* socket); | 
 |  | 
 |  private: | 
 |   virtual void ProcessInput(char* data, size_t* len); | 
 |   void DirectSend(const ByteBuffer& buf); | 
 |  | 
 |   void HandleHello(ByteBuffer* request); | 
 |   void SendHelloReply(int method); | 
 |   void HandleAuth(ByteBuffer* request); | 
 |   void SendAuthReply(int result); | 
 |   void HandleConnect(ByteBuffer* request); | 
 |   virtual void SendConnectResult(int result, const SocketAddress& addr); | 
 |  | 
 |   void Error(int error); | 
 |  | 
 |   static const int kBufferSize = 1024; | 
 |   enum State { | 
 |     SS_HELLO, SS_AUTH, SS_CONNECT, SS_CONNECT_PENDING, SS_TUNNEL, SS_ERROR | 
 |   }; | 
 |   State state_; | 
 |   DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxyServerSocket); | 
 | }; | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | // Implements a socket adapter that logs everything that it sends and receives. | 
 | class LoggingSocketAdapter : public AsyncSocketAdapter { | 
 |  public: | 
 |   LoggingSocketAdapter(AsyncSocket* socket, LoggingSeverity level, | 
 |                  const char * label, bool hex_mode = false); | 
 |  | 
 |   virtual int Send(const void *pv, size_t cb); | 
 |   virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr); | 
 |   virtual int Recv(void *pv, size_t cb); | 
 |   virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr); | 
 |   virtual int Close(); | 
 |  | 
 |  protected: | 
 |   virtual void OnConnectEvent(AsyncSocket * socket); | 
 |   virtual void OnCloseEvent(AsyncSocket * socket, int err); | 
 |  | 
 |  private: | 
 |   LoggingSeverity level_; | 
 |   std::string label_; | 
 |   bool hex_mode_; | 
 |   LogMultilineState lms_; | 
 |   DISALLOW_EVIL_CONSTRUCTORS(LoggingSocketAdapter); | 
 | }; | 
 |  | 
 | /////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | }  // namespace rtc | 
 |  | 
 | #endif  // WEBRTC_BASE_SOCKETADAPTERS_H_ |