Commit d4a7542e authored by Orvid King's avatar Orvid King Committed by Facebook Github Bot

Create a handle-type agnostic sockets API and back the Windows socket portability layer with it

Summary:
The end goal will be to have all calls to the sockets APIs go through the agnostic API rather than the current approach, as the current approach causes a limit of ~64k sockets, due to file descriptor limitations on Windows.
All this diff does for now is create a sockets API that is not backed by file descriptors on Windows.
This also shifts the sockets portability layer to be backed by these APIs until the sockets portability layer is removed.

Reviewed By: yfeldblum

Differential Revision: D10235797

fbshipit-source-id: 1c073231290da48832608f6fec272c3d675bdfd7
parent 0207d08f
This diff is collapsed.
/*
* Copyright 2013-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <cstdint>
#include <folly/net/NetworkSocket.h>
#include <folly/portability/IOVec.h>
#include <folly/portability/SysTypes.h>
#include <folly/portability/Windows.h>
#ifndef _WIN32
#include <netdb.h>
#include <poll.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef MSG_ERRQUEUE
#define FOLLY_HAVE_MSG_ERRQUEUE 1
/* for struct sock_extended_err*/
#include <linux/errqueue.h>
#endif
#ifndef SO_EE_ORIGIN_ZEROCOPY
#define SO_EE_ORIGIN_ZEROCOPY 5
#endif
#ifndef SO_EE_CODE_ZEROCOPY_COPIED
#define SO_EE_CODE_ZEROCOPY_COPIED 1
#endif
#ifndef SO_ZEROCOPY
#define SO_ZEROCOPY 60
#endif
#ifndef MSG_ZEROCOPY
#define MSG_ZEROCOPY 0x4000000
#endif
#ifndef SOL_UDP
#define SOL_UDP 17
#endif
#ifndef ETH_MAX_MTU
#define ETH_MAX_MTU 0xFFFFU
#endif
#ifndef UDP_SEGMENT
#define UDP_SEGMENT 103
#endif
#ifndef UDP_MAX_SEGMENTS
#define UDP_MAX_SEGMENTS (1 << 6UL)
#endif
#else
#include <WS2tcpip.h> // @manual
using nfds_t = int;
using sa_family_t = ADDRESS_FAMILY;
// these are not supported
#define SO_EE_ORIGIN_ZEROCOPY 0
#define SO_ZEROCOPY 0
#define MSG_ZEROCOPY 0x0
#define SOL_UDP 0x0
#define UDP_SEGMENT 0x0
// We don't actually support either of these flags
// currently.
#define MSG_DONTWAIT 0x1000
#define MSG_EOR 0
struct msghdr {
void* msg_name;
socklen_t msg_namelen;
struct iovec* msg_iov;
size_t msg_iovlen;
void* msg_control;
size_t msg_controllen;
int msg_flags;
};
struct sockaddr_un {
sa_family_t sun_family;
char sun_path[108];
};
#define SHUT_RD SD_RECEIVE
#define SHUT_WR SD_SEND
#define SHUT_RDWR SD_BOTH
// These are the same, but PF_LOCAL
// isn't defined by WinSock.
#define AF_LOCAL PF_UNIX
#define PF_LOCAL PF_UNIX
// This isn't defined by Windows, and we need to
// distinguish it from SO_REUSEADDR
#define SO_REUSEPORT 0x7001
// Someone thought it would be a good idea
// to define a field via a macro...
#undef s_host
#endif
namespace folly {
namespace netops {
// Poll descriptor is intended to be byte-for-byte identical to pollfd,
// except that it is typed as containing a NetworkSocket for sane interactions.
struct PollDescriptor {
NetworkSocket fd;
int16_t events;
int16_t revents;
};
NetworkSocket accept(NetworkSocket s, sockaddr* addr, socklen_t* addrlen);
int bind(NetworkSocket s, const sockaddr* name, socklen_t namelen);
int connect(NetworkSocket s, const sockaddr* name, socklen_t namelen);
int getpeername(NetworkSocket s, sockaddr* name, socklen_t* namelen);
int getsockname(NetworkSocket s, sockaddr* name, socklen_t* namelen);
int getsockopt(
NetworkSocket s,
int level,
int optname,
void* optval,
socklen_t* optlen);
int inet_aton(const char* cp, in_addr* inp);
int listen(NetworkSocket s, int backlog);
int poll(PollDescriptor fds[], nfds_t nfds, int timeout);
ssize_t recv(NetworkSocket s, void* buf, size_t len, int flags);
ssize_t recvfrom(
NetworkSocket s,
void* buf,
size_t len,
int flags,
sockaddr* from,
socklen_t* fromlen);
ssize_t recvmsg(NetworkSocket s, msghdr* message, int flags);
ssize_t send(NetworkSocket s, const void* buf, size_t len, int flags);
ssize_t sendto(
NetworkSocket s,
const void* buf,
size_t len,
int flags,
const sockaddr* to,
socklen_t tolen);
ssize_t sendmsg(NetworkSocket socket, const msghdr* message, int flags);
int setsockopt(
NetworkSocket s,
int level,
int optname,
const void* optval,
socklen_t optlen);
int shutdown(NetworkSocket s, int how);
NetworkSocket socket(int af, int type, int protocol);
int socketpair(int domain, int type, int protocol, NetworkSocket sv[2]);
// And now we diverge from the Posix way of doing things and just do things
// our own way.
int set_socket_non_blocking(NetworkSocket s);
int set_socket_close_on_exec(NetworkSocket s);
} // namespace netops
} // namespace folly
/*
* Copyright 2013-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <ostream>
#include <folly/portability/Windows.h>
namespace folly {
/**
* This is just a very thin wrapper around either a file descriptor or
* a SOCKET depending on platform, along with a couple of helper methods
* for explicitly converting to/from file descriptors, even on Windows.
*/
struct NetworkSocket {
#if _WIN32
using native_handle_type = SOCKET;
static constexpr native_handle_type invalid_handle_value = INVALID_SOCKET;
#else
using native_handle_type = int;
static constexpr native_handle_type invalid_handle_value = -1;
#endif
native_handle_type data;
constexpr NetworkSocket() : data(invalid_handle_value) {}
constexpr explicit NetworkSocket(native_handle_type d) : data(d) {}
friend constexpr bool operator==(
const NetworkSocket& a,
const NetworkSocket& b) noexcept {
return a.data == b.data;
}
friend constexpr bool operator!=(
const NetworkSocket& a,
const NetworkSocket& b) noexcept {
return !(a == b);
}
};
template <class CharT, class Traits>
inline std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os,
const NetworkSocket& addr) {
os << "folly::NetworkSocket(" << addr.data << ")";
return os;
}
} // namespace folly
This diff is collapsed.
......@@ -16,107 +16,7 @@
#pragma once
#ifndef _WIN32
#include <netdb.h>
#include <poll.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef MSG_ERRQUEUE
#define FOLLY_HAVE_MSG_ERRQUEUE 1
/* for struct sock_extended_err*/
#include <linux/errqueue.h>
#endif
#ifndef SO_EE_ORIGIN_ZEROCOPY
#define SO_EE_ORIGIN_ZEROCOPY 5
#endif
#ifndef SO_EE_CODE_ZEROCOPY_COPIED
#define SO_EE_CODE_ZEROCOPY_COPIED 1
#endif
#ifndef SO_ZEROCOPY
#define SO_ZEROCOPY 60
#endif
#ifndef MSG_ZEROCOPY
#define MSG_ZEROCOPY 0x4000000
#endif
#ifndef SOL_UDP
#define SOL_UDP 17
#endif
#ifndef ETH_MAX_MTU
#define ETH_MAX_MTU 0xFFFFU
#endif
#ifndef UDP_SEGMENT
#define UDP_SEGMENT 103
#endif
#ifndef UDP_MAX_SEGMENTS
#define UDP_MAX_SEGMENTS (1 << 6UL)
#endif
#else
#include <folly/portability/IOVec.h>
#include <folly/portability/SysTypes.h>
#include <folly/portability/Windows.h>
#include <WS2tcpip.h> // @manual
using nfds_t = int;
using sa_family_t = ADDRESS_FAMILY;
// these are not supported
#define SO_EE_ORIGIN_ZEROCOPY 0
#define SO_ZEROCOPY 0
#define MSG_ZEROCOPY 0x0
#define SOL_UDP 0x0
#define UDP_SEGMENT 0x0
// We don't actually support either of these flags
// currently.
#define MSG_DONTWAIT 0x1000
#define MSG_EOR 0
struct msghdr {
void* msg_name;
socklen_t msg_namelen;
struct iovec* msg_iov;
size_t msg_iovlen;
void* msg_control;
size_t msg_controllen;
int msg_flags;
};
struct sockaddr_un {
sa_family_t sun_family;
char sun_path[108];
};
#define SHUT_RD SD_RECEIVE
#define SHUT_WR SD_SEND
#define SHUT_RDWR SD_BOTH
// These are the same, but PF_LOCAL
// isn't defined by WinSock.
#define AF_LOCAL PF_UNIX
#define PF_LOCAL PF_UNIX
// This isn't defined by Windows, and we need to
// distinguish it from SO_REUSEADDR
#define SO_REUSEPORT 0x7001
// Someone thought it would be a good idea
// to define a field via a macro...
#undef s_host
#endif
#include <folly/net/NetOps.h>
namespace folly {
namespace portability {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment