Move ServerSocket code to separate files and into test target

Classes AsyncProxyServerSocket, AsyncSSLServerSocket, and
AsyncSSLServerSocket are used only by test and example code.

Moved to server_socket_adapters.{cc,h}, and to the
rtc_base_tests_utils build target.

In the process, also deleted a few ancient and unattributed TODO
comments.

Bug: webrtc:9798
Change-Id: I21279c92bd8f1354fab7eeaf1f9697fedfc760e1
Reviewed-on: https://webrtc-review.googlesource.com/c/107735
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26039}
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index a2aa5ff..7d26947 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -214,6 +214,7 @@
     ":rtc_p2p",
     "../rtc_base:checks",
     "../rtc_base:rtc_base",
+    "../rtc_base:rtc_base_tests_utils",
     "../rtc_base/third_party/sigslot",
     "//third_party/abseil-cpp/absl/memory",
   ]
diff --git a/p2p/base/relayserver.cc b/p2p/base/relayserver.cc
index ad6b487..0f712a9 100644
--- a/p2p/base/relayserver.cc
+++ b/p2p/base/relayserver.cc
@@ -22,7 +22,7 @@
 #include "rtc_base/helpers.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/numerics/safe_conversions.h"
-#include "rtc_base/socketadapters.h"
+#include "rtc_base/server_socket_adapters.h"
 
 namespace cricket {
 
diff --git a/p2p/base/testrelayserver.h b/p2p/base/testrelayserver.h
index 5efffc8..9aca2f6 100644
--- a/p2p/base/testrelayserver.h
+++ b/p2p/base/testrelayserver.h
@@ -15,7 +15,7 @@
 
 #include "p2p/base/relayserver.h"
 #include "rtc_base/asynctcpsocket.h"
-#include "rtc_base/socketadapters.h"
+#include "rtc_base/server_socket_adapters.h"
 #include "rtc_base/third_party/sigslot/sigslot.h"
 #include "rtc_base/thread.h"
 
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 1ee1ed5..d8af370 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -1156,6 +1156,8 @@
     "nattypes.h",
     "proxyserver.cc",
     "proxyserver.h",
+    "server_socket_adapters.cc",
+    "server_socket_adapters.h",
     "sigslottester.h",
     "sigslottester.h.pump",
     "socketstream.cc",
diff --git a/rtc_base/proxyserver.h b/rtc_base/proxyserver.h
index 37cadd0..587a49c 100644
--- a/rtc_base/proxyserver.h
+++ b/rtc_base/proxyserver.h
@@ -15,7 +15,7 @@
 #include <memory>
 #include "rtc_base/asyncsocket.h"
 #include "rtc_base/constructormagic.h"
-#include "rtc_base/socketadapters.h"
+#include "rtc_base/server_socket_adapters.h"
 #include "rtc_base/socketaddress.h"
 #include "rtc_base/stream.h"
 
diff --git a/rtc_base/server_socket_adapters.cc b/rtc_base/server_socket_adapters.cc
new file mode 100644
index 0000000..64f9bf0
--- /dev/null
+++ b/rtc_base/server_socket_adapters.cc
@@ -0,0 +1,185 @@
+/*
+ *  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.
+ */
+
+#include <string>
+
+#include "rtc_base/bytebuffer.h"
+#include "rtc_base/server_socket_adapters.h"
+
+namespace rtc {
+
+AsyncProxyServerSocket::AsyncProxyServerSocket(AsyncSocket* socket,
+                                               size_t buffer_size)
+    : BufferedReadAdapter(socket, buffer_size) {}
+
+AsyncProxyServerSocket::~AsyncProxyServerSocket() = default;
+
+AsyncSSLServerSocket::AsyncSSLServerSocket(AsyncSocket* socket)
+    : BufferedReadAdapter(socket, 1024) {
+  BufferInput(true);
+}
+
+void AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) {
+  // We only accept client hello messages.
+  const ArrayView<const uint8_t> client_hello =
+      AsyncSSLSocket::SslClientHello();
+  if (*len < client_hello.size()) {
+    return;
+  }
+
+  if (memcmp(client_hello.data(), data, client_hello.size()) != 0) {
+    Close();
+    SignalCloseEvent(this, 0);
+    return;
+  }
+
+  *len -= client_hello.size();
+
+  // Clients should not send more data until the handshake is completed.
+  RTC_DCHECK(*len == 0);
+
+  const ArrayView<const uint8_t> server_hello =
+      AsyncSSLSocket::SslServerHello();
+  // Send a server hello back to the client.
+  DirectSend(server_hello.data(), server_hello.size());
+
+  // Handshake completed for us, redirect input to our parent.
+  BufferInput(false);
+}
+
+AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(AsyncSocket* socket)
+    : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) {
+  BufferInput(true);
+}
+
+void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) {
+  RTC_DCHECK(state_ < SS_CONNECT_PENDING);
+
+  ByteBufferReader response(data, *len);
+  if (state_ == SS_HELLO) {
+    HandleHello(&response);
+  } else if (state_ == SS_AUTH) {
+    HandleAuth(&response);
+  } else if (state_ == SS_CONNECT) {
+    HandleConnect(&response);
+  }
+
+  // Consume parsed data
+  *len = response.Length();
+  memmove(data, response.Data(), *len);
+}
+
+void AsyncSocksProxyServerSocket::DirectSend(const ByteBufferWriter& buf) {
+  BufferedReadAdapter::DirectSend(buf.Data(), buf.Length());
+}
+
+void AsyncSocksProxyServerSocket::HandleHello(ByteBufferReader* request) {
+  uint8_t ver, num_methods;
+  if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&num_methods)) {
+    Error(0);
+    return;
+  }
+
+  if (ver != 5) {
+    Error(0);
+    return;
+  }
+
+  // Handle either no-auth (0) or user/pass auth (2)
+  uint8_t method = 0xFF;
+  if (num_methods > 0 && !request->ReadUInt8(&method)) {
+    Error(0);
+    return;
+  }
+
+  SendHelloReply(method);
+  if (method == 0) {
+    state_ = SS_CONNECT;
+  } else if (method == 2) {
+    state_ = SS_AUTH;
+  } else {
+    state_ = SS_ERROR;
+  }
+}
+
+void AsyncSocksProxyServerSocket::SendHelloReply(uint8_t method) {
+  ByteBufferWriter response;
+  response.WriteUInt8(5);       // Socks Version
+  response.WriteUInt8(method);  // Auth method
+  DirectSend(response);
+}
+
+void AsyncSocksProxyServerSocket::HandleAuth(ByteBufferReader* request) {
+  uint8_t ver, user_len, pass_len;
+  std::string user, pass;
+  if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&user_len) ||
+      !request->ReadString(&user, user_len) || !request->ReadUInt8(&pass_len) ||
+      !request->ReadString(&pass, pass_len)) {
+    Error(0);
+    return;
+  }
+
+  SendAuthReply(0);
+  state_ = SS_CONNECT;
+}
+
+void AsyncSocksProxyServerSocket::SendAuthReply(uint8_t result) {
+  ByteBufferWriter response;
+  response.WriteUInt8(1);  // Negotiation Version
+  response.WriteUInt8(result);
+  DirectSend(response);
+}
+
+void AsyncSocksProxyServerSocket::HandleConnect(ByteBufferReader* request) {
+  uint8_t ver, command, reserved, addr_type;
+  uint32_t ip;
+  uint16_t port;
+  if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&command) ||
+      !request->ReadUInt8(&reserved) || !request->ReadUInt8(&addr_type) ||
+      !request->ReadUInt32(&ip) || !request->ReadUInt16(&port)) {
+    Error(0);
+    return;
+  }
+
+  if (ver != 5 || command != 1 || reserved != 0 || addr_type != 1) {
+    Error(0);
+    return;
+  }
+
+  SignalConnectRequest(this, SocketAddress(ip, port));
+  state_ = SS_CONNECT_PENDING;
+}
+
+void AsyncSocksProxyServerSocket::SendConnectResult(int result,
+                                                    const SocketAddress& addr) {
+  if (state_ != SS_CONNECT_PENDING)
+    return;
+
+  ByteBufferWriter response;
+  response.WriteUInt8(5);              // Socks version
+  response.WriteUInt8((result != 0));  // 0x01 is generic error
+  response.WriteUInt8(0);              // reserved
+  response.WriteUInt8(1);              // IPv4 address
+  response.WriteUInt32(addr.ip());
+  response.WriteUInt16(addr.port());
+  DirectSend(response);
+  BufferInput(false);
+  state_ = SS_TUNNEL;
+}
+
+void AsyncSocksProxyServerSocket::Error(int error) {
+  state_ = SS_ERROR;
+  BufferInput(false);
+  Close();
+  SetError(SOCKET_EACCES);
+  SignalCloseEvent(this, error);
+}
+
+}  // namespace rtc
diff --git a/rtc_base/server_socket_adapters.h b/rtc_base/server_socket_adapters.h
new file mode 100644
index 0000000..e741ba8
--- /dev/null
+++ b/rtc_base/server_socket_adapters.h
@@ -0,0 +1,72 @@
+/*
+ *  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 RTC_BASE_SERVER_SOCKET_ADAPTERS_H_
+#define RTC_BASE_SERVER_SOCKET_ADAPTERS_H_
+
+#include "rtc_base/socketadapters.h"
+
+namespace rtc {
+
+// Interface for implementing proxy server sockets.
+class AsyncProxyServerSocket : public BufferedReadAdapter {
+ public:
+  AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size);
+  ~AsyncProxyServerSocket() override;
+  sigslot::signal2<AsyncProxyServerSocket*, const SocketAddress&>
+      SignalConnectRequest;
+  virtual void SendConnectResult(int err, const SocketAddress& addr) = 0;
+};
+
+// 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:
+  void ProcessInput(char* data, size_t* len) override;
+  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSSLServerSocket);
+};
+
+// Implements a proxy server socket for the SOCKS protocol.
+class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket {
+ public:
+  explicit AsyncSocksProxyServerSocket(AsyncSocket* socket);
+
+ private:
+  void ProcessInput(char* data, size_t* len) override;
+  void DirectSend(const ByteBufferWriter& buf);
+
+  void HandleHello(ByteBufferReader* request);
+  void SendHelloReply(uint8_t method);
+  void HandleAuth(ByteBufferReader* request);
+  void SendAuthReply(uint8_t result);
+  void HandleConnect(ByteBufferReader* request);
+  void SendConnectResult(int result, const SocketAddress& addr) override;
+
+  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_;
+  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSocksProxyServerSocket);
+};
+
+}  // namespace rtc
+
+#endif  // RTC_BASE_SERVER_SOCKET_ADAPTERS_H_
diff --git a/rtc_base/socketadapters.cc b/rtc_base/socketadapters.cc
index 3bac17b..9587d8d 100644
--- a/rtc_base/socketadapters.cc
+++ b/rtc_base/socketadapters.cc
@@ -130,12 +130,6 @@
   ProcessInput(buffer_, &data_len_);
 }
 
-AsyncProxyServerSocket::AsyncProxyServerSocket(AsyncSocket* socket,
-                                               size_t buffer_size)
-    : BufferedReadAdapter(socket, buffer_size) {}
-
-AsyncProxyServerSocket::~AsyncProxyServerSocket() = default;
-
 ///////////////////////////////////////////////////////////////////////////////
 
 // This is a SSL v2 CLIENT_HELLO message.
@@ -157,6 +151,13 @@
     0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea         //
 };
 
+// static
+ArrayView<const uint8_t> AsyncSSLSocket::SslClientHello() {
+  // Implicit conversion directly from kSslClientHello to ArrayView fails when
+  // built with gcc.
+  return {kSslClientHello, sizeof(kSslClientHello)};
+}
+
 // This is a TLSv1 SERVER_HELLO message.
 static const uint8_t kSslServerHello[] = {
     0x16,                                            // handshake message
@@ -178,6 +179,11 @@
     0x00                                             // null compression
 };
 
+// static
+ArrayView<const uint8_t> AsyncSSLSocket::SslServerHello() {
+  return {kSslServerHello, sizeof(kSslServerHello)};
+}
+
 AsyncSSLSocket::AsyncSSLSocket(AsyncSocket* socket)
     : BufferedReadAdapter(socket, 1024) {}
 
@@ -219,35 +225,6 @@
     SignalReadEvent(this);
 }
 
-AsyncSSLServerSocket::AsyncSSLServerSocket(AsyncSocket* socket)
-    : BufferedReadAdapter(socket, 1024) {
-  BufferInput(true);
-}
-
-void AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) {
-  // We only accept client hello messages.
-  if (*len < sizeof(kSslClientHello)) {
-    return;
-  }
-
-  if (memcmp(kSslClientHello, data, sizeof(kSslClientHello)) != 0) {
-    Close();
-    SignalCloseEvent(this, 0);
-    return;
-  }
-
-  *len -= sizeof(kSslClientHello);
-
-  // Clients should not send more data until the handshake is completed.
-  RTC_DCHECK(*len == 0);
-
-  // Send a server hello back to the client.
-  DirectSend(kSslServerHello, sizeof(kSslServerHello));
-
-  // Handshake completed for us, redirect input to our parent.
-  BufferInput(false);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 AsyncHttpsProxySocket::AsyncHttpsProxySocket(AsyncSocket* socket,
@@ -714,135 +691,4 @@
   SignalCloseEvent(this, error);
 }
 
-AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(AsyncSocket* socket)
-    : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) {
-  BufferInput(true);
-}
-
-void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) {
-  // TODO: See if the whole message has arrived
-  RTC_DCHECK(state_ < SS_CONNECT_PENDING);
-
-  ByteBufferReader response(data, *len);
-  if (state_ == SS_HELLO) {
-    HandleHello(&response);
-  } else if (state_ == SS_AUTH) {
-    HandleAuth(&response);
-  } else if (state_ == SS_CONNECT) {
-    HandleConnect(&response);
-  }
-
-  // Consume parsed data
-  *len = response.Length();
-  memmove(data, response.Data(), *len);
-}
-
-void AsyncSocksProxyServerSocket::DirectSend(const ByteBufferWriter& buf) {
-  BufferedReadAdapter::DirectSend(buf.Data(), buf.Length());
-}
-
-void AsyncSocksProxyServerSocket::HandleHello(ByteBufferReader* request) {
-  uint8_t ver, num_methods;
-  if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&num_methods)) {
-    Error(0);
-    return;
-  }
-
-  if (ver != 5) {
-    Error(0);
-    return;
-  }
-
-  // Handle either no-auth (0) or user/pass auth (2)
-  uint8_t method = 0xFF;
-  if (num_methods > 0 && !request->ReadUInt8(&method)) {
-    Error(0);
-    return;
-  }
-
-  // TODO: Ask the server which method to use.
-  SendHelloReply(method);
-  if (method == 0) {
-    state_ = SS_CONNECT;
-  } else if (method == 2) {
-    state_ = SS_AUTH;
-  } else {
-    state_ = SS_ERROR;
-  }
-}
-
-void AsyncSocksProxyServerSocket::SendHelloReply(uint8_t method) {
-  ByteBufferWriter response;
-  response.WriteUInt8(5);       // Socks Version
-  response.WriteUInt8(method);  // Auth method
-  DirectSend(response);
-}
-
-void AsyncSocksProxyServerSocket::HandleAuth(ByteBufferReader* request) {
-  uint8_t ver, user_len, pass_len;
-  std::string user, pass;
-  if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&user_len) ||
-      !request->ReadString(&user, user_len) || !request->ReadUInt8(&pass_len) ||
-      !request->ReadString(&pass, pass_len)) {
-    Error(0);
-    return;
-  }
-
-  // TODO: Allow for checking of credentials.
-  SendAuthReply(0);
-  state_ = SS_CONNECT;
-}
-
-void AsyncSocksProxyServerSocket::SendAuthReply(uint8_t result) {
-  ByteBufferWriter response;
-  response.WriteUInt8(1);  // Negotiation Version
-  response.WriteUInt8(result);
-  DirectSend(response);
-}
-
-void AsyncSocksProxyServerSocket::HandleConnect(ByteBufferReader* request) {
-  uint8_t ver, command, reserved, addr_type;
-  uint32_t ip;
-  uint16_t port;
-  if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&command) ||
-      !request->ReadUInt8(&reserved) || !request->ReadUInt8(&addr_type) ||
-      !request->ReadUInt32(&ip) || !request->ReadUInt16(&port)) {
-    Error(0);
-    return;
-  }
-
-  if (ver != 5 || command != 1 || reserved != 0 || addr_type != 1) {
-    Error(0);
-    return;
-  }
-
-  SignalConnectRequest(this, SocketAddress(ip, port));
-  state_ = SS_CONNECT_PENDING;
-}
-
-void AsyncSocksProxyServerSocket::SendConnectResult(int result,
-                                                    const SocketAddress& addr) {
-  if (state_ != SS_CONNECT_PENDING)
-    return;
-
-  ByteBufferWriter response;
-  response.WriteUInt8(5);              // Socks version
-  response.WriteUInt8((result != 0));  // 0x01 is generic error
-  response.WriteUInt8(0);              // reserved
-  response.WriteUInt8(1);              // IPv4 address
-  response.WriteUInt32(addr.ip());
-  response.WriteUInt16(addr.port());
-  DirectSend(response);
-  BufferInput(false);
-  state_ = SS_TUNNEL;
-}
-
-void AsyncSocksProxyServerSocket::Error(int error) {
-  state_ = SS_ERROR;
-  BufferInput(false);
-  Close();
-  SetError(SOCKET_EACCES);
-  SignalCloseEvent(this, error);
-}
-
 }  // namespace rtc
diff --git a/rtc_base/socketadapters.h b/rtc_base/socketadapters.h
index 062f75c..ca55909 100644
--- a/rtc_base/socketadapters.h
+++ b/rtc_base/socketadapters.h
@@ -13,6 +13,7 @@
 
 #include <string>
 
+#include "api/array_view.h"
 #include "rtc_base/asyncsocket.h"
 #include "rtc_base/constructormagic.h"
 #include "rtc_base/cryptstring.h"
@@ -55,22 +56,13 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-// Interface for implementing proxy server sockets.
-class AsyncProxyServerSocket : public BufferedReadAdapter {
- public:
-  AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size);
-  ~AsyncProxyServerSocket() override;
-  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:
+  static ArrayView<const uint8_t> SslClientHello();
+  static ArrayView<const uint8_t> SslServerHello();
+
   explicit AsyncSSLSocket(AsyncSocket* socket);
 
   int Connect(const SocketAddress& addr) override;
@@ -81,17 +73,6 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(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:
-  void ProcessInput(char* data, size_t* len) override;
-  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSSLServerSocket);
-};
-
 ///////////////////////////////////////////////////////////////////////////////
 
 // Implements a socket adapter that speaks the HTTP/S proxy protocol.
@@ -184,37 +165,6 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSocksProxySocket);
 };
 
-// Implements a proxy server socket for the SOCKS protocol.
-class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket {
- public:
-  explicit AsyncSocksProxyServerSocket(AsyncSocket* socket);
-
- private:
-  void ProcessInput(char* data, size_t* len) override;
-  void DirectSend(const ByteBufferWriter& buf);
-
-  void HandleHello(ByteBufferReader* request);
-  void SendHelloReply(uint8_t method);
-  void HandleAuth(ByteBufferReader* request);
-  void SendAuthReply(uint8_t result);
-  void HandleConnect(ByteBufferReader* request);
-  void SendConnectResult(int result, const SocketAddress& addr) override;
-
-  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_;
-  RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSocksProxyServerSocket);
-};
-
 }  // namespace rtc
 
 #endif  // RTC_BASE_SOCKETADAPTERS_H_