1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
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/Portability.h>
22 #include <folly/net/NetworkSocket.h>
23 #include <folly/portability/IOVec.h>
24 #include <folly/portability/SysTypes.h>
25 #include <folly/portability/Time.h>
26 #include <folly/portability/Windows.h>
27 
28 #ifdef _WIN32
29 
30 #include <WS2tcpip.h> // @manual
31 
32 using nfds_t = int;
33 using sa_family_t = ADDRESS_FAMILY;
34 
35 // these are not supported
36 #define SO_EE_ORIGIN_ZEROCOPY 0
37 #define SO_ZEROCOPY 0
38 #define SO_TXTIME 0
39 #define MSG_ZEROCOPY 0x0
40 #define SOL_UDP 0x0
41 #define UDP_SEGMENT 0x0
42 #define IP_BIND_ADDRESS_NO_PORT 0
43 
44 // We don't actually support either of these flags
45 // currently.
46 #define MSG_DONTWAIT 0x1000
47 #define MSG_EOR 0
48 struct msghdr {
49   void* msg_name;
50   socklen_t msg_namelen;
51   struct iovec* msg_iov;
52   size_t msg_iovlen;
53   void* msg_control;
54   size_t msg_controllen;
55   int msg_flags;
56 };
57 
58 struct mmsghdr {
59   struct msghdr msg_hdr;
60   unsigned int msg_len;
61 };
62 
63 struct sockaddr_un {
64   sa_family_t sun_family;
65   char sun_path[108];
66 };
67 
68 #define SHUT_RD SD_RECEIVE
69 #define SHUT_WR SD_SEND
70 #define SHUT_RDWR SD_BOTH
71 
72 // These are the same, but PF_LOCAL
73 // isn't defined by WinSock.
74 #define AF_LOCAL PF_UNIX
75 #define PF_LOCAL PF_UNIX
76 
77 // This isn't defined by Windows, and we need to
78 // distinguish it from SO_REUSEADDR
79 #define SO_REUSEPORT 0x7001
80 
81 // Someone thought it would be a good idea
82 // to define a field via a macro...
83 #undef s_host
84 #elif defined(__EMSCRIPTEN__)
85 // Stub this out for now.
86 using nfds_t = int;
87 using socklen_t = int;
88 struct sockaddr {};
89 struct in_addr {};
90 struct msghdr {
91   void* msg_name;
92   socklen_t msg_namelen;
93   struct iovec* msg_iov;
94   size_t msg_iovlen;
95   void* msg_control;
96   size_t msg_controllen;
97   int msg_flags;
98 };
99 
100 struct mmsghdr {
101   struct msghdr msg_hdr;
102   unsigned int msg_len;
103 };
104 #elif defined(__XROS__)
105 #include <xros/portability/net/xr_socket_compat.h> // @manual
106 
107 // Stub this out for now.
108 using nfds_t = int;
109 struct msghdr {
110   void* msg_name;
111   socklen_t msg_namelen;
112   struct iovec* msg_iov;
113   size_t msg_iovlen;
114   void* msg_control;
115   size_t msg_controllen;
116   int msg_flags;
117 };
118 
119 struct mmsghdr {
120   struct msghdr msg_hdr;
121   unsigned int msg_len;
122 };
123 
124 #define SHUT_RDWR 5
125 
126 #else
127 
128 #include <netdb.h>
129 #include <poll.h>
130 
131 #include <arpa/inet.h>
132 #include <netinet/in.h>
133 #include <netinet/tcp.h>
134 #include <netinet/udp.h>
135 #include <sys/socket.h>
136 #include <sys/un.h>
137 
138 #ifdef MSG_ERRQUEUE
139 #define FOLLY_HAVE_MSG_ERRQUEUE 1
140 #ifndef FOLLY_HAVE_SO_TIMESTAMPING
141 #define FOLLY_HAVE_SO_TIMESTAMPING 1
142 #endif
143 /* for struct sock_extended_err*/
144 #include <linux/errqueue.h>
145 #endif
146 
147 #ifndef SO_EE_ORIGIN_ZEROCOPY
148 #define SO_EE_ORIGIN_ZEROCOPY 5
149 #endif
150 
151 #ifndef SO_EE_CODE_ZEROCOPY_COPIED
152 #define SO_EE_CODE_ZEROCOPY_COPIED 1
153 #endif
154 
155 #ifndef SO_ZEROCOPY
156 #define SO_ZEROCOPY 60
157 #endif
158 
159 #ifndef SO_TXTIME
160 #define SO_TXTIME 61
161 #define SCM_TXTIME SO_TXTIME
162 #endif
163 
164 #ifdef FOLLY_HAVE_MSG_ERRQUEUE
165 namespace folly {
166 namespace netops {
167 
168 /* Copied from uapi/linux/net_tstamp.h */
169 enum txtime_flags {
170   SOF_TXTIME_DEADLINE_MODE = (1 << 0),
171   SOF_TXTIME_REPORT_ERRORS = (1 << 1),
172 
173   SOF_TXTIME_FLAGS_LAST = SOF_TXTIME_REPORT_ERRORS,
174   SOF_TXTIME_FLAGS_MASK = (SOF_TXTIME_FLAGS_LAST - 1) | SOF_TXTIME_FLAGS_LAST
175 };
176 
177 /* Copied from uapi/linux/net_tstamp.h */
178 enum timestamping_flags {
179   SOF_TIMESTAMPING_TX_HARDWARE = (1 << 0),
180   SOF_TIMESTAMPING_TX_SOFTWARE = (1 << 1),
181   SOF_TIMESTAMPING_RX_HARDWARE = (1 << 2),
182   SOF_TIMESTAMPING_RX_SOFTWARE = (1 << 3),
183   SOF_TIMESTAMPING_SOFTWARE = (1 << 4),
184   SOF_TIMESTAMPING_SYS_HARDWARE = (1 << 5),
185   SOF_TIMESTAMPING_RAW_HARDWARE = (1 << 6),
186   SOF_TIMESTAMPING_OPT_ID = (1 << 7),
187   SOF_TIMESTAMPING_TX_SCHED = (1 << 8),
188   SOF_TIMESTAMPING_TX_ACK = (1 << 9),
189   SOF_TIMESTAMPING_OPT_CMSG = (1 << 10),
190   SOF_TIMESTAMPING_OPT_TSONLY = (1 << 11),
191   SOF_TIMESTAMPING_OPT_STATS = (1 << 12),
192   SOF_TIMESTAMPING_OPT_PKTINFO = (1 << 13),
193   SOF_TIMESTAMPING_OPT_TX_SWHW = (1 << 14),
194 
195   SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW,
196   SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
197 };
198 
199 /* Copied from uapi/linux/net_tstamp.h */
200 enum tstamp_flags {
201   SCM_TSTAMP_SND, /* driver passed skb to NIC, or HW */
202   SCM_TSTAMP_SCHED, /* data entered the packet scheduler */
203   SCM_TSTAMP_ACK, /* data acknowledged by peer */
204 };
205 
206 struct sock_txtime {
207   __kernel_clockid_t clockid; /* reference clockid */
208   __u32 flags; /* as defined by enum txtime_flags */
209 };
210 } // namespace netops
211 } // namespace folly
212 #endif
213 
214 #ifndef MSG_ZEROCOPY
215 #define MSG_ZEROCOPY 0x4000000
216 #endif
217 
218 #ifndef SOL_UDP
219 #define SOL_UDP 17
220 #endif
221 
222 #ifndef ETH_MAX_MTU
223 #define ETH_MAX_MTU 0xFFFFU
224 #endif
225 
226 #ifndef UDP_NO_CHECK6_TX
227 #define UDP_NO_CHECK6_TX 101 /* Disable sending checksum for UDP6X */
228 #endif
229 
230 #ifndef UDP_NO_CHECK6_RX
231 #define UDP_NO_CHECK6_RX 102 /* Disable accpeting checksum for UDP6 */
232 #endif
233 
234 #ifndef UDP_SEGMENT
235 #define UDP_SEGMENT 103
236 #endif
237 
238 #ifndef UDP_GRO
239 #define UDP_GRO 104
240 #endif
241 
242 #ifndef UDP_MAX_SEGMENTS
243 #define UDP_MAX_SEGMENTS (1 << 6UL)
244 #endif
245 
246 #if !defined(MSG_WAITFORONE) && !defined(__wasm32__)
247 struct mmsghdr {
248   struct msghdr msg_hdr;
249   unsigned int msg_len;
250 };
251 #endif
252 
253 #ifndef IP_BIND_ADDRESS_NO_PORT
254 #define IP_BIND_ADDRESS_NO_PORT 24
255 #endif
256 
257 #endif
258 
259 namespace folly {
260 namespace netops {
261 // Poll descriptor is intended to be byte-for-byte identical to pollfd,
262 // except that it is typed as containing a NetworkSocket for sane interactions.
263 struct PollDescriptor {
264   NetworkSocket fd;
265   int16_t events;
266   int16_t revents;
267 };
268 
269 NetworkSocket accept(NetworkSocket s, sockaddr* addr, socklen_t* addrlen);
270 int bind(NetworkSocket s, const sockaddr* name, socklen_t namelen);
271 int close(NetworkSocket s);
272 int connect(NetworkSocket s, const sockaddr* name, socklen_t namelen);
273 int getpeername(NetworkSocket s, sockaddr* name, socklen_t* namelen);
274 int getsockname(NetworkSocket s, sockaddr* name, socklen_t* namelen);
275 int getsockopt(
276     NetworkSocket s, int level, int optname, void* optval, socklen_t* optlen);
277 int inet_aton(const char* cp, in_addr* inp);
278 int listen(NetworkSocket s, int backlog);
279 int poll(PollDescriptor fds[], nfds_t nfds, int timeout);
280 ssize_t recv(NetworkSocket s, void* buf, size_t len, int flags);
281 ssize_t recvfrom(
282     NetworkSocket s,
283     void* buf,
284     size_t len,
285     int flags,
286     sockaddr* from,
287     socklen_t* fromlen);
288 ssize_t recvmsg(NetworkSocket s, msghdr* message, int flags);
289 int recvmmsg(
290     NetworkSocket s,
291     mmsghdr* msgvec,
292     unsigned int vlen,
293     unsigned int flags,
294     timespec* timeout);
295 ssize_t send(NetworkSocket s, const void* buf, size_t len, int flags);
296 ssize_t sendto(
297     NetworkSocket s,
298     const void* buf,
299     size_t len,
300     int flags,
301     const sockaddr* to,
302     socklen_t tolen);
303 ssize_t sendmsg(NetworkSocket socket, const msghdr* message, int flags);
304 int sendmmsg(
305     NetworkSocket socket, mmsghdr* msgvec, unsigned int vlen, int flags);
306 int setsockopt(
307     NetworkSocket s,
308     int level,
309     int optname,
310     const void* optval,
311     socklen_t optlen);
312 int shutdown(NetworkSocket s, int how);
313 NetworkSocket socket(int af, int type, int protocol);
314 int socketpair(int domain, int type, int protocol, NetworkSocket sv[2]);
315 
316 // And now we diverge from the Posix way of doing things and just do things
317 // our own way.
318 int set_socket_non_blocking(NetworkSocket s);
319 int set_socket_close_on_exec(NetworkSocket s);
320 } // namespace netops
321 } // namespace folly
322