1/*
2 * Copyright 2013-present Facebook, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <cstdint>
20
21#include <folly/net/NetworkSocket.h>
22#include <folly/portability/IOVec.h>
23#include <folly/portability/SysTypes.h>
24#include <folly/portability/Windows.h>
25
26#ifndef _WIN32
27#include <netdb.h>
28#include <poll.h>
29
30#include <arpa/inet.h>
31#include <netinet/in.h>
32#include <netinet/tcp.h>
33#include <sys/socket.h>
34#include <sys/un.h>
35
36#ifdef MSG_ERRQUEUE
37#define FOLLY_HAVE_MSG_ERRQUEUE 1
38/* for struct sock_extended_err*/
39#include <linux/errqueue.h>
40#endif
41
42#ifndef SO_EE_ORIGIN_ZEROCOPY
43#define SO_EE_ORIGIN_ZEROCOPY 5
44#endif
45
46#ifndef SO_EE_CODE_ZEROCOPY_COPIED
47#define SO_EE_CODE_ZEROCOPY_COPIED 1
48#endif
49
50#ifndef SO_ZEROCOPY
51#define SO_ZEROCOPY 60
52#endif
53
54#ifndef MSG_ZEROCOPY
55#define MSG_ZEROCOPY 0x4000000
56#endif
57
58#ifndef SOL_UDP
59#define SOL_UDP 17
60#endif
61
62#ifndef ETH_MAX_MTU
63#define ETH_MAX_MTU 0xFFFFU
64#endif
65
66#ifndef UDP_SEGMENT
67#define UDP_SEGMENT 103
68#endif
69
70#ifndef UDP_MAX_SEGMENTS
71#define UDP_MAX_SEGMENTS (1 << 6UL)
72#endif
73
74#if (!__linux__) || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
75struct mmsghdr {
76 struct msghdr msg_hdr;
77 unsigned int msg_len;
78};
79#else
80#define FOLLY_HAVE_SENDMMSG 1
81#endif
82
83#else
84#include <WS2tcpip.h> // @manual
85
86using nfds_t = int;
87using sa_family_t = ADDRESS_FAMILY;
88
89// these are not supported
90#define SO_EE_ORIGIN_ZEROCOPY 0
91#define SO_ZEROCOPY 0
92#define MSG_ZEROCOPY 0x0
93#define SOL_UDP 0x0
94#define UDP_SEGMENT 0x0
95
96// We don't actually support either of these flags
97// currently.
98#define MSG_DONTWAIT 0x1000
99#define MSG_EOR 0
100struct msghdr {
101 void* msg_name;
102 socklen_t msg_namelen;
103 struct iovec* msg_iov;
104 size_t msg_iovlen;
105 void* msg_control;
106 size_t msg_controllen;
107 int msg_flags;
108};
109
110struct mmsghdr {
111 struct msghdr msg_hdr;
112 unsigned int msg_len;
113};
114
115struct sockaddr_un {
116 sa_family_t sun_family;
117 char sun_path[108];
118};
119
120#define SHUT_RD SD_RECEIVE
121#define SHUT_WR SD_SEND
122#define SHUT_RDWR SD_BOTH
123
124// These are the same, but PF_LOCAL
125// isn't defined by WinSock.
126#define AF_LOCAL PF_UNIX
127#define PF_LOCAL PF_UNIX
128
129// This isn't defined by Windows, and we need to
130// distinguish it from SO_REUSEADDR
131#define SO_REUSEPORT 0x7001
132
133// Someone thought it would be a good idea
134// to define a field via a macro...
135#undef s_host
136#endif
137
138namespace folly {
139namespace netops {
140// Poll descriptor is intended to be byte-for-byte identical to pollfd,
141// except that it is typed as containing a NetworkSocket for sane interactions.
142struct PollDescriptor {
143 NetworkSocket fd;
144 int16_t events;
145 int16_t revents;
146};
147
148NetworkSocket accept(NetworkSocket s, sockaddr* addr, socklen_t* addrlen);
149int bind(NetworkSocket s, const sockaddr* name, socklen_t namelen);
150int close(NetworkSocket s);
151int connect(NetworkSocket s, const sockaddr* name, socklen_t namelen);
152int getpeername(NetworkSocket s, sockaddr* name, socklen_t* namelen);
153int getsockname(NetworkSocket s, sockaddr* name, socklen_t* namelen);
154int getsockopt(
155 NetworkSocket s,
156 int level,
157 int optname,
158 void* optval,
159 socklen_t* optlen);
160int inet_aton(const char* cp, in_addr* inp);
161int listen(NetworkSocket s, int backlog);
162int poll(PollDescriptor fds[], nfds_t nfds, int timeout);
163ssize_t recv(NetworkSocket s, void* buf, size_t len, int flags);
164ssize_t recvfrom(
165 NetworkSocket s,
166 void* buf,
167 size_t len,
168 int flags,
169 sockaddr* from,
170 socklen_t* fromlen);
171ssize_t recvmsg(NetworkSocket s, msghdr* message, int flags);
172ssize_t send(NetworkSocket s, const void* buf, size_t len, int flags);
173ssize_t sendto(
174 NetworkSocket s,
175 const void* buf,
176 size_t len,
177 int flags,
178 const sockaddr* to,
179 socklen_t tolen);
180ssize_t sendmsg(NetworkSocket socket, const msghdr* message, int flags);
181int sendmmsg(
182 NetworkSocket socket,
183 mmsghdr* msgvec,
184 unsigned int vlen,
185 int flags);
186int setsockopt(
187 NetworkSocket s,
188 int level,
189 int optname,
190 const void* optval,
191 socklen_t optlen);
192int shutdown(NetworkSocket s, int how);
193NetworkSocket socket(int af, int type, int protocol);
194int socketpair(int domain, int type, int protocol, NetworkSocket sv[2]);
195
196// And now we diverge from the Posix way of doing things and just do things
197// our own way.
198int set_socket_non_blocking(NetworkSocket s);
199int set_socket_close_on_exec(NetworkSocket s);
200} // namespace netops
201} // namespace folly
202