mhd_sockets.h (32266B)
1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2014-2023 Karlson2k (Evgeny Grin) 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 19 */ 20 21 /** 22 * @file microhttpd/mhd_sockets.c 23 * @brief Header for platform-independent sockets abstraction 24 * @author Karlson2k (Evgeny Grin) 25 * 26 * Provides basic abstraction for sockets. 27 * Any functions can be implemented as macro on some platforms 28 * unless explicitly marked otherwise. 29 * Any function argument can be skipped in macro, so avoid 30 * variable modification in function parameters. 31 */ 32 33 #ifndef MHD_SOCKETS_H 34 #define MHD_SOCKETS_H 1 35 #include "mhd_options.h" 36 37 #include <errno.h> 38 #ifdef HAVE_STDBOOL_H 39 #include <stdbool.h> 40 #endif /* HAVE_STDBOOL_H */ 41 #ifdef HAVE_UNISTD_H 42 #include <unistd.h> 43 #endif /* HAVE_UNISTD_H */ 44 #include <fcntl.h> 45 #ifdef HAVE_STDDEF_H 46 #include <stddef.h> 47 #endif /* HAVE_STDDEF_H */ 48 #if defined(_MSC_FULL_VER) && ! defined(_SSIZE_T_DEFINED) 49 # include <stdint.h> 50 # define _SSIZE_T_DEFINED 51 typedef intptr_t ssize_t; 52 #endif /* !_SSIZE_T_DEFINED */ 53 54 #if ! defined(MHD_POSIX_SOCKETS) && ! defined(MHD_WINSOCK_SOCKETS) 55 # if ! defined(_WIN32) || defined(__CYGWIN__) 56 # define MHD_POSIX_SOCKETS 1 57 # else /* defined(_WIN32) && !defined(__CYGWIN__) */ 58 # define MHD_WINSOCK_SOCKETS 1 59 # endif /* defined(_WIN32) && !defined(__CYGWIN__) */ 60 #endif /* !MHD_POSIX_SOCKETS && !MHD_WINSOCK_SOCKETS */ 61 62 /* 63 * MHD require headers that define socket type, socket basic functions 64 * (socket(), accept(), listen(), bind(), send(), recv(), select()), socket 65 * parameters like SOCK_CLOEXEC, SOCK_NONBLOCK, additional socket functions 66 * (poll(), epoll(), accept4()), struct timeval and other types, required 67 * for socket function. 68 */ 69 #if defined(MHD_POSIX_SOCKETS) 70 # ifdef HAVE_SYS_TYPES_H 71 # include <sys/types.h> /* required on old platforms */ 72 # endif 73 # ifdef HAVE_SYS_TIME_H 74 # include <sys/time.h> 75 # endif 76 # ifdef HAVE_TIME_H 77 # include <time.h> 78 # endif 79 # ifdef HAVE_STRING_H 80 # include <string.h> /* for strerror() */ 81 # endif 82 # ifdef HAVE_SYS_SOCKET_H 83 # include <sys/socket.h> 84 # endif 85 # if defined(__VXWORKS__) || defined(__vxworks) || defined(OS_VXWORKS) 86 # include <strings.h> /* required for FD_SET (bzero() function) */ 87 # ifdef HAVE_SOCKLIB_H 88 # include <sockLib.h> 89 # endif /* HAVE_SOCKLIB_H */ 90 # ifdef HAVE_INETLIB_H 91 # include <inetLib.h> 92 # endif /* HAVE_INETLIB_H */ 93 # endif /* __VXWORKS__ || __vxworks || OS_VXWORKS */ 94 # ifdef HAVE_NETINET_IN_H 95 # include <netinet/in.h> 96 # endif /* HAVE_NETINET_IN_H */ 97 # ifdef HAVE_ARPA_INET_H 98 # include <arpa/inet.h> 99 # endif 100 # ifdef HAVE_NET_IF_H 101 # include <net/if.h> 102 # endif 103 # ifdef HAVE_NETDB_H 104 # include <netdb.h> 105 # endif 106 # ifdef HAVE_SYS_SELECT_H 107 # include <sys/select.h> 108 # endif 109 # ifdef EPOLL_SUPPORT 110 # include <sys/epoll.h> 111 # endif 112 # ifdef HAVE_NETINET_TCP_H 113 /* for TCP_FASTOPEN and TCP_CORK */ 114 # include <netinet/tcp.h> 115 # endif 116 #elif defined(MHD_WINSOCK_SOCKETS) 117 # ifndef WIN32_LEAN_AND_MEAN 118 # define WIN32_LEAN_AND_MEAN 1 119 # endif /* !WIN32_LEAN_AND_MEAN */ 120 # include <winsock2.h> 121 # include <ws2tcpip.h> 122 #endif /* MHD_WINSOCK_SOCKETS */ 123 124 #if defined(HAVE_POLL_H) && defined(HAVE_POLL) 125 # include <poll.h> 126 #endif 127 128 129 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 130 #include <sys/param.h> /* For __FreeBSD_version */ 131 #endif /* __FreeBSD__ */ 132 133 #include "mhd_limits.h" 134 135 #ifdef _MHD_FD_SETSIZE_IS_DEFAULT 136 # define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE 137 #else /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ 138 # ifndef MHD_SYS_FD_SETSIZE_ 139 # include "sysfdsetsize.h" 140 # define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value () 141 # else /* MHD_SYS_FD_SETSIZE_ */ 142 # define _MHD_SYS_DEFAULT_FD_SETSIZE MHD_SYS_FD_SETSIZE_ 143 # endif /* MHD_SYS_FD_SETSIZE_ */ 144 #endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ 145 146 #ifndef MHD_PANIC 147 # include <stdio.h> 148 # include <stdlib.h> 149 /* Simple implementation of MHD_PANIC, to be used outside lib */ 150 # define MHD_PANIC(msg) \ 151 do { fprintf (stderr, \ 152 "Abnormal termination at %d line in file %s: %s\n", \ 153 (int) __LINE__, __FILE__, msg); abort (); \ 154 } while (0) 155 #endif /* ! MHD_PANIC */ 156 157 #ifndef MHD_SOCKET_DEFINED 158 /** 159 * MHD_socket is type for socket FDs 160 */ 161 # if defined(MHD_POSIX_SOCKETS) 162 typedef int MHD_socket; 163 # define MHD_INVALID_SOCKET (-1) 164 # elif defined(MHD_WINSOCK_SOCKETS) 165 typedef SOCKET MHD_socket; 166 # define MHD_INVALID_SOCKET (INVALID_SOCKET) 167 # endif /* MHD_WINSOCK_SOCKETS */ 168 169 # define MHD_SOCKET_DEFINED 1 170 #endif /* ! MHD_SOCKET_DEFINED */ 171 172 #ifdef SOCK_CLOEXEC 173 # define SOCK_CLOEXEC_OR_ZERO SOCK_CLOEXEC 174 #else /* ! SOCK_CLOEXEC */ 175 # define SOCK_CLOEXEC_OR_ZERO 0 176 #endif /* ! SOCK_CLOEXEC */ 177 178 #ifdef HAVE_SOCK_NONBLOCK 179 # define SOCK_NONBLOCK_OR_ZERO SOCK_NONBLOCK 180 #else /* ! HAVE_SOCK_NONBLOCK */ 181 # define SOCK_NONBLOCK_OR_ZERO 0 182 #endif /* ! HAVE_SOCK_NONBLOCK */ 183 184 #ifdef SOCK_NOSIGPIPE 185 # define SOCK_NOSIGPIPE_OR_ZERO SOCK_NOSIGPIPE 186 #else /* ! HAVE_SOCK_NONBLOCK */ 187 # define SOCK_NOSIGPIPE_OR_ZERO 0 188 #endif /* ! HAVE_SOCK_NONBLOCK */ 189 190 #ifdef MSG_NOSIGNAL 191 # define MSG_NOSIGNAL_OR_ZERO MSG_NOSIGNAL 192 #else /* ! MSG_NOSIGNAL */ 193 # define MSG_NOSIGNAL_OR_ZERO 0 194 #endif /* ! MSG_NOSIGNAL */ 195 196 #if ! defined(SHUT_WR) && defined(SD_SEND) 197 # define SHUT_WR SD_SEND 198 #endif 199 #if ! defined(SHUT_RD) && defined(SD_RECEIVE) 200 # define SHUT_RD SD_RECEIVE 201 #endif 202 #if ! defined(SHUT_RDWR) && defined(SD_BOTH) 203 # define SHUT_RDWR SD_BOTH 204 #endif 205 206 #if defined(HAVE_ACCEPT4) && (defined(HAVE_SOCK_NONBLOCK) || \ 207 defined(SOCK_CLOEXEC) || defined(SOCK_NOSIGPIPE)) 208 # define USE_ACCEPT4 1 209 #endif 210 211 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ 212 defined(__OpenBSD__) || defined(__NetBSD__) || \ 213 defined(MHD_WINSOCK_SOCKETS) || defined(__MACH__) || defined(__sun) || \ 214 defined(SOMEBSD) 215 /* Most of OSes inherit nonblocking setting from the listen socket */ 216 #define MHD_ACCEPT_INHERIT_NONBLOCK 1 217 #endif 218 219 #if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC) 220 # define USE_EPOLL_CREATE1 1 221 #endif /* HAVE_EPOLL_CREATE1 && EPOLL_CLOEXEC */ 222 223 #ifdef TCP_FASTOPEN 224 /** 225 * Default TCP fastopen queue size. 226 */ 227 #define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10 228 #endif 229 230 231 #if defined(TCP_CORK) 232 /** 233 * Value of TCP_CORK or TCP_NOPUSH 234 */ 235 #define MHD_TCP_CORK_NOPUSH TCP_CORK 236 #elif defined(TCP_NOPUSH) 237 /** 238 * Value of TCP_CORK or TCP_NOPUSH 239 */ 240 #define MHD_TCP_CORK_NOPUSH TCP_NOPUSH 241 #endif /* TCP_NOPUSH */ 242 243 244 #ifdef MHD_TCP_CORK_NOPUSH 245 #ifdef __linux__ 246 /** 247 * Indicate that reset of TCP_CORK / TCP_NOPUSH push data to the network 248 */ 249 #define _MHD_CORK_RESET_PUSH_DATA 1 250 /** 251 * Indicate that reset of TCP_CORK / TCP_NOPUSH push data to the network 252 * even if TCP_CORK/TCP_NOPUSH was in switched off state. 253 */ 254 #define _MHD_CORK_RESET_PUSH_DATA_ALWAYS 1 255 #endif /* __linux__ */ 256 #if (defined(__FreeBSD__) && \ 257 ((__FreeBSD__ + 0) >= 5 || (__FreeBSD_version + 0) >= 450000)) || \ 258 (defined(__FreeBSD_kernel_version) && \ 259 (__FreeBSD_kernel_version + 0) >= 450000) 260 /* FreeBSD pushes data to the network with reset of TCP_NOPUSH 261 * starting from version 4.5. */ 262 /** 263 * Indicate that reset of TCP_CORK / TCP_NOPUSH push data to the network 264 */ 265 #define _MHD_CORK_RESET_PUSH_DATA 1 266 #endif /* __FreeBSD_version >= 450000 */ 267 #ifdef __OpenBSD__ 268 /* OpenBSD took implementation from FreeBSD */ 269 /** 270 * Indicate that reset of TCP_CORK / TCP_NOPUSH push data to the network 271 */ 272 #define _MHD_CORK_RESET_PUSH_DATA 1 273 #endif /* __OpenBSD__ */ 274 #endif /* MHD_TCP_CORK_NOPUSH */ 275 276 #ifdef __linux__ 277 /** 278 * Indicate that set of TCP_NODELAY push data to the network 279 */ 280 #define _MHD_NODELAY_SET_PUSH_DATA 1 281 /** 282 * Indicate that set of TCP_NODELAY push data to the network even 283 * if TCP_DELAY was already set and regardless of TCP_CORK / TCP_NOPUSH state 284 */ 285 #define _MHD_NODELAY_SET_PUSH_DATA_ALWAYS 1 286 #endif /* __linux__ */ 287 288 #ifdef MSG_MORE 289 #ifdef __linux__ 290 /* MSG_MORE signal kernel to buffer outbond data and works like 291 * TCP_CORK per call without actually setting TCP_CORK value. 292 * It's known to work on Linux. Add more OSes if they are compatible. */ 293 /** 294 * Indicate MSG_MORE is usable for buffered send(). 295 */ 296 #define MHD_USE_MSG_MORE 1 297 #endif /* __linux__ */ 298 #endif /* MSG_MORE */ 299 300 301 /** 302 * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt() 303 */ 304 #ifdef MHD_POSIX_SOCKETS 305 typedef int MHD_SCKT_OPT_BOOL_; 306 #else /* MHD_WINSOCK_SOCKETS */ 307 typedef BOOL MHD_SCKT_OPT_BOOL_; 308 #endif /* MHD_WINSOCK_SOCKETS */ 309 310 /** 311 * MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv 312 * functions 313 */ 314 #if ! defined(MHD_WINSOCK_SOCKETS) 315 typedef size_t MHD_SCKT_SEND_SIZE_; 316 #else 317 typedef int MHD_SCKT_SEND_SIZE_; 318 #endif 319 320 /** 321 * MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value. 322 */ 323 #if ! defined(MHD_WINSOCK_SOCKETS) 324 # define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX 325 #else 326 # define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX 327 #endif 328 329 /** 330 * MHD_socket_close_(fd) close any FDs (non-W32) / close only socket 331 * FDs (W32). Note that on HP-UNIX, this function may leak the FD if 332 * errno is set to EINTR. Do not use HP-UNIX. 333 * 334 * @param fd descriptor to close 335 * @return boolean true on success (error codes like EINTR and EIO are 336 * counted as success, only EBADF counts as an error!), 337 * boolean false otherwise. 338 */ 339 #if ! defined(MHD_WINSOCK_SOCKETS) 340 # define MHD_socket_close_(fd) ((0 == close ((fd))) || (EBADF != errno)) 341 #else 342 # define MHD_socket_close_(fd) (0 == closesocket ((fd))) 343 #endif 344 345 /** 346 * MHD_socket_close_chk_(fd) close socket and abort execution 347 * if error is detected. 348 * @param fd socket to close 349 */ 350 #define MHD_socket_close_chk_(fd) do { \ 351 if (! MHD_socket_close_ (fd)) \ 352 MHD_PANIC (_ ("Close socket failed.\n")); \ 353 } while (0) 354 355 356 /** 357 * MHD_send4_ is a wrapper for system's send() 358 * @param s the socket to use 359 * @param b the buffer with data to send 360 * @param l the length of data in @a b 361 * @param f the additional flags 362 * @return ssize_t type value 363 */ 364 #define MHD_send4_(s,b,l,f) \ 365 ((ssize_t) send ((s),(const void*) (b),(MHD_SCKT_SEND_SIZE_) (l), \ 366 ((MSG_NOSIGNAL_OR_ZERO) | (f)))) 367 368 369 /** 370 * MHD_send_ is a simple wrapper for system's send() 371 * @param s the socket to use 372 * @param b the buffer with data to send 373 * @param l the length of data in @a b 374 * @return ssize_t type value 375 */ 376 #define MHD_send_(s,b,l) MHD_send4_((s),(b),(l), 0) 377 378 379 /** 380 * MHD_recv_ is wrapper for system's recv() 381 * @param s the socket to use 382 * @param b the buffer for data to receive 383 * @param l the length of @a b 384 * @return ssize_t type value 385 */ 386 #define MHD_recv_(s,b,l) \ 387 ((ssize_t) recv ((s),(void*) (b),(MHD_SCKT_SEND_SIZE_) (l), 0)) 388 389 390 /** 391 * Check whether FD can be added to fd_set with specified FD_SETSIZE. 392 * @param fd the fd to check 393 * @param pset the pointer to fd_set to check or NULL to check 394 * whether FD can be used with fd_sets. 395 * @param setsize the value of FD_SETSIZE. 396 * @return boolean true if FD can be added to fd_set, 397 * boolean false otherwise. 398 */ 399 #if defined(MHD_POSIX_SOCKETS) 400 # define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) \ 401 ((fd) < ((MHD_socket) (setsize))) 402 #elif defined(MHD_WINSOCK_SOCKETS) 403 # define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) \ 404 ( ((void*) (pset)== (void*) 0) || \ 405 (((fd_set*) (pset))->fd_count < ((unsigned) setsize)) || \ 406 (FD_ISSET ((fd), (pset))) ) 407 #endif 408 409 /** 410 * Check whether FD can be added to fd_set with current FD_SETSIZE. 411 * @param fd the fd to check 412 * @param pset the pointer to fd_set to check or NULL to check 413 * whether FD can be used with fd_sets. 414 * @return boolean true if FD can be added to fd_set, 415 * boolean false otherwise. 416 */ 417 #define MHD_SCKT_FD_FITS_FDSET_(fd,pset) \ 418 MHD_SCKT_FD_FITS_FDSET_SETSIZE_ ((fd), (pset), FD_SETSIZE) 419 420 /** 421 * Add FD to fd_set with specified FD_SETSIZE. 422 * @param fd the fd to add 423 * @param pset the valid pointer to fd_set. 424 * @param setsize the value of FD_SETSIZE. 425 * @note To work on W32 with value of FD_SETSIZE different from currently defined value, 426 * system definition of FD_SET() is not used. 427 */ 428 #if defined(MHD_POSIX_SOCKETS) 429 # define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \ 430 FD_SET ((fd), (pset)) 431 #elif defined(MHD_WINSOCK_SOCKETS) 432 # define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \ 433 do { \ 434 u_int _i_ = 0; \ 435 fd_set*const _s_ = (fd_set*) (pset); \ 436 while ((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array [_i_])) {++_i_;} \ 437 if ((_i_ == _s_->fd_count)) {_s_->fd_array [_s_->fd_count ++] = (fd);} \ 438 } while (0) 439 #endif 440 441 /* MHD_SYS_select_ is wrapper macro for system select() function */ 442 #if ! defined(MHD_WINSOCK_SOCKETS) 443 # define MHD_SYS_select_(n,r,w,e,t) select ((n),(r),(w),(e),(t)) 444 #else 445 # define MHD_SYS_select_(n,r,w,e,t) \ 446 ( ( (((void*) (r) == (void*) 0) || ((fd_set*) (r))->fd_count == 0) && \ 447 (((void*) (w) == (void*) 0) || ((fd_set*) (w))->fd_count == 0) && \ 448 (((void*) (e) == (void*) 0) || ((fd_set*) (e))->fd_count == 0) ) ? \ 449 ( ((void*) (t) == (void*) 0) ? 0 : \ 450 (Sleep ((DWORD)((struct timeval*) (t))->tv_sec * 1000 \ 451 + (DWORD)((struct timeval*) (t))->tv_usec / 1000), 0) ) : \ 452 (select ((int) 0,(r),(w),(e),(t))) ) 453 #endif 454 455 #if defined(HAVE_POLL) 456 /* MHD_sys_poll_ is wrapper macro for system poll() function */ 457 # if ! defined(MHD_WINSOCK_SOCKETS) 458 # define MHD_sys_poll_ poll 459 # else /* MHD_WINSOCK_SOCKETS */ 460 # define MHD_sys_poll_ WSAPoll 461 # endif /* MHD_WINSOCK_SOCKETS */ 462 463 # ifdef POLLPRI 464 # define MHD_POLLPRI_OR_ZERO POLLPRI 465 # else /* ! POLLPRI */ 466 # define MHD_POLLPRI_OR_ZERO 0 467 # endif /* ! POLLPRI */ 468 # ifdef POLLRDBAND 469 # define MHD_POLLRDBAND_OR_ZERO POLLRDBAND 470 # else /* ! POLLRDBAND */ 471 # define MHD_POLLRDBAND_OR_ZERO 0 472 # endif /* ! POLLRDBAND */ 473 # ifdef POLLNVAL 474 # define MHD_POLLNVAL_OR_ZERO POLLNVAL 475 # else /* ! POLLNVAL */ 476 # define MHD_POLLNVAL_OR_ZERO 0 477 # endif /* ! POLLNVAL */ 478 479 /* MHD_POLL_EVENTS_ERR_DISC is 'events' mask for errors and disconnect. 480 * Note: Out-of-band data is treated as error. */ 481 # if defined(_WIN32) && ! defined(__CYGWIN__) 482 # define MHD_POLL_EVENTS_ERR_DISC POLLRDBAND 483 # elif defined(__linux__) 484 # define MHD_POLL_EVENTS_ERR_DISC POLLPRI 485 # else /* ! __linux__ */ 486 # define MHD_POLL_EVENTS_ERR_DISC \ 487 (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO) 488 # endif /* ! __linux__ */ 489 /* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect. 490 * Note: Out-of-band data is treated as error. */ 491 # define MHD_POLL_REVENTS_ERR_DISC \ 492 (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \ 493 | POLLERR | POLLHUP) 494 /* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors. 495 * Note: Out-of-band data is treated as error. */ 496 # define MHD_POLL_REVENTS_ERRROR \ 497 (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO \ 498 | POLLERR) 499 #endif /* HAVE_POLL */ 500 501 #define MHD_SCKT_MISSING_ERR_CODE_ 31450 502 503 #if defined(MHD_POSIX_SOCKETS) 504 # if defined(EAGAIN) 505 # define MHD_SCKT_EAGAIN_ EAGAIN 506 # elif defined(EWOULDBLOCK) 507 # define MHD_SCKT_EAGAIN_ EWOULDBLOCK 508 # else /* !EAGAIN && !EWOULDBLOCK */ 509 # define MHD_SCKT_EAGAIN_ MHD_SCKT_MISSING_ERR_CODE_ 510 # endif /* !EAGAIN && !EWOULDBLOCK */ 511 # if defined(EWOULDBLOCK) 512 # define MHD_SCKT_EWOULDBLOCK_ EWOULDBLOCK 513 # elif defined(EAGAIN) 514 # define MHD_SCKT_EWOULDBLOCK_ EAGAIN 515 # else /* !EWOULDBLOCK && !EAGAIN */ 516 # define MHD_SCKT_EWOULDBLOCK_ MHD_SCKT_MISSING_ERR_CODE_ 517 # endif /* !EWOULDBLOCK && !EAGAIN */ 518 # ifdef EINTR 519 # define MHD_SCKT_EINTR_ EINTR 520 # else /* ! EINTR */ 521 # define MHD_SCKT_EINTR_ MHD_SCKT_MISSING_ERR_CODE_ 522 # endif /* ! EINTR */ 523 # ifdef ECONNRESET 524 # define MHD_SCKT_ECONNRESET_ ECONNRESET 525 # else /* ! ECONNRESET */ 526 # define MHD_SCKT_ECONNRESET_ MHD_SCKT_MISSING_ERR_CODE_ 527 # endif /* ! ECONNRESET */ 528 # ifdef ECONNABORTED 529 # define MHD_SCKT_ECONNABORTED_ ECONNABORTED 530 # else /* ! ECONNABORTED */ 531 # define MHD_SCKT_ECONNABORTED_ MHD_SCKT_MISSING_ERR_CODE_ 532 # endif /* ! ECONNABORTED */ 533 # ifdef ENOTCONN 534 # define MHD_SCKT_ENOTCONN_ ENOTCONN 535 # else /* ! ENOTCONN */ 536 # define MHD_SCKT_ENOTCONN_ MHD_SCKT_MISSING_ERR_CODE_ 537 # endif /* ! ENOTCONN */ 538 # ifdef EMFILE 539 # define MHD_SCKT_EMFILE_ EMFILE 540 # else /* ! EMFILE */ 541 # define MHD_SCKT_EMFILE_ MHD_SCKT_MISSING_ERR_CODE_ 542 # endif /* ! EMFILE */ 543 # ifdef ENFILE 544 # define MHD_SCKT_ENFILE_ ENFILE 545 # else /* ! ENFILE */ 546 # define MHD_SCKT_ENFILE_ MHD_SCKT_MISSING_ERR_CODE_ 547 # endif /* ! ENFILE */ 548 # ifdef ENOMEM 549 # define MHD_SCKT_ENOMEM_ ENOMEM 550 # else /* ! ENOMEM */ 551 # define MHD_SCKT_ENOMEM_ MHD_SCKT_MISSING_ERR_CODE_ 552 # endif /* ! ENOMEM */ 553 # ifdef ENOBUFS 554 # define MHD_SCKT_ENOBUFS_ ENOBUFS 555 # else /* ! ENOBUFS */ 556 # define MHD_SCKT_ENOBUFS_ MHD_SCKT_MISSING_ERR_CODE_ 557 # endif /* ! ENOBUFS */ 558 # ifdef EBADF 559 # define MHD_SCKT_EBADF_ EBADF 560 # else /* ! EBADF */ 561 # define MHD_SCKT_EBADF_ MHD_SCKT_MISSING_ERR_CODE_ 562 # endif /* ! EBADF */ 563 # ifdef ENOTSOCK 564 # define MHD_SCKT_ENOTSOCK_ ENOTSOCK 565 # else /* ! ENOTSOCK */ 566 # define MHD_SCKT_ENOTSOCK_ MHD_SCKT_MISSING_ERR_CODE_ 567 # endif /* ! ENOTSOCK */ 568 # ifdef EINVAL 569 # define MHD_SCKT_EINVAL_ EINVAL 570 # else /* ! EINVAL */ 571 # define MHD_SCKT_EINVAL_ MHD_SCKT_MISSING_ERR_CODE_ 572 # endif /* ! EINVAL */ 573 # ifdef EPIPE 574 # define MHD_SCKT_EPIPE_ EPIPE 575 # else /* ! EPIPE */ 576 # define MHD_SCKT_EPIPE_ MHD_SCKT_MISSING_ERR_CODE_ 577 # endif /* ! EPIPE */ 578 # ifdef EFAULT 579 # define MHD_SCKT_EFAUL_ EFAULT 580 # else /* ! EFAULT */ 581 # define MHD_SCKT_EFAUL_ MHD_SCKT_MISSING_ERR_CODE_ 582 # endif /* ! EFAULT */ 583 # ifdef ENOSYS 584 # define MHD_SCKT_ENOSYS_ ENOSYS 585 # else /* ! ENOSYS */ 586 # define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_ 587 # endif /* ! ENOSYS */ 588 # ifdef ENOPROTOOPT 589 # define MHD_SCKT_ENOPROTOOPT_ ENOPROTOOPT 590 # else /* ! ENOPROTOOPT */ 591 # define MHD_SCKT_ENOPROTOOPT_ MHD_SCKT_MISSING_ERR_CODE_ 592 # endif /* ! ENOPROTOOPT */ 593 # ifdef ENOTSUP 594 # define MHD_SCKT_ENOTSUP_ ENOTSUP 595 # else /* ! ENOTSUP */ 596 # define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_ 597 # endif /* ! ENOTSUP */ 598 # ifdef EOPNOTSUPP 599 # define MHD_SCKT_EOPNOTSUPP_ EOPNOTSUPP 600 # else /* ! EOPNOTSUPP */ 601 # define MHD_SCKT_EOPNOTSUPP_ MHD_SCKT_MISSING_ERR_CODE_ 602 # endif /* ! EOPNOTSUPP */ 603 # ifdef EACCES 604 # define MHD_SCKT_EACCESS_ EACCES 605 # else /* ! EACCES */ 606 # define MHD_SCKT_EACCESS_ MHD_SCKT_MISSING_ERR_CODE_ 607 # endif /* ! EACCES */ 608 # ifdef ENETDOWN 609 # define MHD_SCKT_ENETDOWN_ ENETDOWN 610 # else /* ! ENETDOWN */ 611 # define MHD_SCKT_ENETDOWN_ MHD_SCKT_MISSING_ERR_CODE_ 612 # endif /* ! ENETDOWN */ 613 # ifdef EALREADY 614 # define MHD_SCKT_EALREADY_ EALREADY 615 # else /* ! EALREADY */ 616 # define MHD_SCKT_EALREADY_ MHD_SCKT_MISSING_ERR_CODE_ 617 # endif /* ! EALREADY */ 618 # ifdef EINPROGRESS 619 # define MHD_SCKT_EINPROGRESS_ EINPROGRESS 620 # else /* ! EINPROGRESS */ 621 # define MHD_SCKT_EINPROGRESS_ MHD_SCKT_MISSING_ERR_CODE_ 622 # endif /* ! EINPROGRESS */ 623 # ifdef EISCONN 624 # define MHD_SCKT_EISCONN_ EISCONN 625 # else /* ! EISCONN */ 626 # define MHD_SCKT_EISCONN_ MHD_SCKT_MISSING_ERR_CODE_ 627 # endif /* ! EISCONN */ 628 #elif defined(MHD_WINSOCK_SOCKETS) 629 # define MHD_SCKT_EAGAIN_ WSAEWOULDBLOCK 630 # define MHD_SCKT_EWOULDBLOCK_ WSAEWOULDBLOCK 631 # define MHD_SCKT_EINTR_ WSAEINTR 632 # define MHD_SCKT_ECONNRESET_ WSAECONNRESET 633 # define MHD_SCKT_ECONNABORTED_ WSAECONNABORTED 634 # define MHD_SCKT_ENOTCONN_ WSAENOTCONN 635 # define MHD_SCKT_EMFILE_ WSAEMFILE 636 # define MHD_SCKT_ENFILE_ MHD_SCKT_MISSING_ERR_CODE_ 637 # define MHD_SCKT_ENOMEM_ MHD_SCKT_MISSING_ERR_CODE_ 638 # define MHD_SCKT_ENOBUFS_ WSAENOBUFS 639 # define MHD_SCKT_EBADF_ WSAEBADF 640 # define MHD_SCKT_ENOTSOCK_ WSAENOTSOCK 641 # define MHD_SCKT_EINVAL_ WSAEINVAL 642 # define MHD_SCKT_EPIPE_ WSAESHUTDOWN 643 # define MHD_SCKT_EFAUL_ WSAEFAULT 644 # define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_ 645 # define MHD_SCKT_ENOPROTOOPT_ WSAENOPROTOOPT 646 # define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_ 647 # define MHD_SCKT_EOPNOTSUPP_ WSAEOPNOTSUPP 648 # define MHD_SCKT_EACCESS_ WSAEACCES 649 # define MHD_SCKT_ENETDOWN_ WSAENETDOWN 650 # define MHD_SCKT_EALREADY_ WSAEALREADY 651 # define MHD_SCKT_EINPROGRESS_ WSAEINPROGRESS 652 # define MHD_SCKT_EISCONN_ WSAEISCONN 653 #endif 654 655 /** 656 * MHD_socket_error_ return system native error code for last socket error. 657 * @return system error code for last socket error. 658 */ 659 #if defined(MHD_POSIX_SOCKETS) 660 # define MHD_socket_get_error_() (errno) 661 #elif defined(MHD_WINSOCK_SOCKETS) 662 # define MHD_socket_get_error_() WSAGetLastError () 663 #endif 664 665 #ifdef MHD_WINSOCK_SOCKETS 666 /* POSIX-W32 sockets compatibility functions */ 667 668 /** 669 * Return pointer to string description of specified WinSock error 670 * @param err the WinSock error code. 671 * @return pointer to string description of specified WinSock error. 672 */ 673 const char *MHD_W32_strerror_winsock_ (int err); 674 675 #endif /* MHD_WINSOCK_SOCKETS */ 676 677 /* MHD_socket_last_strerr_ is description string of specified socket error code */ 678 #if defined(MHD_POSIX_SOCKETS) 679 # define MHD_socket_strerr_(err) strerror ((err)) 680 #elif defined(MHD_WINSOCK_SOCKETS) 681 # define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_ ((err)) 682 #endif 683 684 /* MHD_socket_last_strerr_ is description string of last errno (non-W32) / 685 * description string of last socket error (W32) */ 686 #define MHD_socket_last_strerr_() MHD_socket_strerr_ (MHD_socket_get_error_ ()) 687 688 /** 689 * MHD_socket_fset_error_() set socket system native error code. 690 */ 691 #if defined(MHD_POSIX_SOCKETS) 692 # define MHD_socket_fset_error_(err) (errno = (err)) 693 #elif defined(MHD_WINSOCK_SOCKETS) 694 # define MHD_socket_fset_error_(err) (WSASetLastError ((err))) 695 #endif 696 697 /** 698 * MHD_socket_try_set_error_() set socket system native error code if 699 * specified code is defined on system. 700 * @return non-zero if specified @a err code is defined on system 701 * and error was set; 702 * zero if specified @a err code is not defined on system 703 * and error was not set. 704 */ 705 #define MHD_socket_try_set_error_(err) \ 706 ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \ 707 (MHD_socket_fset_error_ ((err)), ! 0) : 0) 708 709 /** 710 * MHD_socket_set_error_() set socket system native error code to 711 * specified code or replacement code if specified code is not 712 * defined on system. 713 */ 714 #if defined(MHD_POSIX_SOCKETS) 715 # if defined(ENOSYS) 716 # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 717 (errno = ENOSYS) : (errno = (err)) ) 718 # elif defined(EOPNOTSUPP) 719 # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 720 (errno = EOPNOTSUPP) : (errno = \ 721 (err)) ) 722 # elif defined(EFAULT) 723 # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 724 (errno = EFAULT) : (errno = (err)) ) 725 # elif defined(EINVAL) 726 # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 727 (errno = EINVAL) : (errno = (err)) ) 728 # else /* !EOPNOTSUPP && !EFAULT && !EINVAL */ 729 # warning \ 730 No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system. 731 # define MHD_socket_set_error_(err) (errno = (err)) 732 # endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/ 733 #elif defined(MHD_WINSOCK_SOCKETS) 734 # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ 735 (WSASetLastError ((WSAEOPNOTSUPP))) : \ 736 (WSASetLastError ((err))) ) 737 #endif 738 739 /** 740 * Check whether given socket error is equal to specified system 741 * native MHD_SCKT_E*_ code. 742 * If platform don't have specific error code, result is 743 * always boolean false. 744 * @return boolean true if @a code is real error code and 745 * @a err equals to MHD_SCKT_E*_ @a code; 746 * boolean false otherwise 747 */ 748 #define MHD_SCKT_ERR_IS_(err,code) \ 749 ( (MHD_SCKT_MISSING_ERR_CODE_ != (code)) && ((code) == (err)) ) 750 751 /** 752 * Check whether last socket error is equal to specified system 753 * native MHD_SCKT_E*_ code. 754 * If platform don't have specific error code, result is 755 * always boolean false. 756 * @return boolean true if @a code is real error code and 757 * last socket error equals to MHD_SCKT_E*_ @a code; 758 * boolean false otherwise 759 */ 760 #define MHD_SCKT_LAST_ERR_IS_(code) \ 761 MHD_SCKT_ERR_IS_ (MHD_socket_get_error_ (), (code)) 762 763 /* Specific error code checks */ 764 765 /** 766 * Check whether given socket error is equal to system's 767 * socket error codes for EINTR. 768 * @return boolean true if @a err is equal to sockets' EINTR code; 769 * boolean false otherwise. 770 */ 771 #define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EINTR_) 772 773 /** 774 * Check whether given socket error is equal to system's 775 * socket error codes for EAGAIN or EWOULDBLOCK. 776 * @return boolean true if @a err is equal to sockets' EAGAIN or EWOULDBLOCK codes; 777 * boolean false otherwise. 778 */ 779 #if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_ 780 # define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_ ((err),MHD_SCKT_EAGAIN_) 781 #else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ 782 # define MHD_SCKT_ERR_IS_EAGAIN_(err) \ 783 ( MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_EAGAIN_) || \ 784 MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_EWOULDBLOCK_) ) 785 #endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ 786 787 /** 788 * Check whether given socket error is any kind of "low resource" error. 789 * @return boolean true if @a err is any kind of "low resource" error, 790 * boolean false otherwise. 791 */ 792 #define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) \ 793 ( MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_EMFILE_) || \ 794 MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_ENFILE_) || \ 795 MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_ENOMEM_) || \ 796 MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_ENOBUFS_) ) 797 798 /** 799 * Check whether is given socket error is type of "incoming connection 800 * was disconnected before 'accept()' is called". 801 * @return boolean true is @a err match described socket error code, 802 * boolean false otherwise. 803 */ 804 #if defined(MHD_POSIX_SOCKETS) 805 # define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) \ 806 MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_ECONNABORTED_) 807 #elif defined(MHD_WINSOCK_SOCKETS) 808 # define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) \ 809 MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_ECONNRESET_) 810 #endif 811 812 /** 813 * Check whether is given socket error is type of "connection was terminated 814 * by remote side". 815 * @return boolean true is @a err match described socket error code, 816 * boolean false otherwise. 817 */ 818 #define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) \ 819 ( MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_ECONNRESET_) || \ 820 MHD_SCKT_ERR_IS_ ((err), MHD_SCKT_ECONNABORTED_) ) 821 822 /* Specific error code set */ 823 824 /** 825 * Set socket's error code to ENOMEM or equivalent if ENOMEM is not 826 * available on platform. 827 */ 828 #if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_ 829 # define MHD_socket_set_error_to_ENOMEM() \ 830 MHD_socket_set_error_ (MHD_SCKT_ENOMEM_) 831 #elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_ 832 # define MHD_socket_set_error_to_ENOMEM() \ 833 MHD_socket_set_error_ (MHD_SCKT_ENOBUFS_) 834 #else 835 # warning \ 836 No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system. 837 # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_ ( \ 838 MHD_SCKT_ENOMEM_) 839 #endif 840 841 /* Socket functions */ 842 843 #if defined(AF_LOCAL) 844 # define MHD_SCKT_LOCAL AF_LOCAL 845 #elif defined(AF_UNIX) 846 # define MHD_SCKT_LOCAL AF_UNIX 847 #endif /* AF_UNIX */ 848 849 #if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL) 850 # define MHD_socket_pair_(fdarr) \ 851 (! socketpair (MHD_SCKT_LOCAL, SOCK_STREAM, 0, (fdarr))) 852 # if defined(HAVE_SOCK_NONBLOCK) 853 # define MHD_socket_pair_nblk_(fdarr) \ 854 (! socketpair (MHD_SCKT_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, (fdarr))) 855 # endif /* HAVE_SOCK_NONBLOCK*/ 856 #elif defined(MHD_WINSOCK_SOCKETS) 857 /** 858 * Create pair of mutually connected TCP/IP sockets on loopback address 859 * @param sockets_pair array to receive resulted sockets 860 * @param non_blk if set to non-zero value, sockets created in non-blocking mode 861 * otherwise sockets will be in blocking mode 862 * @return non-zero if succeeded, zero otherwise 863 */ 864 int MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk); 865 866 # define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_ ((fdarr), 0) 867 # define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_ ((fdarr), 1) 868 #endif 869 870 /** 871 * Add @a fd to the @a set. If @a fd is 872 * greater than @a max_fd, set @a max_fd to @a fd. 873 * 874 * @param fd file descriptor to add to the @a set 875 * @param set set to modify 876 * @param max_fd maximum value to potentially update 877 * @param fd_setsize value of FD_SETSIZE 878 * @return non-zero if succeeded, zero otherwise 879 */ 880 int 881 MHD_add_to_fd_set_ (MHD_socket fd, 882 fd_set *set, 883 MHD_socket *max_fd, 884 int fd_setsize); 885 886 887 /** 888 * Change socket options to be non-blocking. 889 * 890 * @param sock socket to manipulate 891 * @return non-zero if succeeded, zero otherwise 892 */ 893 int 894 MHD_socket_nonblocking_ (MHD_socket sock); 895 896 897 /** 898 * Disable Nagle's algorithm on @a sock. This is what we do by default for 899 * all TCP sockets in MHD, unless the platform does not support the MSG_MORE 900 * or MSG_CORK or MSG_NOPUSH options. 901 * 902 * @param sock socket to manipulate 903 * @param on value to use 904 * @return 0 on success 905 */ 906 int 907 MHD_socket_set_nodelay_ (MHD_socket sock, 908 bool on); 909 910 /** 911 * Change socket options to be non-inheritable. 912 * 913 * @param sock socket to manipulate 914 * @return non-zero if succeeded, zero otherwise 915 * @warning Does not set socket error on W32. 916 */ 917 int 918 MHD_socket_noninheritable_ (MHD_socket sock); 919 920 921 #if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) 922 static const int _MHD_socket_int_one = 1; 923 /** 924 * Change socket options to no signal on remote disconnect. 925 * 926 * @param sock socket to manipulate 927 * @return non-zero if succeeded, zero otherwise 928 */ 929 #define MHD_socket_nosignal_(sock) \ 930 (! setsockopt ((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one, \ 931 sizeof(_MHD_socket_int_one))) 932 #endif /* SOL_SOCKET && SO_NOSIGPIPE */ 933 934 935 #if defined(MHD_socket_nosignal_) || defined(MSG_NOSIGNAL) 936 /** 937 * Indicate that SIGPIPE can be suppressed by MHD for normal send() by flags 938 * or socket options. 939 * If this macro is undefined, MHD cannot suppress SIGPIPE for socket functions 940 * so sendfile() or writev() calls are avoided in application threads. 941 */ 942 #define MHD_SEND_SPIPE_SUPPRESS_POSSIBLE 1 943 #endif /* MHD_WINSOCK_SOCKETS || MHD_socket_nosignal_ || MSG_NOSIGNAL */ 944 945 #if ! defined(MHD_WINSOCK_SOCKETS) 946 /** 947 * Indicate that suppression of SIGPIPE is required. 948 */ 949 #define MHD_SEND_SPIPE_SUPPRESS_NEEDED 1 950 #endif 951 952 /** 953 * Create a listen socket, with noninheritable flag if possible. 954 * 955 * @param pf protocol family to use 956 * @return created socket or MHD_INVALID_SOCKET in case of errors 957 */ 958 MHD_socket 959 MHD_socket_create_listen_ (int pf); 960 961 962 #endif /* ! MHD_SOCKETS_H */