| Index: net/tools/flip_server/tcp_socket_util.cc
|
| diff --git a/net/tools/flip_server/tcp_socket_util.cc b/net/tools/flip_server/tcp_socket_util.cc
|
| deleted file mode 100644
|
| index 00f9b7e59e0ad68467d9c2d683e2ed592a4a57bc..0000000000000000000000000000000000000000
|
| --- a/net/tools/flip_server/tcp_socket_util.cc
|
| +++ /dev/null
|
| @@ -1,276 +0,0 @@
|
| -// Copyright (c) 2009 The Chromium 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 "net/tools/flip_server/tcp_socket_util.h"
|
| -
|
| -#include <arpa/inet.h>
|
| -#include <errno.h>
|
| -#include <netdb.h>
|
| -#include <netinet/in.h>
|
| -#include <netinet/tcp.h>
|
| -#include <stdlib.h>
|
| -#include <string.h>
|
| -#include <sys/socket.h>
|
| -#include <sys/types.h>
|
| -#include <unistd.h>
|
| -
|
| -#include "base/files/file_util.h"
|
| -#include "base/logging.h"
|
| -#include "net/socket/tcp_socket.h"
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -// Used to ensure we delete the addrinfo structure alloc'd by getaddrinfo().
|
| -class AddrinfoGuard {
|
| - public:
|
| - explicit AddrinfoGuard(struct addrinfo* addrinfo_ptr)
|
| - : addrinfo_ptr_(addrinfo_ptr) {}
|
| -
|
| - ~AddrinfoGuard() { freeaddrinfo(addrinfo_ptr_); }
|
| -
|
| - private:
|
| - struct addrinfo* addrinfo_ptr_;
|
| -};
|
| -
|
| -// Summary:
|
| -// Closes a socket, with option to attempt it multiple times.
|
| -// Why do this? Well, if the system-call gets interrupted, close
|
| -// can fail with EINTR. In that case you should just retry.. Unfortunately,
|
| -// we can't be sure that errno is properly set since we're using a
|
| -// multithreaded approach in the filter proxy, so we should just retry.
|
| -// Args:
|
| -// fd - the socket to close
|
| -// tries - the number of tries to close the socket.
|
| -// Returns:
|
| -// true - if socket was closed
|
| -// false - if socket was NOT closed.
|
| -// Side-effects:
|
| -// sets *fd to -1 if socket was closed.
|
| -//
|
| -bool CloseSocket(int* fd, int tries) {
|
| - for (int i = 0; i < tries; ++i) {
|
| - if (!close(*fd)) {
|
| - *fd = -1;
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -int CreateTCPServerSocket(const std::string& host,
|
| - const std::string& port,
|
| - bool is_numeric_host_address,
|
| - int backlog,
|
| - bool reuseaddr,
|
| - bool reuseport,
|
| - bool wait_for_iface,
|
| - bool disable_nagle,
|
| - int* listen_fd) {
|
| - // start out by assuming things will fail.
|
| - *listen_fd = -1;
|
| -
|
| - const char* node = NULL;
|
| - const char* service = NULL;
|
| -
|
| - if (!host.empty())
|
| - node = host.c_str();
|
| - if (!port.empty())
|
| - service = port.c_str();
|
| -
|
| - struct addrinfo* results = 0;
|
| - struct addrinfo hints;
|
| - memset(&hints, 0, sizeof(hints));
|
| -
|
| - if (is_numeric_host_address) {
|
| - hints.ai_flags = AI_NUMERICHOST; // iff you know the name is numeric.
|
| - }
|
| - hints.ai_flags |= AI_PASSIVE;
|
| -
|
| - hints.ai_family = PF_INET;
|
| - hints.ai_socktype = SOCK_STREAM;
|
| -
|
| - int err = 0;
|
| - if ((err = getaddrinfo(node, service, &hints, &results))) {
|
| - // gai_strerror -is- threadsafe, so we get to use it here.
|
| - LOG(ERROR) << "getaddrinfo "
|
| - << " for (" << host << ":" << port << ") " << gai_strerror(err)
|
| - << "\n";
|
| - return -1;
|
| - }
|
| - // this will delete the addrinfo memory when we return from this function.
|
| - AddrinfoGuard addrinfo_guard(results);
|
| -
|
| - int sock =
|
| - socket(results->ai_family, results->ai_socktype, results->ai_protocol);
|
| - if (sock == -1) {
|
| - LOG(ERROR) << "Unable to create socket for (" << host << ":" << port
|
| - << "): " << strerror(errno) << "\n";
|
| - return -1;
|
| - }
|
| -
|
| - if (reuseaddr) {
|
| - // set SO_REUSEADDR on the listening socket.
|
| - int on = 1;
|
| - int rc;
|
| - rc = setsockopt(sock,
|
| - SOL_SOCKET,
|
| - SO_REUSEADDR,
|
| - reinterpret_cast<char*>(&on),
|
| - sizeof(on));
|
| - if (rc < 0) {
|
| - close(sock);
|
| - LOG(FATAL) << "setsockopt() failed fd=" << listen_fd << "\n";
|
| - }
|
| - }
|
| -#ifndef SO_REUSEPORT
|
| -#define SO_REUSEPORT 15
|
| -#endif
|
| - if (reuseport) {
|
| - // set SO_REUSEPORT on the listening socket.
|
| - int on = 1;
|
| - int rc;
|
| - rc = setsockopt(sock,
|
| - SOL_SOCKET,
|
| - SO_REUSEPORT,
|
| - reinterpret_cast<char*>(&on),
|
| - sizeof(on));
|
| - if (rc < 0) {
|
| - close(sock);
|
| - LOG(FATAL) << "setsockopt() failed fd=" << listen_fd << "\n";
|
| - }
|
| - }
|
| -
|
| - if (bind(sock, results->ai_addr, results->ai_addrlen)) {
|
| - // If we are waiting for the interface to be raised, such as in an
|
| - // HA environment, ignore reporting any errors.
|
| - int saved_errno = errno;
|
| - if (!wait_for_iface || errno != EADDRNOTAVAIL) {
|
| - LOG(ERROR) << "Bind was unsuccessful for (" << host << ":" << port
|
| - << "): " << strerror(errno) << "\n";
|
| - }
|
| - // if we knew that we were not multithreaded, we could do the following:
|
| - // " : " << strerror(errno) << "\n";
|
| - if (CloseSocket(&sock, 100)) {
|
| - if (saved_errno == EADDRNOTAVAIL) {
|
| - return -3;
|
| - }
|
| - return -2;
|
| - } else {
|
| - // couldn't even close the dang socket?!
|
| - LOG(ERROR) << "Unable to close the socket.. Considering this a fatal "
|
| - "error, and exiting\n";
|
| - exit(EXIT_FAILURE);
|
| - return -1;
|
| - }
|
| - }
|
| -
|
| - if (disable_nagle) {
|
| - if (!SetTCPNoDelay(sock, /*no_delay=*/true)) {
|
| - close(sock);
|
| - LOG(FATAL) << "SetTCPNoDelay() failed on fd: " << sock;
|
| - return -1;
|
| - }
|
| - }
|
| -
|
| - if (listen(sock, backlog)) {
|
| - // listen was unsuccessful.
|
| - LOG(ERROR) << "Listen was unsuccessful for (" << host << ":" << port
|
| - << "): " << strerror(errno) << "\n";
|
| - // if we knew that we were not multithreaded, we could do the following:
|
| - // " : " << strerror(errno) << "\n";
|
| -
|
| - if (CloseSocket(&sock, 100)) {
|
| - sock = -1;
|
| - return -1;
|
| - } else {
|
| - // couldn't even close the dang socket?!
|
| - LOG(FATAL) << "Unable to close the socket.. Considering this a fatal "
|
| - "error, and exiting\n";
|
| - }
|
| - }
|
| -
|
| - // If we've gotten to here, Yeay! Success!
|
| - *listen_fd = sock;
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -int CreateTCPClientSocket(const std::string& host,
|
| - const std::string& port,
|
| - bool is_numeric_host_address,
|
| - bool disable_nagle,
|
| - int* connect_fd) {
|
| - const char* node = NULL;
|
| - const char* service = NULL;
|
| -
|
| - *connect_fd = -1;
|
| - if (!host.empty())
|
| - node = host.c_str();
|
| - if (!port.empty())
|
| - service = port.c_str();
|
| -
|
| - struct addrinfo* results = 0;
|
| - struct addrinfo hints;
|
| - memset(&hints, 0, sizeof(hints));
|
| -
|
| - if (is_numeric_host_address)
|
| - hints.ai_flags = AI_NUMERICHOST; // iff you know the name is numeric.
|
| - hints.ai_flags |= AI_PASSIVE;
|
| -
|
| - hints.ai_family = PF_INET;
|
| - hints.ai_socktype = SOCK_STREAM;
|
| -
|
| - int err = 0;
|
| - if ((err = getaddrinfo(node, service, &hints, &results))) {
|
| - // gai_strerror -is- threadsafe, so we get to use it here.
|
| - LOG(ERROR) << "getaddrinfo for (" << node << ":" << service
|
| - << "): " << gai_strerror(err);
|
| - return -1;
|
| - }
|
| - // this will delete the addrinfo memory when we return from this function.
|
| - AddrinfoGuard addrinfo_guard(results);
|
| -
|
| - int sock =
|
| - socket(results->ai_family, results->ai_socktype, results->ai_protocol);
|
| - if (sock == -1) {
|
| - LOG(ERROR) << "Unable to create socket for (" << node << ":" << service
|
| - << "): " << strerror(errno);
|
| - return -1;
|
| - }
|
| -
|
| - if (!base::SetNonBlocking(sock)) {
|
| - LOG(FATAL) << "base::SetNonBlocking failed: " << sock;
|
| - }
|
| -
|
| - if (disable_nagle) {
|
| - if (!SetTCPNoDelay(sock, /*no_delay=*/true)) {
|
| - close(sock);
|
| - LOG(FATAL) << "SetTCPNoDelay() failed on fd: " << sock;
|
| - return -1;
|
| - }
|
| - }
|
| -
|
| - int ret_val = 0;
|
| - if (connect(sock, results->ai_addr, results->ai_addrlen)) {
|
| - if (errno != EINPROGRESS) {
|
| - LOG(ERROR) << "Connect was unsuccessful for (" << node << ":" << service
|
| - << "): " << strerror(errno);
|
| - close(sock);
|
| - return -1;
|
| - }
|
| - } else {
|
| - ret_val = 1;
|
| - }
|
| -
|
| - // If we've gotten to here, Yeay! Success!
|
| - *connect_fd = sock;
|
| -
|
| - return ret_val;
|
| -}
|
| -
|
| -} // namespace net
|
|
|