arc: Move platform2/arc/network/ to platform2/patchpanel

Next step in the arc-networkd -> patchpanel rename, this patch moves the
location of the code.

BUG=b:151879931
TEST=units,flashed image to atlas
TEST=tasts arc.PlayStore, crostini.LaunchTerminal.download

Change-Id: I1b5cf8d670e1631d46f6449b725395157bf88dde
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2115863
Tested-by: Garrick Evans <garrick@chromium.org>
Commit-Queue: Garrick Evans <garrick@chromium.org>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Eric Caruso <ejcaruso@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/socket.cc b/patchpanel/socket.cc
new file mode 100644
index 0000000..bd6e248
--- /dev/null
+++ b/patchpanel/socket.cc
@@ -0,0 +1,123 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "patchpanel/socket.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <net/if.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <utility>
+
+#include <base/logging.h>
+#include <base/memory/ptr_util.h>
+
+#include "patchpanel/net_util.h"
+
+namespace patchpanel {
+namespace {
+
+bool WouldBlock() {
+  return errno == EAGAIN || errno == EWOULDBLOCK;
+}
+}  // namespace
+
+Socket::Socket(int family, int type) : fd_(socket(family, type, 0)) {
+  if (!fd_.is_valid())
+    PLOG(ERROR) << "socket failed (" << family << ", " << type << ")";
+}
+
+Socket::Socket(base::ScopedFD fd) : fd_(std::move(fd)) {
+  if (!fd_.is_valid())
+    LOG(ERROR) << "invalid fd";
+}
+
+bool Socket::Bind(const struct sockaddr* addr, socklen_t addrlen) {
+  if (bind(fd_.get(), addr, addrlen) < 0) {
+    PLOG(WARNING) << "bind failed: " << *addr;
+    return false;
+  }
+  return true;
+}
+
+bool Socket::Connect(const struct sockaddr* addr, socklen_t addrlen) {
+  if (connect(fd_.get(), addr, addrlen) < 0) {
+    PLOG(WARNING) << "connect failed: " << *addr;
+    return false;
+  }
+  return true;
+}
+
+bool Socket::Listen(int backlog) const {
+  if (listen(fd_.get(), backlog) != 0) {
+    PLOG(WARNING) << "listen failed";
+    return false;
+  }
+  return true;
+}
+
+std::unique_ptr<Socket> Socket::Accept(struct sockaddr* addr,
+                                       socklen_t* addrlen) const {
+  base::ScopedFD fd(accept(fd_.get(), addr, addrlen));
+  if (!fd.is_valid()) {
+    if (!WouldBlock())
+      PLOG(WARNING) << "accept failed";
+    return nullptr;
+  }
+  return std::make_unique<Socket>(std::move(fd));
+}
+
+ssize_t Socket::SendTo(const void* data,
+                       size_t len,
+                       const struct sockaddr* addr,
+                       socklen_t addrlen) {
+  if (!fd_.is_valid()) {
+    return -1;
+  }
+  if (!addr) {
+    addrlen = 0;
+  } else if (addrlen == 0) {
+    addrlen = sizeof(*addr);
+  }
+
+  ssize_t bytes = sendto(fd_.get(), data, len, MSG_NOSIGNAL, addr, addrlen);
+  if (bytes >= 0)
+    return bytes;
+
+  if (WouldBlock())
+    return 0;
+
+  PLOG(WARNING) << "sendto failed";
+  return bytes;
+}
+
+ssize_t Socket::RecvFrom(void* data,
+                         size_t len,
+                         struct sockaddr* addr,
+                         socklen_t addrlen) {
+  socklen_t recvlen = addrlen;
+  ssize_t bytes = recvfrom(fd_.get(), data, len, 0, addr, &recvlen);
+  if (bytes >= 0) {
+    if (recvlen != addrlen)
+      PLOG(WARNING) << "recvfrom failed: unexpected src addr length "
+                    << recvlen;
+    return bytes;
+  }
+
+  if (WouldBlock())
+    return 0;
+
+  PLOG(WARNING) << "recvfrom failed";
+  return bytes;
+}
+
+std::ostream& operator<<(std::ostream& stream, const Socket& socket) {
+  stream << "{fd: " << socket.fd() << "}";
+  return stream;
+}
+
+}  // namespace patchpanel