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