src/socket_wrapper.c: make use of uid_wrapper_syscall_{valid,va}()
[socket_wrapper.git] / src / socket_wrapper.c
1 /*
2  * BSD 3-Clause License
3  *
4  * Copyright (c) 2005-2008, Jelmer Vernooij <jelmer@samba.org>
5  * Copyright (c) 2006-2021, Stefan Metzmacher <metze@samba.org>
6  * Copyright (c) 2013-2021, Andreas Schneider <asn@samba.org>
7  * Copyright (c) 2014-2017, Michael Adam <obnox@samba.org>
8  * Copyright (c) 2016-2018, Anoop C S <anoopcs@redhat.com>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * 3. Neither the name of the author nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 /*
40    Socket wrapper library. Passes all socket communication over
41    unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
42    is set.
43 */
44
45 #include "config.h"
46
47 #include <sys/types.h>
48 #include <sys/time.h>
49 #include <sys/stat.h>
50 #ifdef HAVE_SYS_SYSCALL_H
51 #include <sys/syscall.h>
52 #endif
53 #ifdef HAVE_SYSCALL_H
54 #include <syscall.h>
55 #endif
56 #include <sys/socket.h>
57 #include <sys/ioctl.h>
58 #ifdef HAVE_SYS_FILIO_H
59 #include <sys/filio.h>
60 #endif
61 #ifdef HAVE_SYS_SIGNALFD_H
62 #include <sys/signalfd.h>
63 #endif
64 #ifdef HAVE_SYS_EVENTFD_H
65 #include <sys/eventfd.h>
66 #endif
67 #ifdef HAVE_SYS_TIMERFD_H
68 #include <sys/timerfd.h>
69 #endif
70 #include <sys/uio.h>
71 #include <errno.h>
72 #include <sys/un.h>
73 #include <netinet/in.h>
74 #include <netinet/tcp.h>
75 #ifdef HAVE_NETINET_TCP_FSM_H
76 #include <netinet/tcp_fsm.h>
77 #endif
78 #include <arpa/inet.h>
79 #include <fcntl.h>
80 #include <stdlib.h>
81 #include <string.h>
82 #include <stdio.h>
83 #include <stdint.h>
84 #include <stdarg.h>
85 #include <stdbool.h>
86 #include <unistd.h>
87 #ifdef HAVE_GNU_LIB_NAMES_H
88 #include <gnu/lib-names.h>
89 #endif
90 #ifdef HAVE_RPC_RPC_H
91 #include <rpc/rpc.h>
92 #endif
93 #include <pthread.h>
94
95 #include "socket_wrapper.h"
96
97 enum swrap_dbglvl_e {
98         SWRAP_LOG_ERROR = 0,
99         SWRAP_LOG_WARN,
100         SWRAP_LOG_DEBUG,
101         SWRAP_LOG_TRACE
102 };
103
104 /* GCC have printf type attribute check. */
105 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
106 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
107 #else
108 #define PRINTF_ATTRIBUTE(a,b)
109 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
110
111 #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
112 #define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
113 #else
114 #define CONSTRUCTOR_ATTRIBUTE
115 #endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
116
117 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
118 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
119 #else
120 #define DESTRUCTOR_ATTRIBUTE
121 #endif
122
123 #ifndef FALL_THROUGH
124 # ifdef HAVE_FALLTHROUGH_ATTRIBUTE
125 #  define FALL_THROUGH __attribute__ ((fallthrough))
126 # else /* HAVE_FALLTHROUGH_ATTRIBUTE */
127 #  define FALL_THROUGH ((void)0)
128 # endif /* HAVE_FALLTHROUGH_ATTRIBUTE */
129 #endif /* FALL_THROUGH */
130
131 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
132 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address))
133 #else
134 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
135 #endif
136
137 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
138 # define SWRAP_THREAD __thread
139 #else
140 # define SWRAP_THREAD
141 #endif
142
143 #ifndef MIN
144 #define MIN(a,b) ((a)<(b)?(a):(b))
145 #endif
146
147 #ifndef ZERO_STRUCT
148 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
149 #endif
150
151 #ifndef ZERO_STRUCTP
152 #define ZERO_STRUCTP(x) do { \
153                 if ((x) != NULL) \
154                         memset((char *)(x), 0, sizeof(*(x))); \
155         } while(0)
156 #endif
157
158 #ifndef SAFE_FREE
159 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
160 #endif
161
162 #ifndef discard_const
163 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
164 #endif
165
166 #ifndef discard_const_p
167 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
168 #endif
169
170 #define UNUSED(x) (void)(x)
171
172 #ifdef IPV6_PKTINFO
173 # ifndef IPV6_RECVPKTINFO
174 #  define IPV6_RECVPKTINFO IPV6_PKTINFO
175 # endif /* IPV6_RECVPKTINFO */
176 #endif /* IPV6_PKTINFO */
177
178 /*
179  * On BSD IP_PKTINFO has a different name because during
180  * the time when they implemented it, there was no RFC.
181  * The name for IPv6 is the same as on Linux.
182  */
183 #ifndef IP_PKTINFO
184 # ifdef IP_RECVDSTADDR
185 #  define IP_PKTINFO IP_RECVDSTADDR
186 # endif
187 #endif
188
189 #define socket_wrapper_init_mutex(m) \
190         _socket_wrapper_init_mutex(m, #m)
191
192 /* Add new global locks here please */
193 # define SWRAP_REINIT_ALL do { \
194         int ret; \
195         ret = socket_wrapper_init_mutex(&sockets_mutex); \
196         if (ret != 0) exit(-1); \
197         ret = socket_wrapper_init_mutex(&socket_reset_mutex); \
198         if (ret != 0) exit(-1); \
199         ret = socket_wrapper_init_mutex(&first_free_mutex); \
200         if (ret != 0) exit(-1); \
201         ret = socket_wrapper_init_mutex(&sockets_si_global); \
202         if (ret != 0) exit(-1); \
203         ret = socket_wrapper_init_mutex(&autobind_start_mutex); \
204         if (ret != 0) exit(-1); \
205         ret = socket_wrapper_init_mutex(&pcap_dump_mutex); \
206         if (ret != 0) exit(-1); \
207         ret = socket_wrapper_init_mutex(&mtu_update_mutex); \
208         if (ret != 0) exit(-1); \
209 } while(0)
210
211 # define SWRAP_LOCK_ALL do { \
212         swrap_mutex_lock(&sockets_mutex); \
213         swrap_mutex_lock(&socket_reset_mutex); \
214         swrap_mutex_lock(&first_free_mutex); \
215         swrap_mutex_lock(&sockets_si_global); \
216         swrap_mutex_lock(&autobind_start_mutex); \
217         swrap_mutex_lock(&pcap_dump_mutex); \
218         swrap_mutex_lock(&mtu_update_mutex); \
219 } while(0)
220
221 # define SWRAP_UNLOCK_ALL do { \
222         swrap_mutex_unlock(&mtu_update_mutex); \
223         swrap_mutex_unlock(&pcap_dump_mutex); \
224         swrap_mutex_unlock(&autobind_start_mutex); \
225         swrap_mutex_unlock(&sockets_si_global); \
226         swrap_mutex_unlock(&first_free_mutex); \
227         swrap_mutex_unlock(&socket_reset_mutex); \
228         swrap_mutex_unlock(&sockets_mutex); \
229 } while(0)
230
231 #define SOCKET_INFO_CONTAINER(si) \
232         (struct socket_info_container *)(si)
233
234 #define SWRAP_LOCK_SI(si) do { \
235         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
236         if (sic != NULL) { \
237                 swrap_mutex_lock(&sockets_si_global); \
238         } else { \
239                 abort(); \
240         } \
241 } while(0)
242
243 #define SWRAP_UNLOCK_SI(si) do { \
244         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
245         if (sic != NULL) { \
246                 swrap_mutex_unlock(&sockets_si_global); \
247         } else { \
248                 abort(); \
249         } \
250 } while(0)
251
252 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
253 #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
254 #else
255 #define swrapGetTimeOfDay(tval) gettimeofday(tval)
256 #endif
257
258 /* we need to use a very terse format here as IRIX 6.4 silently
259    truncates names to 16 chars, so if we use a longer name then we
260    can't tell which port a packet came from with recvfrom()
261
262    with this format we have 8 chars left for the directory name
263 */
264 #define SOCKET_FORMAT "%c%02X%04X"
265 #define SOCKET_TYPE_CHAR_TCP            'T'
266 #define SOCKET_TYPE_CHAR_UDP            'U'
267 #define SOCKET_TYPE_CHAR_TCP_V6         'X'
268 #define SOCKET_TYPE_CHAR_UDP_V6         'Y'
269
270 /*
271  * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to
272  * format PCAP capture files (as the caller will simply continue from here).
273  */
274 #define SOCKET_WRAPPER_MTU_DEFAULT 1500
275 #define SOCKET_WRAPPER_MTU_MIN     512
276 #define SOCKET_WRAPPER_MTU_MAX     32768
277
278 #define SOCKET_MAX_SOCKETS 1024
279
280 /*
281  * Maximum number of socket_info structures that can
282  * be used. Can be overriden by the environment variable
283  * SOCKET_WRAPPER_MAX_SOCKETS.
284  */
285 #define SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT 65535
286
287 #define SOCKET_WRAPPER_MAX_SOCKETS_LIMIT 262140
288
289 /* This limit is to avoid broadcast sendto() needing to stat too many
290  * files.  It may be raised (with a performance cost) to up to 254
291  * without changing the format above */
292 #define MAX_WRAPPED_INTERFACES 64
293
294 struct swrap_address {
295         socklen_t sa_socklen;
296         union {
297                 struct sockaddr s;
298                 struct sockaddr_in in;
299 #ifdef HAVE_IPV6
300                 struct sockaddr_in6 in6;
301 #endif
302                 struct sockaddr_un un;
303                 struct sockaddr_storage ss;
304         } sa;
305 };
306
307 static int first_free;
308
309 struct socket_info
310 {
311         /*
312          * Remember to update swrap_unix_scm_right_magic
313          * on any change.
314          */
315
316         int family;
317         int type;
318         int protocol;
319         int bound;
320         int bcast;
321         int is_server;
322         int connected;
323         int defer_connect;
324         int pktinfo;
325         int tcp_nodelay;
326         int listening;
327         int fd_passed;
328
329         /* The unix path so we can unlink it on close() */
330         struct sockaddr_un un_addr;
331
332         struct swrap_address bindname;
333         struct swrap_address myname;
334         struct swrap_address peername;
335
336         struct {
337                 unsigned long pck_snd;
338                 unsigned long pck_rcv;
339         } io;
340 };
341
342 struct socket_info_meta
343 {
344         unsigned int refcount;
345         int next_free;
346         /*
347          * As long as we don't use shared memory
348          * for the sockets array, we use
349          * sockets_si_global as a single mutex.
350          *
351          * pthread_mutex_t mutex;
352          */
353 };
354
355 struct socket_info_container
356 {
357         struct socket_info info;
358         struct socket_info_meta meta;
359 };
360
361 static struct socket_info_container *sockets;
362
363 static size_t socket_info_max = 0;
364
365 /*
366  * Allocate the socket array always on the limit value. We want it to be
367  * at least bigger than the default so if we reach the limit we can
368  * still deal with duplicate fds pointing to the same socket_info.
369  */
370 static size_t socket_fds_max = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT;
371
372 /* Hash table to map fds to corresponding socket_info index */
373 static int *socket_fds_idx;
374
375 /* Mutex for syncronizing port selection during swrap_auto_bind() */
376 static pthread_mutex_t autobind_start_mutex = PTHREAD_MUTEX_INITIALIZER;
377
378 /* Mutex to guard the initialization of array of socket_info structures */
379 static pthread_mutex_t sockets_mutex = PTHREAD_MUTEX_INITIALIZER;
380
381 /* Mutex to guard the socket reset in swrap_remove_wrapper() */
382 static pthread_mutex_t socket_reset_mutex = PTHREAD_MUTEX_INITIALIZER;
383
384 /* Mutex to synchronize access to first free index in socket_info array */
385 static pthread_mutex_t first_free_mutex = PTHREAD_MUTEX_INITIALIZER;
386
387 /*
388  * Mutex to synchronize access to to socket_info structures
389  * We use a single global mutex in order to avoid leaking
390  * ~ 38M copy on write memory per fork.
391  * max_sockets=65535 * sizeof(struct socket_info_container)=592 = 38796720
392  */
393 static pthread_mutex_t sockets_si_global = PTHREAD_MUTEX_INITIALIZER;
394
395 /* Mutex to synchronize access to packet capture dump file */
396 static pthread_mutex_t pcap_dump_mutex = PTHREAD_MUTEX_INITIALIZER;
397
398 /* Mutex for synchronizing mtu value fetch*/
399 static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
400
401 /* Function prototypes */
402
403 #if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT)
404 /* xlC and other oldschool compilers support (only) this */
405 #pragma init (swrap_constructor)
406 #endif
407 void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
408 #if ! defined(HAVE_DESTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_FINI)
409 #pragma fini (swrap_destructor)
410 #endif
411 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
412
413 #ifndef HAVE_GETPROGNAME
414 static const char *getprogname(void)
415 {
416 #if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME)
417         return program_invocation_short_name;
418 #elif defined(HAVE_GETEXECNAME)
419         return getexecname();
420 #else
421         return NULL;
422 #endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */
423 }
424 #endif /* HAVE_GETPROGNAME */
425
426 static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
427 # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
428
429 static void swrap_log(enum swrap_dbglvl_e dbglvl,
430                       const char *func,
431                       const char *format, ...)
432 {
433         char buffer[1024];
434         va_list va;
435         const char *d;
436         unsigned int lvl = 0;
437         const char *prefix = "SWRAP";
438         const char *progname = getprogname();
439
440         d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
441         if (d != NULL) {
442                 lvl = atoi(d);
443         }
444
445         if (lvl < dbglvl) {
446                 return;
447         }
448
449         va_start(va, format);
450         vsnprintf(buffer, sizeof(buffer), format, va);
451         va_end(va);
452
453         switch (dbglvl) {
454                 case SWRAP_LOG_ERROR:
455                         prefix = "SWRAP_ERROR";
456                         break;
457                 case SWRAP_LOG_WARN:
458                         prefix = "SWRAP_WARN";
459                         break;
460                 case SWRAP_LOG_DEBUG:
461                         prefix = "SWRAP_DEBUG";
462                         break;
463                 case SWRAP_LOG_TRACE:
464                         prefix = "SWRAP_TRACE";
465                         break;
466         }
467
468         if (progname == NULL) {
469                 progname = "<unknown>";
470         }
471
472         fprintf(stderr,
473                 "%s[%s (%u)] - %s: %s\n",
474                 prefix,
475                 progname,
476                 (unsigned int)getpid(),
477                 func,
478                 buffer);
479 }
480
481 /*********************************************************
482  * SWRAP LOADING LIBC FUNCTIONS
483  *********************************************************/
484
485 #include <dlfcn.h>
486
487 #ifdef HAVE_ACCEPT4
488 typedef int (*__libc_accept4)(int sockfd,
489                               struct sockaddr *addr,
490                               socklen_t *addrlen,
491                               int flags);
492 #else
493 typedef int (*__libc_accept)(int sockfd,
494                              struct sockaddr *addr,
495                              socklen_t *addrlen);
496 #endif
497 typedef int (*__libc_bind)(int sockfd,
498                            const struct sockaddr *addr,
499                            socklen_t addrlen);
500 typedef int (*__libc_close)(int fd);
501 #ifdef HAVE___CLOSE_NOCANCEL
502 typedef int (*__libc___close_nocancel)(int fd);
503 #endif
504 typedef int (*__libc_connect)(int sockfd,
505                               const struct sockaddr *addr,
506                               socklen_t addrlen);
507 typedef int (*__libc_dup)(int fd);
508 typedef int (*__libc_dup2)(int oldfd, int newfd);
509 typedef int (*__libc_fcntl)(int fd, int cmd, ...);
510 typedef FILE *(*__libc_fopen)(const char *name, const char *mode);
511 #ifdef HAVE_FOPEN64
512 typedef FILE *(*__libc_fopen64)(const char *name, const char *mode);
513 #endif
514 #ifdef HAVE_EVENTFD
515 typedef int (*__libc_eventfd)(int count, int flags);
516 #endif
517 typedef int (*__libc_getpeername)(int sockfd,
518                                   struct sockaddr *addr,
519                                   socklen_t *addrlen);
520 typedef int (*__libc_getsockname)(int sockfd,
521                                   struct sockaddr *addr,
522                                   socklen_t *addrlen);
523 typedef int (*__libc_getsockopt)(int sockfd,
524                                int level,
525                                int optname,
526                                void *optval,
527                                socklen_t *optlen);
528 typedef int (*__libc_ioctl)(int d, unsigned long int request, ...);
529 typedef int (*__libc_listen)(int sockfd, int backlog);
530 typedef int (*__libc_open)(const char *pathname, int flags, ...);
531 #ifdef HAVE_OPEN64
532 typedef int (*__libc_open64)(const char *pathname, int flags, ...);
533 #endif /* HAVE_OPEN64 */
534 typedef int (*__libc_openat)(int dirfd, const char *path, int flags, ...);
535 typedef int (*__libc_pipe)(int pipefd[2]);
536 typedef int (*__libc_read)(int fd, void *buf, size_t count);
537 typedef ssize_t (*__libc_readv)(int fd, const struct iovec *iov, int iovcnt);
538 typedef int (*__libc_recv)(int sockfd, void *buf, size_t len, int flags);
539 typedef int (*__libc_recvfrom)(int sockfd,
540                              void *buf,
541                              size_t len,
542                              int flags,
543                              struct sockaddr *src_addr,
544                              socklen_t *addrlen);
545 typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
546 #ifdef HAVE_RECVMMSG
547 #if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT)
548 /* FreeBSD */
549 typedef ssize_t (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags, const struct timespec *timeout);
550 #elif defined(HAVE_RECVMMSG_CONST_TIMEOUT)
551 /* Linux legacy glibc < 2.21 */
552 typedef int (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout);
553 #else
554 /* Linux glibc >= 2.21 */
555 typedef int (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout);
556 #endif
557 #endif /* HAVE_RECVMMSG */
558 typedef int (*__libc_send)(int sockfd, const void *buf, size_t len, int flags);
559 typedef int (*__libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
560 #ifdef HAVE_SENDMMSG
561 #if defined(HAVE_SENDMMSG_SSIZE_T)
562 /* FreeBSD */
563 typedef ssize_t (*__libc_sendmmsg)(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags);
564 #else
565 /* Linux */
566 typedef int (*__libc_sendmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags);
567 #endif
568 #endif /* HAVE_SENDMMSG */
569 typedef int (*__libc_sendto)(int sockfd,
570                            const void *buf,
571                            size_t len,
572                            int flags,
573                            const  struct sockaddr *dst_addr,
574                            socklen_t addrlen);
575 typedef int (*__libc_setsockopt)(int sockfd,
576                                int level,
577                                int optname,
578                                const void *optval,
579                                socklen_t optlen);
580 #ifdef HAVE_SIGNALFD
581 typedef int (*__libc_signalfd)(int fd, const sigset_t *mask, int flags);
582 #endif
583 typedef int (*__libc_socket)(int domain, int type, int protocol);
584 typedef int (*__libc_socketpair)(int domain, int type, int protocol, int sv[2]);
585 #ifdef HAVE_TIMERFD_CREATE
586 typedef int (*__libc_timerfd_create)(int clockid, int flags);
587 #endif
588 typedef ssize_t (*__libc_write)(int fd, const void *buf, size_t count);
589 typedef ssize_t (*__libc_writev)(int fd, const struct iovec *iov, int iovcnt);
590 #ifdef HAVE_SYSCALL
591 typedef long int (*__libc_syscall)(long int sysno, ...);
592 #endif
593
594 #define SWRAP_SYMBOL_ENTRY(i) \
595         union { \
596                 __libc_##i f; \
597                 void *obj; \
598         } _libc_##i
599
600 struct swrap_libc_symbols {
601 #ifdef HAVE_ACCEPT4
602         SWRAP_SYMBOL_ENTRY(accept4);
603 #else
604         SWRAP_SYMBOL_ENTRY(accept);
605 #endif
606         SWRAP_SYMBOL_ENTRY(bind);
607         SWRAP_SYMBOL_ENTRY(close);
608 #ifdef HAVE___CLOSE_NOCANCEL
609         SWRAP_SYMBOL_ENTRY(__close_nocancel);
610 #endif
611         SWRAP_SYMBOL_ENTRY(connect);
612         SWRAP_SYMBOL_ENTRY(dup);
613         SWRAP_SYMBOL_ENTRY(dup2);
614         SWRAP_SYMBOL_ENTRY(fcntl);
615         SWRAP_SYMBOL_ENTRY(fopen);
616 #ifdef HAVE_FOPEN64
617         SWRAP_SYMBOL_ENTRY(fopen64);
618 #endif
619 #ifdef HAVE_EVENTFD
620         SWRAP_SYMBOL_ENTRY(eventfd);
621 #endif
622         SWRAP_SYMBOL_ENTRY(getpeername);
623         SWRAP_SYMBOL_ENTRY(getsockname);
624         SWRAP_SYMBOL_ENTRY(getsockopt);
625         SWRAP_SYMBOL_ENTRY(ioctl);
626         SWRAP_SYMBOL_ENTRY(listen);
627         SWRAP_SYMBOL_ENTRY(open);
628 #ifdef HAVE_OPEN64
629         SWRAP_SYMBOL_ENTRY(open64);
630 #endif
631         SWRAP_SYMBOL_ENTRY(openat);
632         SWRAP_SYMBOL_ENTRY(pipe);
633         SWRAP_SYMBOL_ENTRY(read);
634         SWRAP_SYMBOL_ENTRY(readv);
635         SWRAP_SYMBOL_ENTRY(recv);
636         SWRAP_SYMBOL_ENTRY(recvfrom);
637         SWRAP_SYMBOL_ENTRY(recvmsg);
638 #ifdef HAVE_RECVMMSG
639         SWRAP_SYMBOL_ENTRY(recvmmsg);
640 #endif
641         SWRAP_SYMBOL_ENTRY(send);
642         SWRAP_SYMBOL_ENTRY(sendmsg);
643 #ifdef HAVE_SENDMMSG
644         SWRAP_SYMBOL_ENTRY(sendmmsg);
645 #endif
646         SWRAP_SYMBOL_ENTRY(sendto);
647         SWRAP_SYMBOL_ENTRY(setsockopt);
648 #ifdef HAVE_SIGNALFD
649         SWRAP_SYMBOL_ENTRY(signalfd);
650 #endif
651         SWRAP_SYMBOL_ENTRY(socket);
652         SWRAP_SYMBOL_ENTRY(socketpair);
653 #ifdef HAVE_TIMERFD_CREATE
654         SWRAP_SYMBOL_ENTRY(timerfd_create);
655 #endif
656         SWRAP_SYMBOL_ENTRY(write);
657         SWRAP_SYMBOL_ENTRY(writev);
658 #ifdef HAVE_SYSCALL
659         SWRAP_SYMBOL_ENTRY(syscall);
660 #endif
661 };
662 #undef SWRAP_SYMBOL_ENTRY
663
664 #define SWRAP_SYMBOL_ENTRY(i) \
665         union { \
666                 __rtld_default_##i f; \
667                 void *obj; \
668         } _rtld_default_##i
669
670 #ifdef HAVE_SYSCALL
671 typedef bool (*__rtld_default_uid_wrapper_syscall_valid)(long int sysno);
672 typedef long int (*__rtld_default_uid_wrapper_syscall_va)(long int sysno, va_list va);
673 #endif
674
675 struct swrap_rtld_default_symbols {
676 #ifdef HAVE_SYSCALL
677         SWRAP_SYMBOL_ENTRY(uid_wrapper_syscall_valid);
678         SWRAP_SYMBOL_ENTRY(uid_wrapper_syscall_va);
679 #else
680         uint8_t dummy;
681 #endif
682 };
683 #undef SWRAP_SYMBOL_ENTRY
684
685 struct swrap {
686         struct {
687                 void *handle;
688                 void *socket_handle;
689                 struct swrap_libc_symbols symbols;
690         } libc;
691
692         struct {
693                 struct swrap_rtld_default_symbols symbols;
694         } rtld_default;
695 };
696
697 static struct swrap swrap;
698
699 /* prototypes */
700 static char *socket_wrapper_dir(void);
701
702 #define LIBC_NAME "libc.so"
703
704 enum swrap_lib {
705     SWRAP_LIBC,
706     SWRAP_LIBSOCKET,
707 };
708
709 static const char *swrap_str_lib(enum swrap_lib lib)
710 {
711         switch (lib) {
712         case SWRAP_LIBC:
713                 return "libc";
714         case SWRAP_LIBSOCKET:
715                 return "libsocket";
716         }
717
718         /* Compiler would warn us about unhandled enum value if we get here */
719         return "unknown";
720 }
721
722 static void *swrap_load_lib_handle(enum swrap_lib lib)
723 {
724         int flags = RTLD_LAZY;
725         void *handle = NULL;
726         int i;
727
728 #ifdef RTLD_DEEPBIND
729         const char *env_preload = getenv("LD_PRELOAD");
730         const char *env_deepbind = getenv("SOCKET_WRAPPER_DISABLE_DEEPBIND");
731         bool enable_deepbind = true;
732
733         /* Don't do a deepbind if we run with libasan */
734         if (env_preload != NULL && strlen(env_preload) < 1024) {
735                 const char *p = strstr(env_preload, "libasan.so");
736                 if (p != NULL) {
737                         enable_deepbind = false;
738                 }
739         }
740
741         if (env_deepbind != NULL && strlen(env_deepbind) >= 1) {
742                 enable_deepbind = false;
743         }
744
745         if (enable_deepbind) {
746                 flags |= RTLD_DEEPBIND;
747         }
748 #endif
749
750         switch (lib) {
751         case SWRAP_LIBSOCKET:
752 #ifdef HAVE_LIBSOCKET
753                 handle = swrap.libc.socket_handle;
754                 if (handle == NULL) {
755                         for (i = 10; i >= 0; i--) {
756                                 char soname[256] = {0};
757
758                                 snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
759                                 handle = dlopen(soname, flags);
760                                 if (handle != NULL) {
761                                         break;
762                                 }
763                         }
764
765                         swrap.libc.socket_handle = handle;
766                 }
767                 break;
768 #endif
769         case SWRAP_LIBC:
770                 handle = swrap.libc.handle;
771 #ifdef LIBC_SO
772                 if (handle == NULL) {
773                         handle = dlopen(LIBC_SO, flags);
774
775                         swrap.libc.handle = handle;
776                 }
777 #endif
778                 if (handle == NULL) {
779                         for (i = 10; i >= 0; i--) {
780                                 char soname[256] = {0};
781
782                                 snprintf(soname, sizeof(soname), "libc.so.%d", i);
783                                 handle = dlopen(soname, flags);
784                                 if (handle != NULL) {
785                                         break;
786                                 }
787                         }
788
789                         swrap.libc.handle = handle;
790                 }
791                 break;
792         }
793
794         if (handle == NULL) {
795 #ifdef RTLD_NEXT
796                 handle = swrap.libc.handle = swrap.libc.socket_handle = RTLD_NEXT;
797 #else
798                 SWRAP_LOG(SWRAP_LOG_ERROR,
799                           "Failed to dlopen library: %s",
800                           dlerror());
801                 exit(-1);
802 #endif
803         }
804
805         return handle;
806 }
807
808 static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name)
809 {
810         void *handle;
811         void *func;
812
813         handle = swrap_load_lib_handle(lib);
814
815         func = dlsym(handle, fn_name);
816         if (func == NULL) {
817                 SWRAP_LOG(SWRAP_LOG_ERROR,
818                           "Failed to find %s: %s",
819                           fn_name,
820                           dlerror());
821                 exit(-1);
822         }
823
824         SWRAP_LOG(SWRAP_LOG_TRACE,
825                   "Loaded %s from %s",
826                   fn_name,
827                   swrap_str_lib(lib));
828
829         return func;
830 }
831
832 #define swrap_mutex_lock(m) _swrap_mutex_lock(m, #m, __func__, __LINE__)
833 static void _swrap_mutex_lock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line)
834 {
835         int ret;
836
837         ret = pthread_mutex_lock(mutex);
838         if (ret != 0) {
839                 SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't lock pthread mutex(%s) - %s",
840                           getpid(), getppid(), caller, line, name, strerror(ret));
841                 abort();
842         }
843 }
844
845 #define swrap_mutex_unlock(m) _swrap_mutex_unlock(m, #m, __func__, __LINE__)
846 static void _swrap_mutex_unlock(pthread_mutex_t *mutex, const char *name, const char *caller, unsigned line)
847 {
848         int ret;
849
850         ret = pthread_mutex_unlock(mutex);
851         if (ret != 0) {
852                 SWRAP_LOG(SWRAP_LOG_ERROR, "PID(%d):PPID(%d): %s(%u): Couldn't unlock pthread mutex(%s) - %s",
853                           getpid(), getppid(), caller, line, name, strerror(ret));
854                 abort();
855         }
856 }
857
858 /*
859  * These macros have a thread race condition on purpose!
860  *
861  * This is an optimization to avoid locking each time we check if the symbol is
862  * bound.
863  */
864 #define _swrap_bind_symbol_generic(lib, sym_name) do { \
865         swrap.libc.symbols._libc_##sym_name.obj = \
866                 _swrap_bind_symbol(lib, #sym_name); \
867 } while(0);
868
869 #define swrap_bind_symbol_libc(sym_name) \
870         _swrap_bind_symbol_generic(SWRAP_LIBC, sym_name)
871
872 #define swrap_bind_symbol_libsocket(sym_name) \
873         _swrap_bind_symbol_generic(SWRAP_LIBSOCKET, sym_name)
874
875 #define swrap_bind_symbol_rtld_default_optional(sym_name) do { \
876         swrap.rtld_default.symbols._rtld_default_##sym_name.obj = \
877                 dlsym(RTLD_DEFAULT, #sym_name); \
878 } while(0);
879
880 static void swrap_bind_symbol_all(void);
881
882 /****************************************************************************
883  *                               IMPORTANT
884  ****************************************************************************
885  *
886  * Functions especially from libc need to be loaded individually, you can't
887  * load all at once or gdb will segfault at startup. The same applies to
888  * valgrind and has probably something todo with with the linker.  So we need
889  * load each function at the point it is called the first time.
890  *
891  ****************************************************************************/
892
893 #ifdef HAVE_ACCEPT4
894 static int libc_accept4(int sockfd,
895                         struct sockaddr *addr,
896                         socklen_t *addrlen,
897                         int flags)
898 {
899         swrap_bind_symbol_all();
900
901         return swrap.libc.symbols._libc_accept4.f(sockfd, addr, addrlen, flags);
902 }
903
904 #else /* HAVE_ACCEPT4 */
905
906 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
907 {
908         swrap_bind_symbol_all();
909
910         return swrap.libc.symbols._libc_accept.f(sockfd, addr, addrlen);
911 }
912 #endif /* HAVE_ACCEPT4 */
913
914 static int libc_bind(int sockfd,
915                      const struct sockaddr *addr,
916                      socklen_t addrlen)
917 {
918         swrap_bind_symbol_all();
919
920         return swrap.libc.symbols._libc_bind.f(sockfd, addr, addrlen);
921 }
922
923 static int libc_close(int fd)
924 {
925         swrap_bind_symbol_all();
926
927         return swrap.libc.symbols._libc_close.f(fd);
928 }
929
930 #ifdef HAVE___CLOSE_NOCANCEL
931 static int libc___close_nocancel(int fd)
932 {
933         swrap_bind_symbol_all();
934
935         return swrap.libc.symbols._libc___close_nocancel.f(fd);
936 }
937 #endif /* HAVE___CLOSE_NOCANCEL */
938
939 static int libc_connect(int sockfd,
940                         const struct sockaddr *addr,
941                         socklen_t addrlen)
942 {
943         swrap_bind_symbol_all();
944
945         return swrap.libc.symbols._libc_connect.f(sockfd, addr, addrlen);
946 }
947
948 static int libc_dup(int fd)
949 {
950         swrap_bind_symbol_all();
951
952         return swrap.libc.symbols._libc_dup.f(fd);
953 }
954
955 static int libc_dup2(int oldfd, int newfd)
956 {
957         swrap_bind_symbol_all();
958
959         return swrap.libc.symbols._libc_dup2.f(oldfd, newfd);
960 }
961
962 #ifdef HAVE_EVENTFD
963 static int libc_eventfd(int count, int flags)
964 {
965         swrap_bind_symbol_all();
966
967         return swrap.libc.symbols._libc_eventfd.f(count, flags);
968 }
969 #endif
970
971 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
972 static int libc_vfcntl(int fd, int cmd, va_list ap)
973 {
974         void *arg;
975         int rc;
976
977         swrap_bind_symbol_all();
978
979         arg = va_arg(ap, void *);
980
981         rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg);
982
983         return rc;
984 }
985
986 static int libc_getpeername(int sockfd,
987                             struct sockaddr *addr,
988                             socklen_t *addrlen)
989 {
990         swrap_bind_symbol_all();
991
992         return swrap.libc.symbols._libc_getpeername.f(sockfd, addr, addrlen);
993 }
994
995 static int libc_getsockname(int sockfd,
996                             struct sockaddr *addr,
997                             socklen_t *addrlen)
998 {
999         swrap_bind_symbol_all();
1000
1001         return swrap.libc.symbols._libc_getsockname.f(sockfd, addr, addrlen);
1002 }
1003
1004 static int libc_getsockopt(int sockfd,
1005                            int level,
1006                            int optname,
1007                            void *optval,
1008                            socklen_t *optlen)
1009 {
1010         swrap_bind_symbol_all();
1011
1012         return swrap.libc.symbols._libc_getsockopt.f(sockfd,
1013                                                      level,
1014                                                      optname,
1015                                                      optval,
1016                                                      optlen);
1017 }
1018
1019 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
1020 static int libc_vioctl(int d, unsigned long int request, va_list ap)
1021 {
1022         void *arg;
1023         int rc;
1024
1025         swrap_bind_symbol_all();
1026
1027         arg = va_arg(ap, void *);
1028
1029         rc = swrap.libc.symbols._libc_ioctl.f(d, request, arg);
1030
1031         return rc;
1032 }
1033
1034 static int libc_listen(int sockfd, int backlog)
1035 {
1036         swrap_bind_symbol_all();
1037
1038         return swrap.libc.symbols._libc_listen.f(sockfd, backlog);
1039 }
1040
1041 static FILE *libc_fopen(const char *name, const char *mode)
1042 {
1043         swrap_bind_symbol_all();
1044
1045         return swrap.libc.symbols._libc_fopen.f(name, mode);
1046 }
1047
1048 #ifdef HAVE_FOPEN64
1049 static FILE *libc_fopen64(const char *name, const char *mode)
1050 {
1051         swrap_bind_symbol_all();
1052
1053         return swrap.libc.symbols._libc_fopen64.f(name, mode);
1054 }
1055 #endif /* HAVE_FOPEN64 */
1056
1057 static void swrap_inject_o_largefile(int *flags)
1058 {
1059         (void)*flags; /* maybe unused */
1060 #if SIZE_MAX == 0xffffffffUL && defined(O_LARGEFILE)
1061 #ifdef O_PATH
1062         if (((*flags) & O_PATH) == 0)
1063 #endif
1064         {
1065                 *flags |= O_LARGEFILE;
1066         }
1067 #endif
1068 }
1069
1070 static int libc_vopen(const char *pathname, int flags, va_list ap)
1071 {
1072         int mode = 0;
1073         int fd;
1074
1075         swrap_bind_symbol_all();
1076
1077         swrap_inject_o_largefile(&flags);
1078
1079         if (flags & O_CREAT) {
1080                 mode = va_arg(ap, int);
1081         }
1082         fd = swrap.libc.symbols._libc_open.f(pathname, flags, (mode_t)mode);
1083
1084         return fd;
1085 }
1086
1087 static int libc_open(const char *pathname, int flags, ...)
1088 {
1089         va_list ap;
1090         int fd;
1091
1092         va_start(ap, flags);
1093         fd = libc_vopen(pathname, flags, ap);
1094         va_end(ap);
1095
1096         return fd;
1097 }
1098
1099 #ifdef HAVE_OPEN64
1100 static int libc_vopen64(const char *pathname, int flags, va_list ap)
1101 {
1102         int mode = 0;
1103         int fd;
1104
1105         swrap_bind_symbol_all();
1106
1107         swrap_inject_o_largefile(&flags);
1108
1109         if (flags & O_CREAT) {
1110                 mode = va_arg(ap, int);
1111         }
1112         fd = swrap.libc.symbols._libc_open64.f(pathname, flags, (mode_t)mode);
1113
1114         return fd;
1115 }
1116 #endif /* HAVE_OPEN64 */
1117
1118 static int libc_vopenat(int dirfd, const char *path, int flags, va_list ap)
1119 {
1120         int mode = 0;
1121         int fd;
1122
1123         swrap_bind_symbol_all();
1124
1125         swrap_inject_o_largefile(&flags);
1126
1127         if (flags & O_CREAT) {
1128                 mode = va_arg(ap, int);
1129         }
1130         fd = swrap.libc.symbols._libc_openat.f(dirfd,
1131                                                path,
1132                                                flags,
1133                                                (mode_t)mode);
1134
1135         return fd;
1136 }
1137
1138 #if 0
1139 static int libc_openat(int dirfd, const char *path, int flags, ...)
1140 {
1141         va_list ap;
1142         int fd;
1143
1144         va_start(ap, flags);
1145         fd = libc_vopenat(dirfd, path, flags, ap);
1146         va_end(ap);
1147
1148         return fd;
1149 }
1150 #endif
1151
1152 static int libc_pipe(int pipefd[2])
1153 {
1154         swrap_bind_symbol_all();
1155
1156         return swrap.libc.symbols._libc_pipe.f(pipefd);
1157 }
1158
1159 static int libc_read(int fd, void *buf, size_t count)
1160 {
1161         swrap_bind_symbol_all();
1162
1163         return swrap.libc.symbols._libc_read.f(fd, buf, count);
1164 }
1165
1166 static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
1167 {
1168         swrap_bind_symbol_all();
1169
1170         return swrap.libc.symbols._libc_readv.f(fd, iov, iovcnt);
1171 }
1172
1173 static int libc_recv(int sockfd, void *buf, size_t len, int flags)
1174 {
1175         swrap_bind_symbol_all();
1176
1177         return swrap.libc.symbols._libc_recv.f(sockfd, buf, len, flags);
1178 }
1179
1180 static int libc_recvfrom(int sockfd,
1181                          void *buf,
1182                          size_t len,
1183                          int flags,
1184                          struct sockaddr *src_addr,
1185                          socklen_t *addrlen)
1186 {
1187         swrap_bind_symbol_all();
1188
1189         return swrap.libc.symbols._libc_recvfrom.f(sockfd,
1190                                                    buf,
1191                                                    len,
1192                                                    flags,
1193                                                    src_addr,
1194                                                    addrlen);
1195 }
1196
1197 static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
1198 {
1199         swrap_bind_symbol_all();
1200
1201         return swrap.libc.symbols._libc_recvmsg.f(sockfd, msg, flags);
1202 }
1203
1204 #ifdef HAVE_RECVMMSG
1205 #if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT)
1206 /* FreeBSD */
1207 static ssize_t libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags, const struct timespec *timeout)
1208 #elif defined(HAVE_RECVMMSG_CONST_TIMEOUT)
1209 /* Linux legacy glibc < 2.21 */
1210 static int libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout)
1211 #else
1212 /* Linux glibc >= 2.21 */
1213 static int libc_recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout)
1214 #endif
1215 {
1216         swrap_bind_symbol_all();
1217
1218         return swrap.libc.symbols._libc_recvmmsg.f(sockfd, msgvec, vlen, flags, timeout);
1219 }
1220 #endif
1221
1222 static int libc_send(int sockfd, const void *buf, size_t len, int flags)
1223 {
1224         swrap_bind_symbol_all();
1225
1226         return swrap.libc.symbols._libc_send.f(sockfd, buf, len, flags);
1227 }
1228
1229 static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
1230 {
1231         swrap_bind_symbol_all();
1232
1233         return swrap.libc.symbols._libc_sendmsg.f(sockfd, msg, flags);
1234 }
1235
1236 #ifdef HAVE_SENDMMSG
1237 #if defined(HAVE_SENDMMSG_SSIZE_T)
1238 /* FreeBSD */
1239 static ssize_t libc_sendmmsg(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags)
1240 #else
1241 /* Linux */
1242 static int libc_sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags)
1243 #endif
1244 {
1245         swrap_bind_symbol_all();
1246
1247         return swrap.libc.symbols._libc_sendmmsg.f(sockfd, msgvec, vlen, flags);
1248 }
1249 #endif
1250
1251 static int libc_sendto(int sockfd,
1252                        const void *buf,
1253                        size_t len,
1254                        int flags,
1255                        const  struct sockaddr *dst_addr,
1256                        socklen_t addrlen)
1257 {
1258         swrap_bind_symbol_all();
1259
1260         return swrap.libc.symbols._libc_sendto.f(sockfd,
1261                                                  buf,
1262                                                  len,
1263                                                  flags,
1264                                                  dst_addr,
1265                                                  addrlen);
1266 }
1267
1268 static int libc_setsockopt(int sockfd,
1269                            int level,
1270                            int optname,
1271                            const void *optval,
1272                            socklen_t optlen)
1273 {
1274         swrap_bind_symbol_all();
1275
1276         return swrap.libc.symbols._libc_setsockopt.f(sockfd,
1277                                                      level,
1278                                                      optname,
1279                                                      optval,
1280                                                      optlen);
1281 }
1282
1283 #ifdef HAVE_SIGNALFD
1284 static int libc_signalfd(int fd, const sigset_t *mask, int flags)
1285 {
1286         swrap_bind_symbol_all();
1287
1288         return swrap.libc.symbols._libc_signalfd.f(fd, mask, flags);
1289 }
1290 #endif
1291
1292 static int libc_socket(int domain, int type, int protocol)
1293 {
1294         swrap_bind_symbol_all();
1295
1296         return swrap.libc.symbols._libc_socket.f(domain, type, protocol);
1297 }
1298
1299 static int libc_socketpair(int domain, int type, int protocol, int sv[2])
1300 {
1301         swrap_bind_symbol_all();
1302
1303         return swrap.libc.symbols._libc_socketpair.f(domain, type, protocol, sv);
1304 }
1305
1306 #ifdef HAVE_TIMERFD_CREATE
1307 static int libc_timerfd_create(int clockid, int flags)
1308 {
1309         swrap_bind_symbol_all();
1310
1311         return swrap.libc.symbols._libc_timerfd_create.f(clockid, flags);
1312 }
1313 #endif
1314
1315 static ssize_t libc_write(int fd, const void *buf, size_t count)
1316 {
1317         swrap_bind_symbol_all();
1318
1319         return swrap.libc.symbols._libc_write.f(fd, buf, count);
1320 }
1321
1322 static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
1323 {
1324         swrap_bind_symbol_all();
1325
1326         return swrap.libc.symbols._libc_writev.f(fd, iov, iovcnt);
1327 }
1328
1329 #ifdef HAVE_SYSCALL
1330 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
1331 static long int libc_vsyscall(long int sysno, va_list va)
1332 {
1333         long int args[8];
1334         long int rc;
1335         int i;
1336
1337         swrap_bind_symbol_all();
1338
1339         for (i = 0; i < 8; i++) {
1340                 args[i] = va_arg(va, long int);
1341         }
1342
1343         rc = swrap.libc.symbols._libc_syscall.f(sysno,
1344                                                 args[0],
1345                                                 args[1],
1346                                                 args[2],
1347                                                 args[3],
1348                                                 args[4],
1349                                                 args[5],
1350                                                 args[6],
1351                                                 args[7]);
1352
1353         return rc;
1354 }
1355
1356 static bool swrap_uwrap_syscall_valid(long int sysno)
1357 {
1358         swrap_bind_symbol_all();
1359
1360         if (swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_valid.f == NULL) {
1361                 return false;
1362         }
1363
1364         return swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_valid.f(
1365                                                 sysno);
1366 }
1367
1368 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
1369 static long int swrap_uwrap_syscall_va(long int sysno, va_list va)
1370 {
1371         swrap_bind_symbol_all();
1372
1373         if (swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_va.f == NULL) {
1374                 /*
1375                  * Fallback to libc, if uid_wrapper_syscall_va is not
1376                  * available.
1377                  */
1378                 return libc_vsyscall(sysno, va);
1379         }
1380
1381         return swrap.rtld_default.symbols._rtld_default_uid_wrapper_syscall_va.f(
1382                                                 sysno,
1383                                                 va);
1384 }
1385 #endif /* HAVE_SYSCALL */
1386
1387 /* DO NOT call this function during library initialization! */
1388 static void __swrap_bind_symbol_all_once(void)
1389 {
1390 #ifdef HAVE_ACCEPT4
1391         swrap_bind_symbol_libsocket(accept4);
1392 #else
1393         swrap_bind_symbol_libsocket(accept);
1394 #endif
1395         swrap_bind_symbol_libsocket(bind);
1396         swrap_bind_symbol_libc(close);
1397 #ifdef HAVE___CLOSE_NOCANCEL
1398         swrap_bind_symbol_libc(__close_nocancel);
1399 #endif
1400         swrap_bind_symbol_libsocket(connect);
1401         swrap_bind_symbol_libc(dup);
1402         swrap_bind_symbol_libc(dup2);
1403         swrap_bind_symbol_libc(fcntl);
1404         swrap_bind_symbol_libc(fopen);
1405 #ifdef HAVE_FOPEN64
1406         swrap_bind_symbol_libc(fopen64);
1407 #endif
1408 #ifdef HAVE_EVENTFD
1409         swrap_bind_symbol_libc(eventfd);
1410 #endif
1411         swrap_bind_symbol_libsocket(getpeername);
1412         swrap_bind_symbol_libsocket(getsockname);
1413         swrap_bind_symbol_libsocket(getsockopt);
1414         swrap_bind_symbol_libc(ioctl);
1415         swrap_bind_symbol_libsocket(listen);
1416         swrap_bind_symbol_libc(open);
1417 #ifdef HAVE_OPEN64
1418         swrap_bind_symbol_libc(open64);
1419 #endif
1420         swrap_bind_symbol_libc(openat);
1421         swrap_bind_symbol_libsocket(pipe);
1422         swrap_bind_symbol_libc(read);
1423         swrap_bind_symbol_libsocket(readv);
1424         swrap_bind_symbol_libsocket(recv);
1425         swrap_bind_symbol_libsocket(recvfrom);
1426         swrap_bind_symbol_libsocket(recvmsg);
1427 #ifdef HAVE_RECVMMSG
1428         swrap_bind_symbol_libsocket(recvmmsg);
1429 #endif
1430         swrap_bind_symbol_libsocket(send);
1431         swrap_bind_symbol_libsocket(sendmsg);
1432 #ifdef HAVE_SENDMMSG
1433         swrap_bind_symbol_libsocket(sendmmsg);
1434 #endif
1435         swrap_bind_symbol_libsocket(sendto);
1436         swrap_bind_symbol_libsocket(setsockopt);
1437 #ifdef HAVE_SIGNALFD
1438         swrap_bind_symbol_libsocket(signalfd);
1439 #endif
1440         swrap_bind_symbol_libsocket(socket);
1441         swrap_bind_symbol_libsocket(socketpair);
1442 #ifdef HAVE_TIMERFD_CREATE
1443         swrap_bind_symbol_libc(timerfd_create);
1444 #endif
1445         swrap_bind_symbol_libc(write);
1446         swrap_bind_symbol_libsocket(writev);
1447 #ifdef HAVE_SYSCALL
1448         swrap_bind_symbol_libc(syscall);
1449         swrap_bind_symbol_rtld_default_optional(uid_wrapper_syscall_valid);
1450         swrap_bind_symbol_rtld_default_optional(uid_wrapper_syscall_va);
1451 #endif
1452 }
1453
1454 static void swrap_bind_symbol_all(void)
1455 {
1456         static pthread_once_t all_symbol_binding_once = PTHREAD_ONCE_INIT;
1457
1458         pthread_once(&all_symbol_binding_once, __swrap_bind_symbol_all_once);
1459 }
1460
1461 /*********************************************************
1462  * SWRAP HELPER FUNCTIONS
1463  *********************************************************/
1464
1465 /*
1466  * We return 127.0.0.0 (default) or 10.53.57.0.
1467  *
1468  * This can be controlled by:
1469  * SOCKET_WRAPPER_IPV4_NETWORK=127.0.0.0 (default)
1470  * or
1471  * SOCKET_WRAPPER_IPV4_NETWORK=10.53.57.0
1472  */
1473 static in_addr_t swrap_ipv4_net(void)
1474 {
1475         static int initialized;
1476         static in_addr_t hv;
1477         const char *net_str = NULL;
1478         struct in_addr nv;
1479         int ret;
1480
1481         if (initialized) {
1482                 return hv;
1483         }
1484         initialized = 1;
1485
1486         net_str = getenv("SOCKET_WRAPPER_IPV4_NETWORK");
1487         if (net_str == NULL) {
1488                 net_str = "127.0.0.0";
1489         }
1490
1491         ret = inet_pton(AF_INET, net_str, &nv);
1492         if (ret <= 0) {
1493                 SWRAP_LOG(SWRAP_LOG_ERROR,
1494                           "INVALID IPv4 Network [%s]",
1495                           net_str);
1496                 abort();
1497         }
1498
1499         hv = ntohl(nv.s_addr);
1500
1501         switch (hv) {
1502         case 0x7f000000:
1503                 /* 127.0.0.0 */
1504                 break;
1505         case 0x0a353900:
1506                 /* 10.53.57.0 */
1507                 break;
1508         default:
1509                 SWRAP_LOG(SWRAP_LOG_ERROR,
1510                           "INVALID IPv4 Network [%s][0x%x] should be "
1511                           "127.0.0.0 or 10.53.57.0",
1512                           net_str, (unsigned)hv);
1513                 abort();
1514         }
1515
1516         return hv;
1517 }
1518
1519 /*
1520  * This returns 127.255.255.255 or 10.255.255.255
1521  */
1522 static in_addr_t swrap_ipv4_bcast(void)
1523 {
1524         in_addr_t hv;
1525
1526         hv = swrap_ipv4_net();
1527         hv |= IN_CLASSA_HOST;
1528
1529         return hv;
1530 }
1531
1532 /*
1533  * This returns 127.0.0.${iface} or 10.53.57.${iface}
1534  */
1535 static in_addr_t swrap_ipv4_iface(unsigned int iface)
1536 {
1537         in_addr_t hv;
1538
1539         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
1540                 SWRAP_LOG(SWRAP_LOG_ERROR,
1541                           "swrap_ipv4_iface(%u) invalid!",
1542                           iface);
1543                 abort();
1544                 return -1;
1545         }
1546
1547         hv = swrap_ipv4_net();
1548         hv |= iface;
1549
1550         return hv;
1551 }
1552
1553 #ifdef HAVE_IPV6
1554 /*
1555  * FD00::5357:5FXX
1556  */
1557 static const struct in6_addr *swrap_ipv6(void)
1558 {
1559         static struct in6_addr v;
1560         static int initialized;
1561         int ret;
1562
1563         if (initialized) {
1564                 return &v;
1565         }
1566         initialized = 1;
1567
1568         ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
1569         if (ret <= 0) {
1570                 abort();
1571         }
1572
1573         return &v;
1574 }
1575 #endif
1576
1577 static void set_port(int family, int prt, struct swrap_address *addr)
1578 {
1579         switch (family) {
1580         case AF_INET:
1581                 addr->sa.in.sin_port = htons(prt);
1582                 break;
1583 #ifdef HAVE_IPV6
1584         case AF_INET6:
1585                 addr->sa.in6.sin6_port = htons(prt);
1586                 break;
1587 #endif
1588         }
1589 }
1590
1591 static size_t socket_length(int family)
1592 {
1593         switch (family) {
1594         case AF_INET:
1595                 return sizeof(struct sockaddr_in);
1596 #ifdef HAVE_IPV6
1597         case AF_INET6:
1598                 return sizeof(struct sockaddr_in6);
1599 #endif
1600         }
1601         return 0;
1602 }
1603
1604 struct swrap_sockaddr_buf {
1605         char str[128];
1606 };
1607
1608 static const char *swrap_sockaddr_string(struct swrap_sockaddr_buf *buf,
1609                                          const struct sockaddr *saddr)
1610 {
1611         unsigned int port = 0;
1612         char addr[64] = {0,};
1613
1614         switch (saddr->sa_family) {
1615         case AF_INET: {
1616                 const struct sockaddr_in *in =
1617                     (const struct sockaddr_in *)(const void *)saddr;
1618
1619                 port = ntohs(in->sin_port);
1620
1621                 inet_ntop(saddr->sa_family,
1622                           &in->sin_addr,
1623                           addr, sizeof(addr));
1624                 break;
1625         }
1626 #ifdef HAVE_IPV6
1627         case AF_INET6: {
1628                 const struct sockaddr_in6 *in6 =
1629                     (const struct sockaddr_in6 *)(const void *)saddr;
1630
1631                 port = ntohs(in6->sin6_port);
1632
1633                 inet_ntop(saddr->sa_family,
1634                           &in6->sin6_addr,
1635                           addr, sizeof(addr));
1636                 break;
1637         }
1638 #endif
1639         default:
1640                 snprintf(addr, sizeof(addr),
1641                          "<Unknown address family %u>",
1642                          saddr->sa_family);
1643                 break;
1644         }
1645
1646         snprintf(buf->str, sizeof(buf->str),
1647                  "addr[%s]/port[%u]",
1648                  addr, port);
1649
1650         return buf->str;
1651 }
1652
1653 static struct socket_info *swrap_get_socket_info(int si_index)
1654 {
1655         return (struct socket_info *)(&(sockets[si_index].info));
1656 }
1657
1658 static int swrap_get_refcount(struct socket_info *si)
1659 {
1660         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1661         return sic->meta.refcount;
1662 }
1663
1664 static void swrap_inc_refcount(struct socket_info *si)
1665 {
1666         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1667
1668         sic->meta.refcount += 1;
1669 }
1670
1671 static void swrap_dec_refcount(struct socket_info *si)
1672 {
1673         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1674
1675         sic->meta.refcount -= 1;
1676 }
1677
1678 static int swrap_get_next_free(struct socket_info *si)
1679 {
1680         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1681
1682         return sic->meta.next_free;
1683 }
1684
1685 static void swrap_set_next_free(struct socket_info *si, int next_free)
1686 {
1687         struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
1688
1689         sic->meta.next_free = next_free;
1690 }
1691
1692 static int swrap_un_path(struct sockaddr_un *un,
1693                          const char *swrap_dir,
1694                          char type,
1695                          unsigned int iface,
1696                          unsigned int prt)
1697 {
1698         int ret;
1699
1700         ret = snprintf(un->sun_path,
1701                        sizeof(un->sun_path),
1702                        "%s/"SOCKET_FORMAT,
1703                        swrap_dir,
1704                        type,
1705                        iface,
1706                        prt);
1707         if ((size_t)ret >= sizeof(un->sun_path)) {
1708                 return ENAMETOOLONG;
1709         }
1710
1711         return 0;
1712 }
1713
1714 static int swrap_un_path_EINVAL(struct sockaddr_un *un,
1715                                 const char *swrap_dir)
1716 {
1717         int ret;
1718
1719         ret = snprintf(un->sun_path,
1720                        sizeof(un->sun_path),
1721                        "%s/EINVAL",
1722                        swrap_dir);
1723
1724         if ((size_t)ret >= sizeof(un->sun_path)) {
1725                 return ENAMETOOLONG;
1726         }
1727
1728         return 0;
1729 }
1730
1731 static bool swrap_dir_usable(const char *swrap_dir)
1732 {
1733         struct sockaddr_un un;
1734         int ret;
1735
1736         ret = swrap_un_path(&un, swrap_dir, SOCKET_TYPE_CHAR_TCP, 0, 0);
1737         if (ret == 0) {
1738                 return true;
1739         }
1740
1741         ret = swrap_un_path_EINVAL(&un, swrap_dir);
1742         if (ret == 0) {
1743                 return true;
1744         }
1745
1746         return false;
1747 }
1748
1749 static char *socket_wrapper_dir(void)
1750 {
1751         char *swrap_dir = NULL;
1752         char *s = getenv("SOCKET_WRAPPER_DIR");
1753         char *t;
1754         bool ok;
1755
1756         if (s == NULL || s[0] == '\0') {
1757                 SWRAP_LOG(SWRAP_LOG_WARN, "SOCKET_WRAPPER_DIR not set");
1758                 return NULL;
1759         }
1760
1761         swrap_dir = realpath(s, NULL);
1762         if (swrap_dir == NULL) {
1763                 SWRAP_LOG(SWRAP_LOG_ERROR,
1764                           "Unable to resolve socket_wrapper dir path: %s - %s",
1765                           s,
1766                           strerror(errno));
1767                 abort();
1768         }
1769
1770         ok = swrap_dir_usable(swrap_dir);
1771         if (ok) {
1772                 goto done;
1773         }
1774
1775         free(swrap_dir);
1776
1777         ok = swrap_dir_usable(s);
1778         if (!ok) {
1779                 SWRAP_LOG(SWRAP_LOG_ERROR, "SOCKET_WRAPPER_DIR is too long");
1780                 abort();
1781         }
1782
1783         t = getenv("SOCKET_WRAPPER_DIR_ALLOW_ORIG");
1784         if (t == NULL) {
1785                 SWRAP_LOG(SWRAP_LOG_ERROR,
1786                           "realpath(SOCKET_WRAPPER_DIR) too long and "
1787                           "SOCKET_WRAPPER_DIR_ALLOW_ORIG not set");
1788                 abort();
1789
1790         }
1791
1792         swrap_dir = strdup(s);
1793         if (swrap_dir == NULL) {
1794                 SWRAP_LOG(SWRAP_LOG_ERROR,
1795                           "Unable to duplicate socket_wrapper dir path");
1796                 abort();
1797         }
1798
1799         SWRAP_LOG(SWRAP_LOG_WARN,
1800                   "realpath(SOCKET_WRAPPER_DIR) too long, "
1801                   "using original SOCKET_WRAPPER_DIR\n");
1802
1803 done:
1804         SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", swrap_dir);
1805         return swrap_dir;
1806 }
1807
1808 static unsigned int socket_wrapper_mtu(void)
1809 {
1810         static unsigned int max_mtu = 0;
1811         unsigned int tmp;
1812         const char *s;
1813         char *endp;
1814
1815         swrap_mutex_lock(&mtu_update_mutex);
1816
1817         if (max_mtu != 0) {
1818                 goto done;
1819         }
1820
1821         max_mtu = SOCKET_WRAPPER_MTU_DEFAULT;
1822
1823         s = getenv("SOCKET_WRAPPER_MTU");
1824         if (s == NULL) {
1825                 goto done;
1826         }
1827
1828         tmp = strtol(s, &endp, 10);
1829         if (s == endp) {
1830                 goto done;
1831         }
1832
1833         if (tmp < SOCKET_WRAPPER_MTU_MIN || tmp > SOCKET_WRAPPER_MTU_MAX) {
1834                 goto done;
1835         }
1836         max_mtu = tmp;
1837
1838 done:
1839         swrap_mutex_unlock(&mtu_update_mutex);
1840         return max_mtu;
1841 }
1842
1843 static int _socket_wrapper_init_mutex(pthread_mutex_t *m, const char *name)
1844 {
1845         pthread_mutexattr_t ma;
1846         bool need_destroy = false;
1847         int ret = 0;
1848
1849 #define __CHECK(cmd) do { \
1850         ret = cmd; \
1851         if (ret != 0) { \
1852                 SWRAP_LOG(SWRAP_LOG_ERROR, \
1853                           "%s: %s - failed %d", \
1854                           name, #cmd, ret); \
1855                 goto done; \
1856         } \
1857 } while(0)
1858
1859         *m = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
1860         __CHECK(pthread_mutexattr_init(&ma));
1861         need_destroy = true;
1862         __CHECK(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK));
1863         __CHECK(pthread_mutex_init(m, &ma));
1864 done:
1865         if (need_destroy) {
1866                 pthread_mutexattr_destroy(&ma);
1867         }
1868         return ret;
1869 }
1870
1871 static size_t socket_wrapper_max_sockets(void)
1872 {
1873         const char *s;
1874         size_t tmp;
1875         char *endp;
1876
1877         if (socket_info_max != 0) {
1878                 return socket_info_max;
1879         }
1880
1881         socket_info_max = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
1882
1883         s = getenv("SOCKET_WRAPPER_MAX_SOCKETS");
1884         if (s == NULL || s[0] == '\0') {
1885                 goto done;
1886         }
1887
1888         tmp = strtoul(s, &endp, 10);
1889         if (s == endp) {
1890                 goto done;
1891         }
1892         if (tmp == 0) {
1893                 tmp = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
1894                 SWRAP_LOG(SWRAP_LOG_ERROR,
1895                           "Invalid number of sockets specified, "
1896                           "using default (%zu)",
1897                           tmp);
1898         }
1899
1900         if (tmp > SOCKET_WRAPPER_MAX_SOCKETS_LIMIT) {
1901                 tmp = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT;
1902                 SWRAP_LOG(SWRAP_LOG_ERROR,
1903                           "Invalid number of sockets specified, "
1904                           "using maximum (%zu).",
1905                           tmp);
1906         }
1907
1908         socket_info_max = tmp;
1909
1910 done:
1911         return socket_info_max;
1912 }
1913
1914 static void socket_wrapper_init_fds_idx(void)
1915 {
1916         int *tmp = NULL;
1917         size_t i;
1918
1919         if (socket_fds_idx != NULL) {
1920                 return;
1921         }
1922
1923         tmp = (int *)calloc(socket_fds_max, sizeof(int));
1924         if (tmp == NULL) {
1925                 SWRAP_LOG(SWRAP_LOG_ERROR,
1926                           "Failed to allocate socket fds index array: %s",
1927                           strerror(errno));
1928                 exit(-1);
1929         }
1930
1931         for (i = 0; i < socket_fds_max; i++) {
1932                 tmp[i] = -1;
1933         }
1934
1935         socket_fds_idx = tmp;
1936 }
1937
1938 static void socket_wrapper_init_sockets(void)
1939 {
1940         size_t max_sockets;
1941         size_t i;
1942         int ret = 0;
1943
1944         swrap_bind_symbol_all();
1945
1946         swrap_mutex_lock(&sockets_mutex);
1947
1948         if (sockets != NULL) {
1949                 swrap_mutex_unlock(&sockets_mutex);
1950                 return;
1951         }
1952
1953         SWRAP_LOG(SWRAP_LOG_DEBUG,
1954                   "SOCKET_WRAPPER_PACKAGE[%s] SOCKET_WRAPPER_VERSION[%s]",
1955                   SOCKET_WRAPPER_PACKAGE, SOCKET_WRAPPER_VERSION);
1956
1957         /*
1958          * Intialize the static cache early before
1959          * any thread is able to start.
1960          */
1961         (void)swrap_ipv4_net();
1962
1963         socket_wrapper_init_fds_idx();
1964
1965         /* Needs to be called inside the sockets_mutex lock here. */
1966         max_sockets = socket_wrapper_max_sockets();
1967
1968         sockets = (struct socket_info_container *)calloc(max_sockets,
1969                                         sizeof(struct socket_info_container));
1970
1971         if (sockets == NULL) {
1972                 SWRAP_LOG(SWRAP_LOG_ERROR,
1973                           "Failed to allocate sockets array: %s",
1974                           strerror(errno));
1975                 swrap_mutex_unlock(&sockets_mutex);
1976                 exit(-1);
1977         }
1978
1979         swrap_mutex_lock(&first_free_mutex);
1980         swrap_mutex_lock(&sockets_si_global);
1981
1982         first_free = 0;
1983
1984         for (i = 0; i < max_sockets; i++) {
1985                 swrap_set_next_free(&sockets[i].info, i+1);
1986         }
1987
1988         /* mark the end of the free list */
1989         swrap_set_next_free(&sockets[max_sockets-1].info, -1);
1990
1991         swrap_mutex_unlock(&sockets_si_global);
1992         swrap_mutex_unlock(&first_free_mutex);
1993         swrap_mutex_unlock(&sockets_mutex);
1994         if (ret != 0) {
1995                 exit(-1);
1996         }
1997 }
1998
1999 bool socket_wrapper_enabled(void)
2000 {
2001         char *s = socket_wrapper_dir();
2002
2003         if (s == NULL) {
2004                 return false;
2005         }
2006
2007         SAFE_FREE(s);
2008
2009         socket_wrapper_init_sockets();
2010
2011         return true;
2012 }
2013
2014 static unsigned int socket_wrapper_default_iface(void)
2015 {
2016         const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
2017         if (s) {
2018                 unsigned int iface;
2019                 if (sscanf(s, "%u", &iface) == 1) {
2020                         if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) {
2021                                 return iface;
2022                         }
2023                 }
2024         }
2025
2026         return 1;/* 127.0.0.1 */
2027 }
2028
2029 static void set_socket_info_index(int fd, int idx)
2030 {
2031         SWRAP_LOG(SWRAP_LOG_TRACE,
2032                   "fd=%d idx=%d",
2033                   fd, idx);
2034         socket_fds_idx[fd] = idx;
2035         /* This builtin issues a full memory barrier. */
2036         __sync_synchronize();
2037 }
2038
2039 static void reset_socket_info_index(int fd)
2040 {
2041         SWRAP_LOG(SWRAP_LOG_TRACE,
2042                   "fd=%d idx=%d",
2043                   fd, -1);
2044         set_socket_info_index(fd, -1);
2045 }
2046
2047 static int find_socket_info_index(int fd)
2048 {
2049         if (fd < 0) {
2050                 return -1;
2051         }
2052
2053         if (socket_fds_idx == NULL) {
2054                 return -1;
2055         }
2056
2057         if ((size_t)fd >= socket_fds_max) {
2058                 /*
2059                  * Do not add a log here as some applications do stupid things
2060                  * like:
2061                  *
2062                  *     for (fd = 0; fd <= getdtablesize(); fd++) {
2063                  *         close(fd)
2064                  *     };
2065                  *
2066                  * This would produce millions of lines of debug messages.
2067                  */
2068 #if 0
2069                 SWRAP_LOG(SWRAP_LOG_ERROR,
2070                           "Looking for a socket info for the fd %d is over the "
2071                           "max socket index limit of %zu.",
2072                           fd,
2073                           socket_fds_max);
2074 #endif
2075                 return -1;
2076         }
2077
2078         /* This builtin issues a full memory barrier. */
2079         __sync_synchronize();
2080         return socket_fds_idx[fd];
2081 }
2082
2083 static int swrap_add_socket_info(const struct socket_info *si_input)
2084 {
2085         struct socket_info *si = NULL;
2086         int si_index = -1;
2087
2088         if (si_input == NULL) {
2089                 errno = EINVAL;
2090                 return -1;
2091         }
2092
2093         swrap_mutex_lock(&first_free_mutex);
2094         if (first_free == -1) {
2095                 errno = ENFILE;
2096                 goto out;
2097         }
2098
2099         si_index = first_free;
2100         si = swrap_get_socket_info(si_index);
2101
2102         SWRAP_LOCK_SI(si);
2103
2104         first_free = swrap_get_next_free(si);
2105         *si = *si_input;
2106         swrap_inc_refcount(si);
2107
2108         SWRAP_UNLOCK_SI(si);
2109
2110 out:
2111         swrap_mutex_unlock(&first_free_mutex);
2112
2113         return si_index;
2114 }
2115
2116 static int swrap_create_socket(struct socket_info *si, int fd)
2117 {
2118         int idx;
2119
2120         if ((size_t)fd >= socket_fds_max) {
2121                 SWRAP_LOG(SWRAP_LOG_ERROR,
2122                           "The max socket index limit of %zu has been reached, "
2123                           "trying to add %d",
2124                           socket_fds_max,
2125                           fd);
2126                 errno = EMFILE;
2127                 return -1;
2128         }
2129
2130         idx = swrap_add_socket_info(si);
2131         if (idx == -1) {
2132                 return -1;
2133         }
2134
2135         set_socket_info_index(fd, idx);
2136
2137         return idx;
2138 }
2139
2140 static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
2141 {
2142         unsigned int iface;
2143         unsigned int prt;
2144         const char *p;
2145         char type;
2146
2147         p = strrchr(un->sun_path, '/');
2148         if (p) p++; else p = un->sun_path;
2149
2150         if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) {
2151                 SWRAP_LOG(SWRAP_LOG_ERROR, "sun_path[%s] p[%s]",
2152                           un->sun_path, p);
2153                 errno = EINVAL;
2154                 return -1;
2155         }
2156
2157         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
2158                 SWRAP_LOG(SWRAP_LOG_ERROR, "type %c iface %u port %u",
2159                           type, iface, prt);
2160                 errno = EINVAL;
2161                 return -1;
2162         }
2163
2164         if (prt > 0xFFFF) {
2165                 SWRAP_LOG(SWRAP_LOG_ERROR, "type %c iface %u port %u",
2166                           type, iface, prt);
2167                 errno = EINVAL;
2168                 return -1;
2169         }
2170
2171         SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
2172                   type, iface, prt);
2173
2174         switch(type) {
2175         case SOCKET_TYPE_CHAR_TCP:
2176         case SOCKET_TYPE_CHAR_UDP: {
2177                 struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
2178
2179                 if ((*len) < sizeof(*in2)) {
2180                         SWRAP_LOG(SWRAP_LOG_ERROR,
2181                                   "V4: *len(%zu) < sizeof(*in2)=%zu",
2182                                   (size_t)*len, sizeof(*in2));
2183                         errno = EINVAL;
2184                         return -1;
2185                 }
2186
2187                 memset(in2, 0, sizeof(*in2));
2188                 in2->sin_family = AF_INET;
2189                 in2->sin_addr.s_addr = htonl(swrap_ipv4_iface(iface));
2190                 in2->sin_port = htons(prt);
2191
2192                 *len = sizeof(*in2);
2193                 break;
2194         }
2195 #ifdef HAVE_IPV6
2196         case SOCKET_TYPE_CHAR_TCP_V6:
2197         case SOCKET_TYPE_CHAR_UDP_V6: {
2198                 struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
2199
2200                 if ((*len) < sizeof(*in2)) {
2201                         SWRAP_LOG(SWRAP_LOG_ERROR,
2202                                   "V6: *len(%zu) < sizeof(*in2)=%zu",
2203                                   (size_t)*len, sizeof(*in2));
2204                         SWRAP_LOG(SWRAP_LOG_ERROR, "LINE:%d", __LINE__);
2205                         errno = EINVAL;
2206                         return -1;
2207                 }
2208
2209                 memset(in2, 0, sizeof(*in2));
2210                 in2->sin6_family = AF_INET6;
2211                 in2->sin6_addr = *swrap_ipv6();
2212                 in2->sin6_addr.s6_addr[15] = iface;
2213                 in2->sin6_port = htons(prt);
2214
2215                 *len = sizeof(*in2);
2216                 break;
2217         }
2218 #endif
2219         default:
2220                 SWRAP_LOG(SWRAP_LOG_ERROR, "type %c iface %u port %u",
2221                           type, iface, prt);
2222                 errno = EINVAL;
2223                 return -1;
2224         }
2225
2226         return 0;
2227 }
2228
2229 static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
2230                                 int *bcast)
2231 {
2232         char type = '\0';
2233         unsigned int prt;
2234         unsigned int iface;
2235         int is_bcast = 0;
2236         char *swrap_dir = NULL;
2237
2238         if (bcast) *bcast = 0;
2239
2240         switch (inaddr->sa_family) {
2241         case AF_INET: {
2242                 const struct sockaddr_in *in =
2243                     (const struct sockaddr_in *)(const void *)inaddr;
2244                 unsigned int addr = ntohl(in->sin_addr.s_addr);
2245                 char u_type = '\0';
2246                 char b_type = '\0';
2247                 char a_type = '\0';
2248                 const unsigned int sw_net_addr = swrap_ipv4_net();
2249                 const unsigned int sw_bcast_addr = swrap_ipv4_bcast();
2250
2251                 switch (si->type) {
2252                 case SOCK_STREAM:
2253                         u_type = SOCKET_TYPE_CHAR_TCP;
2254                         break;
2255                 case SOCK_DGRAM:
2256                         u_type = SOCKET_TYPE_CHAR_UDP;
2257                         a_type = SOCKET_TYPE_CHAR_UDP;
2258                         b_type = SOCKET_TYPE_CHAR_UDP;
2259                         break;
2260                 default:
2261                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2262                         errno = ESOCKTNOSUPPORT;
2263                         return -1;
2264                 }
2265
2266                 prt = ntohs(in->sin_port);
2267                 if (a_type && addr == 0xFFFFFFFF) {
2268                         /* 255.255.255.255 only udp */
2269                         is_bcast = 2;
2270                         type = a_type;
2271                         iface = socket_wrapper_default_iface();
2272                 } else if (b_type && addr == sw_bcast_addr) {
2273                         /*
2274                          * 127.255.255.255
2275                          * or
2276                          * 10.255.255.255
2277                          * only udp
2278                          */
2279                         is_bcast = 1;
2280                         type = b_type;
2281                         iface = socket_wrapper_default_iface();
2282                 } else if ((addr & 0xFFFFFF00) == sw_net_addr) {
2283                         /* 127.0.0.X or 10.53.57.X */
2284                         is_bcast = 0;
2285                         type = u_type;
2286                         iface = (addr & 0x000000FF);
2287                 } else {
2288                         struct swrap_sockaddr_buf buf = {};
2289                         SWRAP_LOG(SWRAP_LOG_WARN,
2290                                   "%s",
2291                                   swrap_sockaddr_string(&buf, inaddr));
2292                         errno = ENETUNREACH;
2293                         return -1;
2294                 }
2295                 if (bcast) *bcast = is_bcast;
2296                 break;
2297         }
2298 #ifdef HAVE_IPV6
2299         case AF_INET6: {
2300                 const struct sockaddr_in6 *in =
2301                     (const struct sockaddr_in6 *)(const void *)inaddr;
2302                 struct in6_addr cmp1, cmp2;
2303
2304                 switch (si->type) {
2305                 case SOCK_STREAM:
2306                         type = SOCKET_TYPE_CHAR_TCP_V6;
2307                         break;
2308                 case SOCK_DGRAM:
2309                         type = SOCKET_TYPE_CHAR_UDP_V6;
2310                         break;
2311                 default:
2312                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2313                         errno = ESOCKTNOSUPPORT;
2314                         return -1;
2315                 }
2316
2317                 /* XXX no multicast/broadcast */
2318
2319                 prt = ntohs(in->sin6_port);
2320
2321                 cmp1 = *swrap_ipv6();
2322                 cmp2 = in->sin6_addr;
2323                 cmp2.s6_addr[15] = 0;
2324                 if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
2325                         iface = in->sin6_addr.s6_addr[15];
2326                 } else {
2327                         struct swrap_sockaddr_buf buf = {};
2328                         SWRAP_LOG(SWRAP_LOG_WARN,
2329                                   "%s",
2330                                   swrap_sockaddr_string(&buf, inaddr));
2331                         errno = ENETUNREACH;
2332                         return -1;
2333                 }
2334
2335                 break;
2336         }
2337 #endif
2338         default:
2339                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!");
2340                 errno = ENETUNREACH;
2341                 return -1;
2342         }
2343
2344         if (prt == 0) {
2345                 SWRAP_LOG(SWRAP_LOG_WARN, "Port not set");
2346                 errno = EINVAL;
2347                 return -1;
2348         }
2349
2350         swrap_dir = socket_wrapper_dir();
2351         if (swrap_dir == NULL) {
2352                 errno = EINVAL;
2353                 return -1;
2354         }
2355
2356         if (is_bcast) {
2357                 swrap_un_path_EINVAL(un, swrap_dir);
2358                 SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2359                 SAFE_FREE(swrap_dir);
2360                 /* the caller need to do more processing */
2361                 return 0;
2362         }
2363
2364         swrap_un_path(un, swrap_dir, type, iface, prt);
2365         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2366
2367         SAFE_FREE(swrap_dir);
2368
2369         return 0;
2370 }
2371
2372 static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
2373                                int *bcast)
2374 {
2375         char type = '\0';
2376         unsigned int prt;
2377         unsigned int iface;
2378         struct stat st;
2379         int is_bcast = 0;
2380         char *swrap_dir = NULL;
2381
2382         if (bcast) *bcast = 0;
2383
2384         switch (si->family) {
2385         case AF_INET: {
2386                 const struct sockaddr_in *in =
2387                     (const struct sockaddr_in *)(const void *)inaddr;
2388                 unsigned int addr = ntohl(in->sin_addr.s_addr);
2389                 char u_type = '\0';
2390                 char d_type = '\0';
2391                 char b_type = '\0';
2392                 char a_type = '\0';
2393                 const unsigned int sw_net_addr = swrap_ipv4_net();
2394                 const unsigned int sw_bcast_addr = swrap_ipv4_bcast();
2395
2396                 prt = ntohs(in->sin_port);
2397
2398                 switch (si->type) {
2399                 case SOCK_STREAM:
2400                         u_type = SOCKET_TYPE_CHAR_TCP;
2401                         d_type = SOCKET_TYPE_CHAR_TCP;
2402                         break;
2403                 case SOCK_DGRAM:
2404                         u_type = SOCKET_TYPE_CHAR_UDP;
2405                         d_type = SOCKET_TYPE_CHAR_UDP;
2406                         a_type = SOCKET_TYPE_CHAR_UDP;
2407                         b_type = SOCKET_TYPE_CHAR_UDP;
2408                         break;
2409                 default:
2410                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2411                         errno = ESOCKTNOSUPPORT;
2412                         return -1;
2413                 }
2414
2415                 if (addr == 0) {
2416                         /* 0.0.0.0 */
2417                         is_bcast = 0;
2418                         type = d_type;
2419                         iface = socket_wrapper_default_iface();
2420                 } else if (a_type && addr == 0xFFFFFFFF) {
2421                         /* 255.255.255.255 only udp */
2422                         is_bcast = 2;
2423                         type = a_type;
2424                         iface = socket_wrapper_default_iface();
2425                 } else if (b_type && addr == sw_bcast_addr) {
2426                         /* 127.255.255.255 only udp */
2427                         is_bcast = 1;
2428                         type = b_type;
2429                         iface = socket_wrapper_default_iface();
2430                 } else if ((addr & 0xFFFFFF00) == sw_net_addr) {
2431                         /* 127.0.0.X */
2432                         is_bcast = 0;
2433                         type = u_type;
2434                         iface = (addr & 0x000000FF);
2435                 } else {
2436                         errno = EADDRNOTAVAIL;
2437                         return -1;
2438                 }
2439
2440                 /* Store the bind address for connect() */
2441                 if (si->bindname.sa_socklen == 0) {
2442                         struct sockaddr_in bind_in;
2443                         socklen_t blen = sizeof(struct sockaddr_in);
2444
2445                         ZERO_STRUCT(bind_in);
2446                         bind_in.sin_family = in->sin_family;
2447                         bind_in.sin_port = in->sin_port;
2448                         bind_in.sin_addr.s_addr = htonl(swrap_ipv4_iface(iface));
2449                         si->bindname.sa_socklen = blen;
2450                         memcpy(&si->bindname.sa.in, &bind_in, blen);
2451                 }
2452
2453                 break;
2454         }
2455 #ifdef HAVE_IPV6
2456         case AF_INET6: {
2457                 const struct sockaddr_in6 *in =
2458                     (const struct sockaddr_in6 *)(const void *)inaddr;
2459                 struct in6_addr cmp1, cmp2;
2460
2461                 switch (si->type) {
2462                 case SOCK_STREAM:
2463                         type = SOCKET_TYPE_CHAR_TCP_V6;
2464                         break;
2465                 case SOCK_DGRAM:
2466                         type = SOCKET_TYPE_CHAR_UDP_V6;
2467                         break;
2468                 default:
2469                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2470                         errno = ESOCKTNOSUPPORT;
2471                         return -1;
2472                 }
2473
2474                 /* XXX no multicast/broadcast */
2475
2476                 prt = ntohs(in->sin6_port);
2477
2478                 cmp1 = *swrap_ipv6();
2479                 cmp2 = in->sin6_addr;
2480                 cmp2.s6_addr[15] = 0;
2481                 if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
2482                         iface = socket_wrapper_default_iface();
2483                 } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
2484                         iface = in->sin6_addr.s6_addr[15];
2485                 } else {
2486                         errno = EADDRNOTAVAIL;
2487                         return -1;
2488                 }
2489
2490                 /* Store the bind address for connect() */
2491                 if (si->bindname.sa_socklen == 0) {
2492                         struct sockaddr_in6 bind_in;
2493                         socklen_t blen = sizeof(struct sockaddr_in6);
2494
2495                         ZERO_STRUCT(bind_in);
2496                         bind_in.sin6_family = in->sin6_family;
2497                         bind_in.sin6_port = in->sin6_port;
2498
2499                         bind_in.sin6_addr = *swrap_ipv6();
2500                         bind_in.sin6_addr.s6_addr[15] = iface;
2501
2502                         memcpy(&si->bindname.sa.in6, &bind_in, blen);
2503                         si->bindname.sa_socklen = blen;
2504                 }
2505
2506                 break;
2507         }
2508 #endif
2509         default:
2510                 SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2511                 errno = EADDRNOTAVAIL;
2512                 return -1;
2513         }
2514
2515
2516         if (bcast) *bcast = is_bcast;
2517
2518         if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
2519                 errno = EINVAL;
2520                 return -1;
2521         }
2522
2523         swrap_dir = socket_wrapper_dir();
2524         if (swrap_dir == NULL) {
2525                 errno = EINVAL;
2526                 return -1;
2527         }
2528
2529         if (prt == 0) {
2530                 /* handle auto-allocation of ephemeral ports */
2531                 for (prt = 5001; prt < 10000; prt++) {
2532                         swrap_un_path(un, swrap_dir, type, iface, prt);
2533                         if (stat(un->sun_path, &st) == 0) continue;
2534
2535                         set_port(si->family, prt, &si->myname);
2536                         set_port(si->family, prt, &si->bindname);
2537
2538                         break;
2539                 }
2540
2541                 if (prt == 10000) {
2542                         errno = ENFILE;
2543                         SAFE_FREE(swrap_dir);
2544                         return -1;
2545                 }
2546         }
2547
2548         swrap_un_path(un, swrap_dir, type, iface, prt);
2549         SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
2550
2551         SAFE_FREE(swrap_dir);
2552
2553         return 0;
2554 }
2555
2556 static struct socket_info *find_socket_info(int fd)
2557 {
2558         int idx = find_socket_info_index(fd);
2559
2560         if (idx == -1) {
2561                 return NULL;
2562         }
2563
2564         return swrap_get_socket_info(idx);
2565 }
2566
2567 #if 0 /* FIXME */
2568 static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
2569 {
2570         struct socket_info_fd *f;
2571         const struct socket_info *last_s = NULL;
2572
2573         /* first catch invalid input */
2574         switch (sa->sa_family) {
2575         case AF_INET:
2576                 if (len < sizeof(struct sockaddr_in)) {
2577                         return false;
2578                 }
2579                 break;
2580 #ifdef HAVE_IPV6
2581         case AF_INET6:
2582                 if (len < sizeof(struct sockaddr_in6)) {
2583                         return false;
2584                 }
2585                 break;
2586 #endif
2587         default:
2588                 return false;
2589                 break;
2590         }
2591
2592         for (f = socket_fds; f; f = f->next) {
2593                 struct socket_info *s = swrap_get_socket_info(f->si_index);
2594
2595                 if (s == last_s) {
2596                         continue;
2597                 }
2598                 last_s = s;
2599
2600                 if (s->myname == NULL) {
2601                         continue;
2602                 }
2603                 if (s->myname->sa_family != sa->sa_family) {
2604                         continue;
2605                 }
2606                 switch (s->myname->sa_family) {
2607                 case AF_INET: {
2608                         struct sockaddr_in *sin1, *sin2;
2609
2610                         sin1 = (struct sockaddr_in *)s->myname;
2611                         sin2 = (struct sockaddr_in *)sa;
2612
2613                         if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
2614                                 continue;
2615                         }
2616                         if (sin1->sin_port != sin2->sin_port) {
2617                                 continue;
2618                         }
2619                         if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
2620                                 continue;
2621                         }
2622
2623                         /* found */
2624                         return true;
2625                         break;
2626                 }
2627 #ifdef HAVE_IPV6
2628                 case AF_INET6: {
2629                         struct sockaddr_in6 *sin1, *sin2;
2630
2631                         sin1 = (struct sockaddr_in6 *)s->myname;
2632                         sin2 = (struct sockaddr_in6 *)sa;
2633
2634                         if (sin1->sin6_port != sin2->sin6_port) {
2635                                 continue;
2636                         }
2637                         if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
2638                                                 &sin2->sin6_addr))
2639                         {
2640                                 continue;
2641                         }
2642
2643                         /* found */
2644                         return true;
2645                         break;
2646                 }
2647 #endif
2648                 default:
2649                         continue;
2650                         break;
2651
2652                 }
2653         }
2654
2655         return false;
2656 }
2657 #endif
2658
2659 static void swrap_remove_stale(int fd);
2660
2661 static int sockaddr_convert_to_un(struct socket_info *si,
2662                                   const struct sockaddr *in_addr,
2663                                   socklen_t in_len,
2664                                   struct sockaddr_un *out_addr,
2665                                   int alloc_sock,
2666                                   int *bcast)
2667 {
2668         struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
2669
2670         (void) in_len; /* unused */
2671
2672         if (out_addr == NULL) {
2673                 return 0;
2674         }
2675
2676         out->sa_family = AF_UNIX;
2677 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2678         out->sa_len = sizeof(*out_addr);
2679 #endif
2680
2681         switch (in_addr->sa_family) {
2682         case AF_UNSPEC: {
2683                 const struct sockaddr_in *sin;
2684                 if (si->family != AF_INET) {
2685                         break;
2686                 }
2687                 if (in_len < sizeof(struct sockaddr_in)) {
2688                         break;
2689                 }
2690                 sin = (const struct sockaddr_in *)(const void *)in_addr;
2691                 if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
2692                         break;
2693                 }
2694
2695                 /*
2696                  * Note: in the special case of AF_UNSPEC and INADDR_ANY,
2697                  * AF_UNSPEC is mapped to AF_INET and must be treated here.
2698                  */
2699
2700                 FALL_THROUGH;
2701         }
2702         case AF_INET:
2703 #ifdef HAVE_IPV6
2704         case AF_INET6:
2705 #endif
2706                 switch (si->type) {
2707                 case SOCK_STREAM:
2708                 case SOCK_DGRAM:
2709                         break;
2710                 default:
2711                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2712                         errno = ESOCKTNOSUPPORT;
2713                         return -1;
2714                 }
2715                 if (alloc_sock) {
2716                         return convert_in_un_alloc(si, in_addr, out_addr, bcast);
2717                 } else {
2718                         return convert_in_un_remote(si, in_addr, out_addr, bcast);
2719                 }
2720         default:
2721                 break;
2722         }
2723
2724         errno = EAFNOSUPPORT;
2725         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2726         return -1;
2727 }
2728
2729 static int sockaddr_convert_from_un(const struct socket_info *si,
2730                                     const struct sockaddr_un *in_addr,
2731                                     socklen_t un_addrlen,
2732                                     int family,
2733                                     struct sockaddr *out_addr,
2734                                     socklen_t *out_addrlen)
2735 {
2736         int ret;
2737
2738         if (out_addr == NULL || out_addrlen == NULL)
2739                 return 0;
2740
2741         if (un_addrlen == 0) {
2742                 *out_addrlen = 0;
2743                 return 0;
2744         }
2745
2746         switch (family) {
2747         case AF_INET:
2748 #ifdef HAVE_IPV6
2749         case AF_INET6:
2750 #endif
2751                 switch (si->type) {
2752                 case SOCK_STREAM:
2753                 case SOCK_DGRAM:
2754                         break;
2755                 default:
2756                         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!");
2757                         errno = ESOCKTNOSUPPORT;
2758                         return -1;
2759                 }
2760                 ret = convert_un_in(in_addr, out_addr, out_addrlen);
2761 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
2762                 out_addr->sa_len = *out_addrlen;
2763 #endif
2764                 return ret;
2765         default:
2766                 break;
2767         }
2768
2769         SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family");
2770         errno = EAFNOSUPPORT;
2771         return -1;
2772 }
2773
2774 enum swrap_packet_type {
2775         SWRAP_CONNECT_SEND,
2776         SWRAP_CONNECT_UNREACH,
2777         SWRAP_CONNECT_RECV,
2778         SWRAP_CONNECT_ACK,
2779         SWRAP_ACCEPT_SEND,
2780         SWRAP_ACCEPT_RECV,
2781         SWRAP_ACCEPT_ACK,
2782         SWRAP_RECVFROM,
2783         SWRAP_SENDTO,
2784         SWRAP_SENDTO_UNREACH,
2785         SWRAP_PENDING_RST,
2786         SWRAP_RECV,
2787         SWRAP_RECV_RST,
2788         SWRAP_SEND,
2789         SWRAP_SEND_RST,
2790         SWRAP_CLOSE_SEND,
2791         SWRAP_CLOSE_RECV,
2792         SWRAP_CLOSE_ACK,
2793 };
2794
2795 struct swrap_file_hdr {
2796         uint32_t        magic;
2797         uint16_t        version_major;
2798         uint16_t        version_minor;
2799         int32_t         timezone;
2800         uint32_t        sigfigs;
2801         uint32_t        frame_max_len;
2802 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
2803         uint32_t        link_type;
2804 };
2805 #define SWRAP_FILE_HDR_SIZE 24
2806
2807 struct swrap_packet_frame {
2808         uint32_t seconds;
2809         uint32_t micro_seconds;
2810         uint32_t recorded_length;
2811         uint32_t full_length;
2812 };
2813 #define SWRAP_PACKET_FRAME_SIZE 16
2814
2815 union swrap_packet_ip {
2816         struct {
2817                 uint8_t         ver_hdrlen;
2818                 uint8_t         tos;
2819                 uint16_t        packet_length;
2820                 uint16_t        identification;
2821                 uint8_t         flags;
2822                 uint8_t         fragment;
2823                 uint8_t         ttl;
2824                 uint8_t         protocol;
2825                 uint16_t        hdr_checksum;
2826                 uint32_t        src_addr;
2827                 uint32_t        dest_addr;
2828         } v4;
2829 #define SWRAP_PACKET_IP_V4_SIZE 20
2830         struct {
2831                 uint8_t         ver_prio;
2832                 uint8_t         flow_label_high;
2833                 uint16_t        flow_label_low;
2834                 uint16_t        payload_length;
2835                 uint8_t         next_header;
2836                 uint8_t         hop_limit;
2837                 uint8_t         src_addr[16];
2838                 uint8_t         dest_addr[16];
2839         } v6;
2840 #define SWRAP_PACKET_IP_V6_SIZE 40
2841 };
2842 #define SWRAP_PACKET_IP_SIZE 40
2843
2844 union swrap_packet_payload {
2845         struct {
2846                 uint16_t        source_port;
2847                 uint16_t        dest_port;
2848                 uint32_t        seq_num;
2849                 uint32_t        ack_num;
2850                 uint8_t         hdr_length;
2851                 uint8_t         control;
2852                 uint16_t        window;
2853                 uint16_t        checksum;
2854                 uint16_t        urg;
2855         } tcp;
2856 #define SWRAP_PACKET_PAYLOAD_TCP_SIZE 20
2857         struct {
2858                 uint16_t        source_port;
2859                 uint16_t        dest_port;
2860                 uint16_t        length;
2861                 uint16_t        checksum;
2862         } udp;
2863 #define SWRAP_PACKET_PAYLOAD_UDP_SIZE 8
2864         struct {
2865                 uint8_t         type;
2866                 uint8_t         code;
2867                 uint16_t        checksum;
2868                 uint32_t        unused;
2869         } icmp4;
2870 #define SWRAP_PACKET_PAYLOAD_ICMP4_SIZE 8
2871         struct {
2872                 uint8_t         type;
2873                 uint8_t         code;
2874                 uint16_t        checksum;
2875                 uint32_t        unused;
2876         } icmp6;
2877 #define SWRAP_PACKET_PAYLOAD_ICMP6_SIZE 8
2878 };
2879 #define SWRAP_PACKET_PAYLOAD_SIZE 20
2880
2881 #define SWRAP_PACKET_MIN_ALLOC \
2882         (SWRAP_PACKET_FRAME_SIZE + \
2883          SWRAP_PACKET_IP_SIZE + \
2884          SWRAP_PACKET_PAYLOAD_SIZE)
2885
2886 static const char *swrap_pcap_init_file(void)
2887 {
2888         static int initialized = 0;
2889         static const char *s = NULL;
2890         static const struct swrap_file_hdr h;
2891         static const struct swrap_packet_frame f;
2892         static const union swrap_packet_ip i;
2893         static const union swrap_packet_payload p;
2894
2895         if (initialized == 1) {
2896                 return s;
2897         }
2898         initialized = 1;
2899
2900         /*
2901          * TODO: don't use the structs use plain buffer offsets
2902          *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
2903          *
2904          * for now make sure we disable PCAP support
2905          * if the struct has alignment!
2906          */
2907         if (sizeof(h) != SWRAP_FILE_HDR_SIZE) {
2908                 return NULL;
2909         }
2910         if (sizeof(f) != SWRAP_PACKET_FRAME_SIZE) {
2911                 return NULL;
2912         }
2913         if (sizeof(i) != SWRAP_PACKET_IP_SIZE) {
2914                 return NULL;
2915         }
2916         if (sizeof(i.v4) != SWRAP_PACKET_IP_V4_SIZE) {
2917                 return NULL;
2918         }
2919         if (sizeof(i.v6) != SWRAP_PACKET_IP_V6_SIZE) {
2920                 return NULL;
2921         }
2922         if (sizeof(p) != SWRAP_PACKET_PAYLOAD_SIZE) {
2923                 return NULL;
2924         }
2925         if (sizeof(p.tcp) != SWRAP_PACKET_PAYLOAD_TCP_SIZE) {
2926                 return NULL;
2927         }
2928         if (sizeof(p.udp) != SWRAP_PACKET_PAYLOAD_UDP_SIZE) {
2929                 return NULL;
2930         }
2931         if (sizeof(p.icmp4) != SWRAP_PACKET_PAYLOAD_ICMP4_SIZE) {
2932                 return NULL;
2933         }
2934         if (sizeof(p.icmp6) != SWRAP_PACKET_PAYLOAD_ICMP6_SIZE) {
2935                 return NULL;
2936         }
2937
2938         s = getenv("SOCKET_WRAPPER_PCAP_FILE");
2939         if (s == NULL) {
2940                 return NULL;
2941         }
2942         if (strncmp(s, "./", 2) == 0) {
2943                 s += 2;
2944         }
2945         SWRAP_LOG(SWRAP_LOG_TRACE, "SOCKET_WRAPPER_PCAP_FILE: %s", s);
2946         return s;
2947 }
2948
2949 static uint8_t *swrap_pcap_packet_init(struct timeval *tval,
2950                                        const struct sockaddr *src,
2951                                        const struct sockaddr *dest,
2952                                        int socket_type,
2953                                        const uint8_t *payload,
2954                                        size_t payload_len,
2955                                        unsigned long tcp_seqno,
2956                                        unsigned long tcp_ack,
2957                                        unsigned char tcp_ctl,
2958                                        int unreachable,
2959                                        size_t *_packet_len)
2960 {
2961         uint8_t *base = NULL;
2962         uint8_t *buf = NULL;
2963         union {
2964                 uint8_t *ptr;
2965                 struct swrap_packet_frame *frame;
2966         } f;
2967         union {
2968                 uint8_t *ptr;
2969                 union swrap_packet_ip *ip;
2970         } i;
2971         union swrap_packet_payload *pay;
2972         size_t packet_len;
2973         size_t alloc_len;
2974         size_t nonwire_len = sizeof(struct swrap_packet_frame);
2975         size_t wire_hdr_len = 0;
2976         size_t wire_len = 0;
2977         size_t ip_hdr_len = 0;
2978         size_t icmp_hdr_len = 0;
2979         size_t icmp_truncate_len = 0;
2980         uint8_t protocol = 0, icmp_protocol = 0;
2981         const struct sockaddr_in *src_in = NULL;
2982         const struct sockaddr_in *dest_in = NULL;
2983 #ifdef HAVE_IPV6
2984         const struct sockaddr_in6 *src_in6 = NULL;
2985         const struct sockaddr_in6 *dest_in6 = NULL;
2986 #endif
2987         uint16_t src_port;
2988         uint16_t dest_port;
2989
2990         switch (src->sa_family) {
2991         case AF_INET:
2992                 src_in = (const struct sockaddr_in *)(const void *)src;
2993                 dest_in = (const struct sockaddr_in *)(const void *)dest;
2994                 src_port = src_in->sin_port;
2995                 dest_port = dest_in->sin_port;
2996                 ip_hdr_len = sizeof(i.ip->v4);
2997                 break;
2998 #ifdef HAVE_IPV6
2999         case AF_INET6:
3000                 src_in6 = (const struct sockaddr_in6 *)(const void *)src;
3001                 dest_in6 = (const struct sockaddr_in6 *)(const void *)dest;
3002                 src_port = src_in6->sin6_port;
3003                 dest_port = dest_in6->sin6_port;
3004                 ip_hdr_len = sizeof(i.ip->v6);
3005                 break;
3006 #endif
3007         default:
3008                 return NULL;
3009         }
3010
3011         switch (socket_type) {
3012         case SOCK_STREAM:
3013                 protocol = 0x06; /* TCP */
3014                 wire_hdr_len = ip_hdr_len + sizeof(pay->tcp);
3015                 wire_len = wire_hdr_len + payload_len;
3016                 break;
3017
3018         case SOCK_DGRAM:
3019                 protocol = 0x11; /* UDP */
3020                 wire_hdr_len = ip_hdr_len + sizeof(pay->udp);
3021                 wire_len = wire_hdr_len + payload_len;
3022                 break;
3023
3024         default:
3025                 return NULL;
3026         }
3027
3028         if (unreachable) {
3029                 icmp_protocol = protocol;
3030                 switch (src->sa_family) {
3031                 case AF_INET:
3032                         protocol = 0x01; /* ICMPv4 */
3033                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp4);
3034                         break;
3035 #ifdef HAVE_IPV6
3036                 case AF_INET6:
3037                         protocol = 0x3A; /* ICMPv6 */
3038                         icmp_hdr_len = ip_hdr_len + sizeof(pay->icmp6);
3039                         break;
3040 #endif
3041                 }
3042                 if (wire_len > 64 ) {
3043                         icmp_truncate_len = wire_len - 64;
3044                 }
3045                 wire_len += icmp_hdr_len;
3046         }
3047
3048         packet_len = nonwire_len + wire_len;
3049         alloc_len = packet_len;
3050         if (alloc_len < SWRAP_PACKET_MIN_ALLOC) {
3051                 alloc_len = SWRAP_PACKET_MIN_ALLOC;
3052         }
3053
3054         base = (uint8_t *)calloc(1, alloc_len);
3055         if (base == NULL) {
3056                 return NULL;
3057         }
3058
3059         buf = base;
3060         f.ptr = buf;
3061
3062         f.frame->seconds                = tval->tv_sec;
3063         f.frame->micro_seconds  = tval->tv_usec;
3064         f.frame->recorded_length        = wire_len - icmp_truncate_len;
3065         f.frame->full_length    = wire_len - icmp_truncate_len;
3066
3067         buf += SWRAP_PACKET_FRAME_SIZE;
3068
3069         i.ptr = buf;
3070         switch (src->sa_family) {
3071         case AF_INET:
3072                 if (src_in == NULL || dest_in == NULL) {
3073                         SAFE_FREE(base);
3074                         return NULL;
3075                 }
3076
3077                 i.ip->v4.ver_hdrlen     = 0x45; /* version 4 and 5 * 32 bit words */
3078                 i.ip->v4.tos            = 0x00;
3079                 i.ip->v4.packet_length  = htons(wire_len - icmp_truncate_len);
3080                 i.ip->v4.identification = htons(0xFFFF);
3081                 i.ip->v4.flags          = 0x40; /* BIT 1 set - means don't fragment */
3082                 i.ip->v4.fragment       = htons(0x0000);
3083                 i.ip->v4.ttl            = 0xFF;
3084                 i.ip->v4.protocol       = protocol;
3085                 i.ip->v4.hdr_checksum   = htons(0x0000);
3086                 i.ip->v4.src_addr       = src_in->sin_addr.s_addr;
3087                 i.ip->v4.dest_addr      = dest_in->sin_addr.s_addr;
3088                 buf += SWRAP_PACKET_IP_V4_SIZE;
3089                 break;
3090 #ifdef HAVE_IPV6
3091         case AF_INET6:
3092                 if (src_in6 == NULL || dest_in6 == NULL) {
3093                         SAFE_FREE(base);
3094                         return NULL;
3095                 }
3096
3097                 i.ip->v6.ver_prio               = 0x60; /* version 4 and 5 * 32 bit words */
3098                 i.ip->v6.flow_label_high        = 0x00;
3099                 i.ip->v6.flow_label_low = 0x0000;
3100                 i.ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
3101                 i.ip->v6.next_header    = protocol;
3102                 memcpy(i.ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
3103                 memcpy(i.ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
3104                 buf += SWRAP_PACKET_IP_V6_SIZE;
3105                 break;
3106 #endif
3107         }
3108
3109         if (unreachable) {
3110                 pay = (union swrap_packet_payload *)(void *)buf;
3111                 switch (src->sa_family) {
3112                 case AF_INET:
3113                         pay->icmp4.type         = 0x03; /* destination unreachable */
3114                         pay->icmp4.code         = 0x01; /* host unreachable */
3115                         pay->icmp4.checksum     = htons(0x0000);
3116                         pay->icmp4.unused       = htonl(0x00000000);
3117
3118                         buf += SWRAP_PACKET_PAYLOAD_ICMP4_SIZE;
3119
3120                         /* set the ip header in the ICMP payload */
3121                         i.ptr = buf;
3122                         i.ip->v4.ver_hdrlen     = 0x45; /* version 4 and 5 * 32 bit words */
3123                         i.ip->v4.tos            = 0x00;
3124                         i.ip->v4.packet_length  = htons(wire_len - icmp_hdr_len);
3125                         i.ip->v4.identification = htons(0xFFFF);
3126                         i.ip->v4.flags          = 0x40; /* BIT 1 set - means don't fragment */
3127                         i.ip->v4.fragment       = htons(0x0000);
3128                         i.ip->v4.ttl            = 0xFF;
3129                         i.ip->v4.protocol       = icmp_protocol;
3130                         i.ip->v4.hdr_checksum   = htons(0x0000);
3131                         i.ip->v4.src_addr       = dest_in->sin_addr.s_addr;
3132                         i.ip->v4.dest_addr      = src_in->sin_addr.s_addr;
3133
3134                         buf += SWRAP_PACKET_IP_V4_SIZE;
3135
3136                         src_port = dest_in->sin_port;
3137                         dest_port = src_in->sin_port;
3138                         break;
3139 #ifdef HAVE_IPV6
3140                 case AF_INET6:
3141                         pay->icmp6.type         = 0x01; /* destination unreachable */
3142                         pay->icmp6.code         = 0x03; /* address unreachable */
3143                         pay->icmp6.checksum     = htons(0x0000);
3144                         pay->icmp6.unused       = htonl(0x00000000);
3145                         buf += SWRAP_PACKET_PAYLOAD_ICMP6_SIZE;
3146
3147                         /* set the ip header in the ICMP payload */
3148                         i.ptr = buf;
3149                         i.ip->v6.ver_prio               = 0x60; /* version 4 and 5 * 32 bit words */
3150                         i.ip->v6.flow_label_high        = 0x00;
3151                         i.ip->v6.flow_label_low = 0x0000;
3152                         i.ip->v6.payload_length = htons(wire_len - icmp_truncate_len); /* TODO */
3153                         i.ip->v6.next_header    = protocol;
3154                         memcpy(i.ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
3155                         memcpy(i.ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
3156
3157                         buf += SWRAP_PACKET_IP_V6_SIZE;
3158
3159                         src_port = dest_in6->sin6_port;
3160                         dest_port = src_in6->sin6_port;
3161                         break;
3162 #endif
3163                 }
3164         }
3165
3166         pay = (union swrap_packet_payload *)(void *)buf;
3167
3168         switch (socket_type) {
3169         case SOCK_STREAM:
3170                 pay->tcp.source_port    = src_port;
3171                 pay->tcp.dest_port      = dest_port;
3172                 pay->tcp.seq_num        = htonl(tcp_seqno);
3173                 pay->tcp.ack_num        = htonl(tcp_ack);
3174                 pay->tcp.hdr_length     = 0x50; /* 5 * 32 bit words */
3175                 pay->tcp.control        = tcp_ctl;
3176                 pay->tcp.window         = htons(0x7FFF);
3177                 pay->tcp.checksum       = htons(0x0000);
3178                 pay->tcp.urg            = htons(0x0000);
3179                 buf += SWRAP_PACKET_PAYLOAD_TCP_SIZE;
3180
3181                 break;
3182
3183         case SOCK_DGRAM:
3184                 pay->udp.source_port    = src_port;
3185                 pay->udp.dest_port      = dest_port;
3186                 pay->udp.length         = htons(8 + payload_len);
3187                 pay->udp.checksum       = htons(0x0000);
3188                 buf += SWRAP_PACKET_PAYLOAD_UDP_SIZE;
3189
3190                 break;
3191         }
3192
3193         if (payload && payload_len > 0) {
3194                 memcpy(buf, payload, payload_len);
3195         }
3196
3197         *_packet_len = packet_len - icmp_truncate_len;
3198         return base;
3199 }
3200
3201 static int swrap_pcap_get_fd(const char *fname)
3202 {
3203         static int fd = -1;
3204
3205         if (fd != -1) {
3206                 return fd;
3207         }
3208
3209         fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
3210         if (fd != -1) {
3211                 struct swrap_file_hdr file_hdr;
3212                 file_hdr.magic          = 0xA1B2C3D4;
3213                 file_hdr.version_major  = 0x0002;
3214                 file_hdr.version_minor  = 0x0004;
3215                 file_hdr.timezone       = 0x00000000;
3216                 file_hdr.sigfigs        = 0x00000000;
3217                 file_hdr.frame_max_len  = SWRAP_FRAME_LENGTH_MAX;
3218                 file_hdr.link_type      = 0x0065; /* 101 RAW IP */
3219
3220                 if (libc_write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
3221                         libc_close(fd);
3222                         fd = -1;
3223                 }
3224                 return fd;
3225         }
3226
3227         fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
3228
3229         return fd;
3230 }
3231
3232 static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
3233                                            const struct sockaddr *addr,
3234                                            enum swrap_packet_type type,
3235                                            const void *buf, size_t len,
3236                                            size_t *packet_len)
3237 {
3238         const struct sockaddr *src_addr;
3239         const struct sockaddr *dest_addr;
3240         unsigned long tcp_seqno = 0;
3241         unsigned long tcp_ack = 0;
3242         unsigned char tcp_ctl = 0;
3243         int unreachable = 0;
3244
3245         struct timeval tv;
3246
3247         switch (si->family) {
3248         case AF_INET:
3249                 break;
3250 #ifdef HAVE_IPV6
3251         case AF_INET6:
3252                 break;
3253 #endif
3254         default:
3255                 return NULL;
3256         }
3257
3258         switch (type) {
3259         case SWRAP_CONNECT_SEND:
3260                 if (si->type != SOCK_STREAM) {
3261                         return NULL;
3262                 }
3263
3264                 src_addr  = &si->myname.sa.s;
3265                 dest_addr = addr;
3266
3267                 tcp_seqno = si->io.pck_snd;
3268                 tcp_ack = si->io.pck_rcv;
3269                 tcp_ctl = 0x02; /* SYN */
3270
3271                 si->io.pck_snd += 1;
3272
3273                 break;
3274
3275         case SWRAP_CONNECT_RECV:
3276                 if (si->type != SOCK_STREAM) {
3277                         return NULL;
3278                 }
3279
3280                 dest_addr = &si->myname.sa.s;
3281                 src_addr = addr;
3282
3283                 tcp_seqno = si->io.pck_rcv;
3284                 tcp_ack = si->io.pck_snd;
3285                 tcp_ctl = 0x12; /** SYN,ACK */
3286
3287                 si->io.pck_rcv += 1;
3288
3289                 break;
3290
3291         case SWRAP_CONNECT_UNREACH:
3292                 if (si->type != SOCK_STREAM) {
3293                         return NULL;
3294                 }
3295
3296                 dest_addr = &si->myname.sa.s;
3297                 src_addr  = addr;
3298
3299                 /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
3300                 tcp_seqno = si->io.pck_snd - 1;
3301                 tcp_ack = si->io.pck_rcv;
3302                 tcp_ctl = 0x02; /* SYN */
3303                 unreachable = 1;
3304
3305                 break;
3306
3307         case SWRAP_CONNECT_ACK:
3308                 if (si->type != SOCK_STREAM) {
3309                         return NULL;
3310                 }
3311
3312                 src_addr  = &si->myname.sa.s;
3313                 dest_addr = addr;
3314
3315                 tcp_seqno = si->io.pck_snd;
3316                 tcp_ack = si->io.pck_rcv;
3317                 tcp_ctl = 0x10; /* ACK */
3318
3319                 break;
3320
3321         case SWRAP_ACCEPT_SEND:
3322                 if (si->type != SOCK_STREAM) {
3323                         return NULL;
3324                 }
3325
3326                 dest_addr = &si->myname.sa.s;
3327                 src_addr = addr;
3328
3329                 tcp_seqno = si->io.pck_rcv;
3330                 tcp_ack = si->io.pck_snd;
3331                 tcp_ctl = 0x02; /* SYN */
3332
3333                 si->io.pck_rcv += 1;
3334
3335                 break;
3336
3337         case SWRAP_ACCEPT_RECV:
3338                 if (si->type != SOCK_STREAM) {
3339                         return NULL;
3340                 }
3341
3342                 src_addr = &si->myname.sa.s;
3343                 dest_addr = addr;
3344
3345                 tcp_seqno = si->io.pck_snd;
3346                 tcp_ack = si->io.pck_rcv;
3347                 tcp_ctl = 0x12; /* SYN,ACK */
3348
3349                 si->io.pck_snd += 1;
3350
3351                 break;
3352
3353         case SWRAP_ACCEPT_ACK:
3354                 if (si->type != SOCK_STREAM) {
3355                         return NULL;
3356                 }
3357
3358                 dest_addr = &si->myname.sa.s;
3359                 src_addr = addr;
3360
3361                 tcp_seqno = si->io.pck_rcv;
3362                 tcp_ack = si->io.pck_snd;
3363                 tcp_ctl = 0x10; /* ACK */
3364
3365                 break;
3366
3367         case SWRAP_SEND:
3368                 src_addr  = &si->myname.sa.s;
3369                 dest_addr = &si->peername.sa.s;
3370
3371                 tcp_seqno = si->io.pck_snd;
3372                 tcp_ack = si->io.pck_rcv;
3373                 tcp_ctl = 0x18; /* PSH,ACK */
3374
3375                 si->io.pck_snd += len;
3376
3377                 break;
3378
3379         case SWRAP_SEND_RST:
3380                 dest_addr = &si->myname.sa.s;
3381                 src_addr  = &si->peername.sa.s;
3382
3383                 if (si->type == SOCK_DGRAM) {
3384                         return swrap_pcap_marshall_packet(si,
3385                                                           &si->peername.sa.s,
3386                                                           SWRAP_SENDTO_UNREACH,
3387                                                           buf,
3388                                                           len,
3389                                                           packet_len);
3390                 }
3391
3392                 tcp_seqno = si->io.pck_rcv;
3393                 tcp_ack = si->io.pck_snd;
3394                 tcp_ctl = 0x14; /** RST,ACK */
3395
3396                 break;
3397
3398         case SWRAP_PENDING_RST:
3399                 dest_addr = &si->myname.sa.s;
3400                 src_addr  = &si->peername.sa.s;
3401
3402                 if (si->type == SOCK_DGRAM) {
3403                         return NULL;
3404                 }
3405
3406                 tcp_seqno = si->io.pck_rcv;
3407                 tcp_ack = si->io.pck_snd;
3408                 tcp_ctl = 0x14; /* RST,ACK */
3409
3410                 break;
3411
3412         case SWRAP_RECV:
3413                 dest_addr = &si->myname.sa.s;
3414                 src_addr  = &si->peername.sa.s;
3415
3416                 tcp_seqno = si->io.pck_rcv;
3417                 tcp_ack = si->io.pck_snd;
3418                 tcp_ctl = 0x18; /* PSH,ACK */
3419
3420                 si->io.pck_rcv += len;
3421
3422                 break;
3423
3424         case SWRAP_RECV_RST:
3425                 dest_addr = &si->myname.sa.s;
3426                 src_addr  = &si->peername.sa.s;
3427
3428                 if (si->type == SOCK_DGRAM) {
3429                         return NULL;
3430                 }
3431
3432                 tcp_seqno = si->io.pck_rcv;
3433                 tcp_ack = si->io.pck_snd;
3434                 tcp_ctl = 0x14; /* RST,ACK */
3435
3436                 break;
3437
3438         case SWRAP_SENDTO:
3439                 src_addr = &si->myname.sa.s;
3440                 dest_addr = addr;
3441
3442                 si->io.pck_snd += len;
3443
3444                 break;
3445
3446         case SWRAP_SENDTO_UNREACH:
3447                 dest_addr = &si->myname.sa.s;
3448                 src_addr = addr;
3449
3450                 unreachable = 1;
3451
3452                 break;
3453
3454         case SWRAP_RECVFROM:
3455                 dest_addr = &si->myname.sa.s;
3456                 src_addr = addr;
3457
3458                 si->io.pck_rcv += len;
3459
3460                 break;
3461
3462         case SWRAP_CLOSE_SEND:
3463                 if (si->type != SOCK_STREAM) {
3464                         return NULL;
3465                 }
3466
3467                 src_addr  = &si->myname.sa.s;
3468                 dest_addr = &si->peername.sa.s;
3469
3470                 tcp_seqno = si->io.pck_snd;
3471                 tcp_ack = si->io.pck_rcv;
3472                 tcp_ctl = 0x11; /* FIN, ACK */
3473
3474                 si->io.pck_snd += 1;
3475
3476                 break;
3477
3478         case SWRAP_CLOSE_RECV:
3479                 if (si->type != SOCK_STREAM) {
3480                         return NULL;
3481                 }
3482
3483                 dest_addr = &si->myname.sa.s;
3484                 src_addr  = &si->peername.sa.s;
3485
3486                 tcp_seqno = si->io.pck_rcv;
3487                 tcp_ack = si->io.pck_snd;
3488                 tcp_ctl = 0x11; /* FIN,ACK */
3489
3490                 si->io.pck_rcv += 1;
3491
3492                 break;
3493
3494         case SWRAP_CLOSE_ACK:
3495                 if (si->type != SOCK_STREAM) {
3496                         return NULL;
3497                 }
3498
3499                 src_addr  = &si->myname.sa.s;
3500                 dest_addr = &si->peername.sa.s;
3501
3502                 tcp_seqno = si->io.pck_snd;
3503                 tcp_ack = si->io.pck_rcv;
3504                 tcp_ctl = 0x10; /* ACK */
3505
3506                 break;
3507         default:
3508                 return NULL;
3509         }
3510
3511         swrapGetTimeOfDay(&tv);
3512
3513         return swrap_pcap_packet_init(&tv,
3514                                       src_addr,
3515                                       dest_addr,
3516                                       si->type,
3517                                       (const uint8_t *)buf,
3518                                       len,
3519                                       tcp_seqno,
3520                                       tcp_ack,
3521                                       tcp_ctl,
3522                                       unreachable,
3523                                       packet_len);
3524 }
3525
3526 static void swrap_pcap_dump_packet(struct socket_info *si,
3527                                    const struct sockaddr *addr,
3528                                    enum swrap_packet_type type,
3529                                    const void *buf, size_t len)
3530 {
3531         const char *file_name;
3532         uint8_t *packet;
3533         size_t packet_len = 0;
3534         int fd;
3535
3536         swrap_mutex_lock(&pcap_dump_mutex);
3537
3538         file_name = swrap_pcap_init_file();
3539         if (!file_name) {
3540                 goto done;
3541         }
3542
3543         packet = swrap_pcap_marshall_packet(si,
3544                                             addr,
3545                                             type,
3546                                             buf,
3547                                             len,
3548                                             &packet_len);
3549         if (packet == NULL) {
3550                 goto done;
3551         }
3552
3553         fd = swrap_pcap_get_fd(file_name);
3554         if (fd != -1) {
3555                 if (libc_write(fd, packet, packet_len) != (ssize_t)packet_len) {
3556                         free(packet);
3557                         goto done;
3558                 }
3559         }
3560
3561         free(packet);
3562
3563 done:
3564         swrap_mutex_unlock(&pcap_dump_mutex);
3565 }
3566
3567 /****************************************************************************
3568  *   SIGNALFD
3569  ***************************************************************************/
3570
3571 #ifdef HAVE_SIGNALFD
3572 static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
3573 {
3574         int rc;
3575
3576         rc = libc_signalfd(fd, mask, flags);
3577         if (rc != -1) {
3578                 swrap_remove_stale(fd);
3579         }
3580
3581         return rc;
3582 }
3583
3584 int signalfd(int fd, const sigset_t *mask, int flags)
3585 {
3586         return swrap_signalfd(fd, mask, flags);
3587 }
3588 #endif
3589
3590 /****************************************************************************
3591  *   SOCKET
3592  ***************************************************************************/
3593
3594 static int swrap_socket(int family, int type, int protocol)
3595 {
3596         struct socket_info *si = NULL;
3597         struct socket_info _si = { 0 };
3598         int fd;
3599         int ret;
3600         int real_type = type;
3601
3602         /*
3603          * Remove possible addition flags passed to socket() so
3604          * do not fail checking the type.
3605          * See https://lwn.net/Articles/281965/
3606          */
3607 #ifdef SOCK_CLOEXEC
3608         real_type &= ~SOCK_CLOEXEC;
3609 #endif
3610 #ifdef SOCK_NONBLOCK
3611         real_type &= ~SOCK_NONBLOCK;
3612 #endif
3613
3614         if (!socket_wrapper_enabled()) {
3615                 return libc_socket(family, type, protocol);
3616         }
3617
3618         switch (family) {
3619         case AF_INET:
3620 #ifdef HAVE_IPV6
3621         case AF_INET6:
3622 #endif
3623                 break;
3624 #ifdef AF_NETLINK
3625         case AF_NETLINK:
3626 #endif /* AF_NETLINK */
3627 #ifdef AF_PACKET
3628         case AF_PACKET:
3629 #endif /* AF_PACKET */
3630         case AF_UNIX:
3631                 fd = libc_socket(family, type, protocol);
3632                 if (fd != -1) {
3633                         /* Check if we have a stale fd and remove it */
3634                         swrap_remove_stale(fd);
3635                         SWRAP_LOG(SWRAP_LOG_TRACE,
3636                                   "Unix socket fd=%d",
3637                                   fd);
3638                 }
3639                 return fd;
3640         default:
3641                 errno = EAFNOSUPPORT;
3642                 return -1;
3643         }
3644
3645         switch (real_type) {
3646         case SOCK_STREAM:
3647                 break;
3648         case SOCK_DGRAM:
3649                 break;
3650         default:
3651                 errno = EPROTONOSUPPORT;
3652                 return -1;
3653         }
3654
3655         switch (protocol) {
3656         case 0:
3657                 break;
3658         case 6:
3659                 if (real_type == SOCK_STREAM) {
3660                         break;
3661                 }
3662                 FALL_THROUGH;
3663         case 17:
3664                 if (real_type == SOCK_DGRAM) {
3665                         break;
3666                 }
3667                 FALL_THROUGH;
3668         default:
3669                 errno = EPROTONOSUPPORT;
3670                 return -1;
3671         }
3672
3673         /*
3674          * We must call libc_socket with type, from the caller, not the version
3675          * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
3676          */
3677         fd = libc_socket(AF_UNIX, type, 0);
3678
3679         if (fd == -1) {
3680                 return -1;
3681         }
3682
3683         /* Check if we have a stale fd and remove it */
3684         swrap_remove_stale(fd);
3685
3686         si = &_si;
3687         si->family = family;
3688
3689         /* however, the rest of the socket_wrapper code expects just
3690          * the type, not the flags */
3691         si->type = real_type;
3692         si->protocol = protocol;
3693
3694         /*
3695          * Setup myname so getsockname() can succeed to find out the socket
3696          * type.
3697          */
3698         switch(si->family) {
3699         case AF_INET: {
3700                 struct sockaddr_in sin = {
3701                         .sin_family = AF_INET,
3702                 };
3703
3704                 si->myname.sa_socklen = sizeof(struct sockaddr_in);
3705                 memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen);
3706                 break;
3707         }
3708 #ifdef HAVE_IPV6
3709         case AF_INET6: {
3710                 struct sockaddr_in6 sin6 = {
3711                         .sin6_family = AF_INET6,
3712                 };
3713
3714                 si->myname.sa_socklen = sizeof(struct sockaddr_in6);
3715                 memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen);
3716                 break;
3717         }
3718 #endif
3719         default:
3720                 errno = EINVAL;
3721                 return -1;
3722         }
3723
3724         ret = swrap_create_socket(si, fd);
3725         if (ret == -1) {
3726                 int saved_errno = errno;
3727                 libc_close(fd);
3728                 errno = saved_errno;
3729                 return -1;
3730         }
3731
3732         SWRAP_LOG(SWRAP_LOG_TRACE,
3733                   "Created %s socket for protocol %s, fd=%d",
3734                   family == AF_INET ? "IPv4" : "IPv6",
3735                   real_type == SOCK_DGRAM ? "UDP" : "TCP",
3736                   fd);
3737
3738         return fd;
3739 }
3740
3741 int socket(int family, int type, int protocol)
3742 {
3743         return swrap_socket(family, type, protocol);
3744 }
3745
3746 /****************************************************************************
3747  *   SOCKETPAIR
3748  ***************************************************************************/
3749
3750 static int swrap_socketpair(int family, int type, int protocol, int sv[2])
3751 {
3752         int rc;
3753
3754         rc = libc_socketpair(family, type, protocol, sv);
3755         if (rc != -1) {
3756                 swrap_remove_stale(sv[0]);
3757                 swrap_remove_stale(sv[1]);
3758         }
3759
3760         return rc;
3761 }
3762
3763 int socketpair(int family, int type, int protocol, int sv[2])
3764 {
3765         return swrap_socketpair(family, type, protocol, sv);
3766 }
3767
3768 /****************************************************************************
3769  *   SOCKETPAIR
3770  ***************************************************************************/
3771
3772 #ifdef HAVE_TIMERFD_CREATE
3773 static int swrap_timerfd_create(int clockid, int flags)
3774 {
3775         int fd;
3776
3777         fd = libc_timerfd_create(clockid, flags);
3778         if (fd != -1) {
3779                 swrap_remove_stale(fd);
3780         }
3781
3782         return fd;
3783 }
3784
3785 int timerfd_create(int clockid, int flags)
3786 {
3787         return swrap_timerfd_create(clockid, flags);
3788 }
3789 #endif
3790
3791 /****************************************************************************
3792  *   PIPE
3793  ***************************************************************************/
3794
3795 static int swrap_pipe(int pipefd[2])
3796 {
3797         int rc;
3798
3799         rc = libc_pipe(pipefd);
3800         if (rc != -1) {
3801                 swrap_remove_stale(pipefd[0]);
3802                 swrap_remove_stale(pipefd[1]);
3803         }
3804
3805         return rc;
3806 }
3807
3808 int pipe(int pipefd[2])
3809 {
3810         return swrap_pipe(pipefd);
3811 }
3812
3813 /****************************************************************************
3814  *   ACCEPT
3815  ***************************************************************************/
3816
3817 static int swrap_accept(int s,
3818                         struct sockaddr *addr,
3819                         socklen_t *addrlen,
3820                         int flags)
3821 {
3822         struct socket_info *parent_si, *child_si;
3823         struct socket_info new_si = { 0 };
3824         int fd;
3825         int idx;
3826         struct swrap_address un_addr = {
3827                 .sa_socklen = sizeof(struct sockaddr_un),
3828         };
3829         struct swrap_address un_my_addr = {
3830                 .sa_socklen = sizeof(struct sockaddr_un),
3831         };
3832         struct swrap_address in_addr = {
3833                 .sa_socklen = sizeof(struct sockaddr_storage),
3834         };
3835         struct swrap_address in_my_addr = {
3836                 .sa_socklen = sizeof(struct sockaddr_storage),
3837         };
3838         int ret;
3839
3840         parent_si = find_socket_info(s);
3841         if (!parent_si) {
3842 #ifdef HAVE_ACCEPT4
3843                 return libc_accept4(s, addr, addrlen, flags);
3844 #else
3845                 UNUSED(flags);
3846                 return libc_accept(s, addr, addrlen);
3847 #endif
3848         }
3849
3850
3851         /*
3852          * prevent parent_si from being altered / closed
3853          * while we read it
3854          */
3855         SWRAP_LOCK_SI(parent_si);
3856
3857         /*
3858          * assume out sockaddr have the same size as the in parent
3859          * socket family
3860          */
3861         in_addr.sa_socklen = socket_length(parent_si->family);
3862         if (in_addr.sa_socklen <= 0) {
3863                 SWRAP_UNLOCK_SI(parent_si);
3864                 errno = EINVAL;
3865                 return -1;
3866         }
3867
3868         SWRAP_UNLOCK_SI(parent_si);
3869
3870 #ifdef HAVE_ACCEPT4
3871         ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
3872 #else
3873         UNUSED(flags);
3874         ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
3875 #endif
3876         if (ret == -1) {
3877                 int saved_errno = errno;
3878                 if (saved_errno == ENOTSOCK) {
3879                         /* Remove stale fds */
3880                         swrap_remove_stale(s);
3881                 }
3882                 errno = saved_errno;
3883                 return ret;
3884         }
3885
3886         fd = ret;
3887
3888         /* Check if we have a stale fd and remove it */
3889         swrap_remove_stale(fd);
3890
3891         if (un_addr.sa.un.sun_path[0] == '\0') {
3892                 /*
3893                  * FreeBSD seems to have a problem where
3894                  * accept4() on the unix socket doesn't
3895                  * ECONNABORTED for already disconnected connections.
3896                  *
3897                  * Let's try libc_getpeername() to get the peer address
3898                  * as a fallback, but it'll likely return ENOTCONN,
3899                  * which we have to map to ECONNABORTED.
3900                  */
3901                 un_addr.sa_socklen = sizeof(struct sockaddr_un),
3902                 ret = libc_getpeername(fd, &un_addr.sa.s, &un_addr.sa_socklen);
3903                 if (ret == -1) {
3904                         int saved_errno = errno;
3905                         libc_close(fd);
3906                         if (saved_errno == ENOTCONN) {
3907                                 /*
3908                                  * If the connection is already disconnected
3909                                  * we should return ECONNABORTED.
3910                                  */
3911                                 saved_errno = ECONNABORTED;
3912                         }
3913                         errno = saved_errno;
3914                         return ret;
3915                 }
3916         }
3917
3918         ret = libc_getsockname(fd,
3919                                &un_my_addr.sa.s,
3920                                &un_my_addr.sa_socklen);
3921         if (ret == -1) {
3922                 int saved_errno = errno;
3923                 libc_close(fd);
3924                 if (saved_errno == ENOTCONN) {
3925                         /*
3926                          * If the connection is already disconnected
3927                          * we should return ECONNABORTED.
3928                          */
3929                         saved_errno = ECONNABORTED;
3930                 }
3931                 errno = saved_errno;
3932                 return ret;
3933         }
3934
3935         SWRAP_LOCK_SI(parent_si);
3936
3937         ret = sockaddr_convert_from_un(parent_si,
3938                                        &un_addr.sa.un,
3939                                        un_addr.sa_socklen,
3940                                        parent_si->family,
3941                                        &in_addr.sa.s,
3942                                        &in_addr.sa_socklen);
3943         if (ret == -1) {
3944                 int saved_errno = errno;
3945                 SWRAP_UNLOCK_SI(parent_si);
3946                 libc_close(fd);
3947                 errno = saved_errno;
3948                 return ret;
3949         }
3950
3951         child_si = &new_si;
3952
3953         child_si->family = parent_si->family;
3954         child_si->type = parent_si->type;
3955         child_si->protocol = parent_si->protocol;
3956         child_si->bound = 1;
3957         child_si->is_server = 1;
3958         child_si->connected = 1;
3959
3960         SWRAP_UNLOCK_SI(parent_si);
3961
3962         child_si->peername = (struct swrap_address) {
3963                 .sa_socklen = in_addr.sa_socklen,
3964         };
3965         memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
3966
3967         if (addr != NULL && addrlen != NULL) {
3968                 size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
3969                 if (copy_len > 0) {
3970                         memcpy(addr, &in_addr.sa.ss, copy_len);
3971                 }
3972                 *addrlen = in_addr.sa_socklen;
3973         }
3974
3975         ret = sockaddr_convert_from_un(child_si,
3976                                        &un_my_addr.sa.un,
3977                                        un_my_addr.sa_socklen,
3978                                        child_si->family,
3979                                        &in_my_addr.sa.s,
3980                                        &in_my_addr.sa_socklen);
3981         if (ret == -1) {
3982                 int saved_errno = errno;
3983                 libc_close(fd);
3984                 errno = saved_errno;
3985                 return ret;
3986         }
3987
3988         SWRAP_LOG(SWRAP_LOG_TRACE,
3989                   "accept() path=%s, fd=%d",
3990                   un_my_addr.sa.un.sun_path, s);
3991
3992         child_si->myname = (struct swrap_address) {
3993                 .sa_socklen = in_my_addr.sa_socklen,
3994         };
3995         memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
3996
3997         idx = swrap_create_socket(&new_si, fd);
3998         if (idx == -1) {
3999                 int saved_errno = errno;
4000                 libc_close(fd);
4001                 errno = saved_errno;
4002                 return -1;
4003         }
4004
4005         if (addr != NULL) {
4006                 struct socket_info *si = swrap_get_socket_info(idx);
4007
4008                 SWRAP_LOCK_SI(si);
4009                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
4010                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
4011                 swrap_pcap_dump_packet(si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
4012                 SWRAP_UNLOCK_SI(si);
4013         }
4014
4015         return fd;
4016 }
4017
4018 #ifdef HAVE_ACCEPT4
4019 int accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
4020 {
4021         return swrap_accept(s, addr, (socklen_t *)addrlen, flags);
4022 }
4023 #endif
4024
4025 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4026 int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
4027 #else
4028 int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
4029 #endif
4030 {
4031         return swrap_accept(s, addr, (socklen_t *)addrlen, 0);
4032 }
4033
4034 static int autobind_start_init;
4035 static int autobind_start;
4036
4037 /* using sendto() or connect() on an unbound socket would give the
4038    recipient no way to reply, as unlike UDP and TCP, a unix domain
4039    socket can't auto-assign ephemeral port numbers, so we need to
4040    assign it here.
4041    Note: this might change the family from ipv6 to ipv4
4042 */
4043 static int swrap_auto_bind(int fd, struct socket_info *si, int family)
4044 {
4045         struct swrap_address un_addr = {
4046                 .sa_socklen = sizeof(struct sockaddr_un),
4047         };
4048         int i;
4049         char type;
4050         int ret;
4051         int port;
4052         char *swrap_dir = NULL;
4053
4054         swrap_mutex_lock(&autobind_start_mutex);
4055
4056         if (autobind_start_init != 1) {
4057                 autobind_start_init = 1;
4058                 autobind_start = getpid();
4059                 autobind_start %= 50000;
4060                 autobind_start += 10000;
4061         }
4062
4063         un_addr.sa.un.sun_family = AF_UNIX;
4064
4065         switch (family) {
4066         case AF_INET: {
4067                 struct sockaddr_in in;
4068
4069                 switch (si->type) {
4070                 case SOCK_STREAM:
4071                         type = SOCKET_TYPE_CHAR_TCP;
4072                         break;
4073                 case SOCK_DGRAM:
4074                         type = SOCKET_TYPE_CHAR_UDP;
4075                         break;
4076                 default:
4077                         errno = ESOCKTNOSUPPORT;
4078                         ret = -1;
4079                         goto done;
4080                 }
4081
4082                 memset(&in, 0, sizeof(in));
4083                 in.sin_family = AF_INET;
4084                 in.sin_addr.s_addr = htonl(swrap_ipv4_iface(
4085                                            socket_wrapper_default_iface()));
4086
4087                 si->myname = (struct swrap_address) {
4088                         .sa_socklen = sizeof(in),
4089                 };
4090                 memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
4091                 break;
4092         }
4093 #ifdef HAVE_IPV6
4094         case AF_INET6: {
4095                 struct sockaddr_in6 in6;
4096
4097                 if (si->family != family) {
4098                         errno = ENETUNREACH;
4099                         ret = -1;
4100                         goto done;
4101                 }
4102
4103                 switch (si->type) {
4104                 case SOCK_STREAM:
4105                         type = SOCKET_TYPE_CHAR_TCP_V6;
4106                         break;
4107                 case SOCK_DGRAM:
4108                         type = SOCKET_TYPE_CHAR_UDP_V6;
4109                         break;
4110                 default:
4111                         errno = ESOCKTNOSUPPORT;
4112                         ret = -1;
4113                         goto done;
4114                 }
4115
4116                 memset(&in6, 0, sizeof(in6));
4117                 in6.sin6_family = AF_INET6;
4118                 in6.sin6_addr = *swrap_ipv6();
4119                 in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
4120
4121                 si->myname = (struct swrap_address) {
4122                         .sa_socklen = sizeof(in6),
4123                 };
4124                 memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
4125                 break;
4126         }
4127 #endif
4128         default:
4129                 errno = ESOCKTNOSUPPORT;
4130                 ret = -1;
4131                 goto done;
4132         }
4133
4134         if (autobind_start > 60000) {
4135                 autobind_start = 10000;
4136         }
4137
4138         swrap_dir = socket_wrapper_dir();
4139         if (swrap_dir == NULL) {
4140                 errno = EINVAL;
4141                 ret = -1;
4142                 goto done;
4143         }
4144
4145         for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
4146                 port = autobind_start + i;
4147                 swrap_un_path(&un_addr.sa.un,
4148                               swrap_dir,
4149                               type,
4150                               socket_wrapper_default_iface(),
4151                               port);
4152
4153                 ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
4154                 if (ret == -1) {
4155                         if (errno == EALREADY || errno == EADDRINUSE) {
4156                                 continue;
4157                         }
4158                         goto done;
4159                 }
4160
4161                 si->un_addr = un_addr.sa.un;
4162
4163                 si->bound = 1;
4164                 autobind_start = port + 1;
4165                 break;
4166         }
4167         if (i == SOCKET_MAX_SOCKETS) {
4168                 SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
4169                                            "interface "SOCKET_FORMAT,
4170                                            SOCKET_MAX_SOCKETS,
4171                                            type,
4172                                            socket_wrapper_default_iface(),
4173                                            0);
4174                 errno = ENFILE;
4175                 ret = -1;
4176                 goto done;
4177         }
4178
4179         si->family = family;
4180         set_port(si->family, port, &si->myname);
4181
4182         ret = 0;
4183
4184 done:
4185         SAFE_FREE(swrap_dir);
4186         swrap_mutex_unlock(&autobind_start_mutex);
4187         return ret;
4188 }
4189
4190 /****************************************************************************
4191  *   CONNECT
4192  ***************************************************************************/
4193
4194 static int swrap_connect(int s, const struct sockaddr *serv_addr,
4195                          socklen_t addrlen)
4196 {
4197         int ret;
4198         struct swrap_address un_addr = {
4199                 .sa_socklen = sizeof(struct sockaddr_un),
4200         };
4201         struct socket_info *si = find_socket_info(s);
4202         struct swrap_sockaddr_buf buf = {};
4203         int bcast = 0;
4204
4205         if (!si) {
4206                 return libc_connect(s, serv_addr, addrlen);
4207         }
4208
4209         SWRAP_LOCK_SI(si);
4210
4211         if (si->bound == 0) {
4212                 ret = swrap_auto_bind(s, si, serv_addr->sa_family);
4213                 if (ret == -1) {
4214                         goto done;
4215                 }
4216         }
4217
4218         if (si->family != serv_addr->sa_family) {
4219                 SWRAP_LOG(SWRAP_LOG_ERROR,
4220                           "called for fd=%d (family=%d) called with invalid family=%d",
4221                           s, si->family, serv_addr->sa_family);
4222                 errno = EINVAL;
4223                 ret = -1;
4224                 goto done;
4225         }
4226
4227         ret = sockaddr_convert_to_un(si, serv_addr,
4228                                      addrlen, &un_addr.sa.un, 0, &bcast);
4229         if (ret == -1) {
4230                 goto done;
4231         }
4232
4233         if (bcast) {
4234                 errno = ENETUNREACH;
4235                 ret = -1;
4236                 goto done;
4237         }
4238
4239         if (si->type == SOCK_DGRAM) {
4240                 si->defer_connect = 1;
4241                 ret = 0;
4242         } else {
4243                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
4244
4245                 ret = libc_connect(s,
4246                                    &un_addr.sa.s,
4247                                    un_addr.sa_socklen);
4248         }
4249
4250         SWRAP_LOG(SWRAP_LOG_TRACE,
4251                   "connect(%s) path=%s, fd=%d",
4252                   swrap_sockaddr_string(&buf, serv_addr),
4253                   un_addr.sa.un.sun_path, s);
4254
4255
4256         /* to give better errors */
4257         if (ret == -1 && errno == ENOENT) {
4258                 errno = EHOSTUNREACH;
4259         }
4260
4261         if (ret == 0) {
4262                 si->peername = (struct swrap_address) {
4263                         .sa_socklen = addrlen,
4264                 };
4265
4266                 memcpy(&si->peername.sa.ss, serv_addr, addrlen);
4267                 si->connected = 1;
4268
4269                 /*
4270                  * When we connect() on a socket than we have to bind the
4271                  * outgoing connection on the interface we use for the
4272                  * transport. We already bound it on the right interface
4273                  * but here we have to update the name so getsockname()
4274                  * returns correct information.
4275                  */
4276                 if (si->bindname.sa_socklen > 0) {
4277                         si->myname = (struct swrap_address) {
4278                                 .sa_socklen = si->bindname.sa_socklen,
4279                         };
4280
4281                         memcpy(&si->myname.sa.ss,
4282                                &si->bindname.sa.ss,
4283                                si->bindname.sa_socklen);
4284
4285                         /* Cleanup bindname */
4286                         si->bindname = (struct swrap_address) {
4287                                 .sa_socklen = 0,
4288                         };
4289                 }
4290
4291                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
4292                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
4293         } else {
4294                 swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
4295         }
4296
4297 done:
4298         SWRAP_UNLOCK_SI(si);
4299         return ret;
4300 }
4301
4302 int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
4303 {
4304         return swrap_connect(s, serv_addr, addrlen);
4305 }
4306
4307 /****************************************************************************
4308  *   BIND
4309  ***************************************************************************/
4310
4311 static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
4312 {
4313         int ret;
4314         struct swrap_address un_addr = {
4315                 .sa_socklen = sizeof(struct sockaddr_un),
4316         };
4317         struct socket_info *si = find_socket_info(s);
4318         struct swrap_sockaddr_buf buf = {};
4319         int ret_errno = errno;
4320         int bind_error = 0;
4321 #if 0 /* FIXME */
4322         bool in_use;
4323 #endif
4324
4325         if (!si) {
4326                 return libc_bind(s, myaddr, addrlen);
4327         }
4328
4329         SWRAP_LOCK_SI(si);
4330
4331         switch (si->family) {
4332         case AF_INET: {
4333                 const struct sockaddr_in *sin;
4334                 if (addrlen < sizeof(struct sockaddr_in)) {
4335                         bind_error = EINVAL;
4336                         break;
4337                 }
4338
4339                 sin = (const struct sockaddr_in *)(const void *)myaddr;
4340
4341                 if (sin->sin_family != AF_INET) {
4342                         bind_error = EAFNOSUPPORT;
4343                 }
4344
4345                 /* special case for AF_UNSPEC */
4346                 if (sin->sin_family == AF_UNSPEC &&
4347                     (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
4348                 {
4349                         bind_error = 0;
4350                 }
4351
4352                 break;
4353         }
4354 #ifdef HAVE_IPV6
4355         case AF_INET6: {
4356                 const struct sockaddr_in6 *sin6;
4357                 if (addrlen < sizeof(struct sockaddr_in6)) {
4358                         bind_error = EINVAL;
4359                         break;
4360                 }
4361
4362                 sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
4363
4364                 if (sin6->sin6_family != AF_INET6) {
4365                         bind_error = EAFNOSUPPORT;
4366                 }
4367
4368                 break;
4369         }
4370 #endif
4371         default:
4372                 bind_error = EINVAL;
4373                 break;
4374         }
4375
4376         if (bind_error != 0) {
4377                 ret_errno = bind_error;
4378                 ret = -1;
4379                 goto out;
4380         }
4381
4382 #if 0 /* FIXME */
4383         in_use = check_addr_port_in_use(myaddr, addrlen);
4384         if (in_use) {
4385                 errno = EADDRINUSE;
4386                 ret = -1;
4387                 goto out;
4388         }
4389 #endif
4390
4391         si->myname.sa_socklen = addrlen;
4392         memcpy(&si->myname.sa.ss, myaddr, addrlen);
4393
4394         ret = sockaddr_convert_to_un(si,
4395                                      myaddr,
4396                                      addrlen,
4397                                      &un_addr.sa.un,
4398                                      1,
4399                                      &si->bcast);
4400         if (ret == -1) {
4401                 ret_errno = errno;
4402                 goto out;
4403         }
4404
4405         unlink(un_addr.sa.un.sun_path);
4406
4407         ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
4408         if (ret == -1) {
4409                 ret_errno = errno;
4410         }
4411
4412         SWRAP_LOG(SWRAP_LOG_TRACE,
4413                   "bind(%s) path=%s, fd=%d ret=%d ret_errno=%d",
4414                   swrap_sockaddr_string(&buf, myaddr),
4415                   un_addr.sa.un.sun_path, s, ret, ret_errno);
4416
4417         if (ret == 0) {
4418                 si->bound = 1;
4419         }
4420
4421 out:
4422         SWRAP_UNLOCK_SI(si);
4423         errno = ret_errno;
4424         return ret;
4425 }
4426
4427 int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
4428 {
4429         return swrap_bind(s, myaddr, addrlen);
4430 }
4431
4432 /****************************************************************************
4433  *   BINDRESVPORT
4434  ***************************************************************************/
4435
4436 #ifdef HAVE_BINDRESVPORT
4437 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
4438
4439 static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
4440 {
4441         struct swrap_address myaddr = {
4442                 .sa_socklen = sizeof(struct sockaddr_storage),
4443         };
4444         socklen_t salen;
4445         static uint16_t port;
4446         uint16_t i;
4447         int rc = -1;
4448         int af;
4449
4450 #define SWRAP_STARTPORT 600
4451 #define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
4452 #define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
4453
4454         if (port == 0) {
4455                 port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
4456         }
4457
4458         if (sa == NULL) {
4459                 salen = myaddr.sa_socklen;
4460                 sa = &myaddr.sa.s;
4461
4462                 rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
4463                 if (rc < 0) {
4464                         return -1;
4465                 }
4466
4467                 af = sa->sa_family;
4468                 memset(&myaddr.sa.ss, 0, salen);
4469         } else {
4470                 af = sa->sa_family;
4471         }
4472
4473         for (i = 0; i < SWRAP_NPORTS; i++, port++) {
4474                 switch(af) {
4475                 case AF_INET: {
4476                         struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
4477
4478                         salen = sizeof(struct sockaddr_in);
4479                         sinp->sin_port = htons(port);
4480                         break;
4481                 }
4482                 case AF_INET6: {
4483                         struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
4484
4485                         salen = sizeof(struct sockaddr_in6);
4486                         sin6p->sin6_port = htons(port);
4487                         break;
4488                 }
4489                 default:
4490                         errno = EAFNOSUPPORT;
4491                         return -1;
4492                 }
4493                 sa->sa_family = af;
4494
4495                 if (port > SWRAP_ENDPORT) {
4496                         port = SWRAP_STARTPORT;
4497                 }
4498
4499                 rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
4500                 if (rc == 0 || errno != EADDRINUSE) {
4501                         break;
4502                 }
4503         }
4504
4505         return rc;
4506 }
4507
4508 int bindresvport(int sockfd, struct sockaddr_in *sinp)
4509 {
4510         return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
4511 }
4512 #endif
4513
4514 /****************************************************************************
4515  *   LISTEN
4516  ***************************************************************************/
4517
4518 static int swrap_listen(int s, int backlog)
4519 {
4520         int ret;
4521         struct socket_info *si = find_socket_info(s);
4522
4523         if (!si) {
4524                 return libc_listen(s, backlog);
4525         }
4526
4527         SWRAP_LOCK_SI(si);
4528
4529         if (si->bound == 0) {
4530                 ret = swrap_auto_bind(s, si, si->family);
4531                 if (ret == -1) {
4532                         errno = EADDRINUSE;
4533                         goto out;
4534                 }
4535         }
4536
4537         ret = libc_listen(s, backlog);
4538         if (ret == 0) {
4539                 si->listening = 1;
4540         }
4541
4542 out:
4543         SWRAP_UNLOCK_SI(si);
4544
4545         return ret;
4546 }
4547
4548 int listen(int s, int backlog)
4549 {
4550         return swrap_listen(s, backlog);
4551 }
4552
4553 /****************************************************************************
4554  *   FOPEN
4555  ***************************************************************************/
4556
4557 static FILE *swrap_fopen(const char *name, const char *mode)
4558 {
4559         FILE *fp;
4560
4561         fp = libc_fopen(name, mode);
4562         if (fp != NULL) {
4563                 int fd = fileno(fp);
4564
4565                 swrap_remove_stale(fd);
4566         }
4567
4568         return fp;
4569 }
4570
4571 FILE *fopen(const char *name, const char *mode)
4572 {
4573         return swrap_fopen(name, mode);
4574 }
4575
4576 /****************************************************************************
4577  *   FOPEN64
4578  ***************************************************************************/
4579
4580 #ifdef HAVE_FOPEN64
4581 static FILE *swrap_fopen64(const char *name, const char *mode)
4582 {
4583         FILE *fp;
4584
4585         fp = libc_fopen64(name, mode);
4586         if (fp != NULL) {
4587                 int fd = fileno(fp);
4588
4589                 swrap_remove_stale(fd);
4590         }
4591
4592         return fp;
4593 }
4594
4595 FILE *fopen64(const char *name, const char *mode)
4596 {
4597         return swrap_fopen64(name, mode);
4598 }
4599 #endif /* HAVE_FOPEN64 */
4600
4601 /****************************************************************************
4602  *   OPEN
4603  ***************************************************************************/
4604
4605 static int swrap_vopen(const char *pathname, int flags, va_list ap)
4606 {
4607         int ret;
4608
4609         ret = libc_vopen(pathname, flags, ap);
4610         if (ret != -1) {
4611                 /*
4612                  * There are methods for closing descriptors (libc-internal code
4613                  * paths, direct syscalls) which close descriptors in ways that
4614                  * we can't intercept, so try to recover when we notice that
4615                  * that's happened
4616                  */
4617                 swrap_remove_stale(ret);
4618         }
4619         return ret;
4620 }
4621
4622 int open(const char *pathname, int flags, ...)
4623 {
4624         va_list ap;
4625         int fd;
4626
4627         va_start(ap, flags);
4628         fd = swrap_vopen(pathname, flags, ap);
4629         va_end(ap);
4630
4631         return fd;
4632 }
4633
4634 /****************************************************************************
4635  *   OPEN64
4636  ***************************************************************************/
4637
4638 #ifdef HAVE_OPEN64
4639 static int swrap_vopen64(const char *pathname, int flags, va_list ap)
4640 {
4641         int ret;
4642
4643         ret = libc_vopen64(pathname, flags, ap);
4644         if (ret != -1) {
4645                 /*
4646                  * There are methods for closing descriptors (libc-internal code
4647                  * paths, direct syscalls) which close descriptors in ways that
4648                  * we can't intercept, so try to recover when we notice that
4649                  * that's happened
4650                  */
4651                 swrap_remove_stale(ret);
4652         }
4653         return ret;
4654 }
4655
4656 int open64(const char *pathname, int flags, ...)
4657 {
4658         va_list ap;
4659         int fd;
4660
4661         va_start(ap, flags);
4662         fd = swrap_vopen64(pathname, flags, ap);
4663         va_end(ap);
4664
4665         return fd;
4666 }
4667 #endif /* HAVE_OPEN64 */
4668
4669 /****************************************************************************
4670  *   OPENAT
4671  ***************************************************************************/
4672
4673 static int swrap_vopenat(int dirfd, const char *path, int flags, va_list ap)
4674 {
4675         int ret;
4676
4677         ret = libc_vopenat(dirfd, path, flags, ap);
4678         if (ret != -1) {
4679                 /*
4680                  * There are methods for closing descriptors (libc-internal code
4681                  * paths, direct syscalls) which close descriptors in ways that
4682                  * we can't intercept, so try to recover when we notice that
4683                  * that's happened
4684                  */
4685                 swrap_remove_stale(ret);
4686         }
4687
4688         return ret;
4689 }
4690
4691 int openat(int dirfd, const char *path, int flags, ...)
4692 {
4693         va_list ap;
4694         int fd;
4695
4696         va_start(ap, flags);
4697         fd = swrap_vopenat(dirfd, path, flags, ap);
4698         va_end(ap);
4699
4700         return fd;
4701 }
4702
4703 /****************************************************************************
4704  *   GETPEERNAME
4705  ***************************************************************************/
4706
4707 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
4708 {
4709         struct socket_info *si = find_socket_info(s);
4710         socklen_t len;
4711         int ret = -1;
4712
4713         if (!si) {
4714                 return libc_getpeername(s, name, addrlen);
4715         }
4716
4717         SWRAP_LOCK_SI(si);
4718
4719         if (si->peername.sa_socklen == 0)
4720         {
4721                 errno = ENOTCONN;
4722                 goto out;
4723         }
4724
4725         len = MIN(*addrlen, si->peername.sa_socklen);
4726         if (len == 0) {
4727                 ret = 0;
4728                 goto out;
4729         }
4730
4731         memcpy(name, &si->peername.sa.ss, len);
4732         *addrlen = si->peername.sa_socklen;
4733
4734         ret = 0;
4735 out:
4736         SWRAP_UNLOCK_SI(si);
4737
4738         return ret;
4739 }
4740
4741 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4742 int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
4743 #else
4744 int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
4745 #endif
4746 {
4747         return swrap_getpeername(s, name, (socklen_t *)addrlen);
4748 }
4749
4750 /****************************************************************************
4751  *   GETSOCKNAME
4752  ***************************************************************************/
4753
4754 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
4755 {
4756         struct socket_info *si = find_socket_info(s);
4757         socklen_t len;
4758         int ret = -1;
4759
4760         if (!si) {
4761                 return libc_getsockname(s, name, addrlen);
4762         }
4763
4764         SWRAP_LOCK_SI(si);
4765
4766         len = MIN(*addrlen, si->myname.sa_socklen);
4767         if (len == 0) {
4768                 ret = 0;
4769                 goto out;
4770         }
4771
4772         memcpy(name, &si->myname.sa.ss, len);
4773         *addrlen = si->myname.sa_socklen;
4774
4775         ret = 0;
4776 out:
4777         SWRAP_UNLOCK_SI(si);
4778
4779         return ret;
4780 }
4781
4782 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4783 int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
4784 #else
4785 int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
4786 #endif
4787 {
4788         return swrap_getsockname(s, name, (socklen_t *)addrlen);
4789 }
4790
4791 /****************************************************************************
4792  *   GETSOCKOPT
4793  ***************************************************************************/
4794
4795 #ifndef SO_PROTOCOL
4796 # ifdef SO_PROTOTYPE /* The Solaris name */
4797 #  define SO_PROTOCOL SO_PROTOTYPE
4798 # endif /* SO_PROTOTYPE */
4799 #endif /* SO_PROTOCOL */
4800
4801 static int swrap_getsockopt(int s, int level, int optname,
4802                             void *optval, socklen_t *optlen)
4803 {
4804         struct socket_info *si = find_socket_info(s);
4805         int ret;
4806
4807         if (!si) {
4808                 return libc_getsockopt(s,
4809                                        level,
4810                                        optname,
4811                                        optval,
4812                                        optlen);
4813         }
4814
4815         SWRAP_LOCK_SI(si);
4816
4817         if (level == SOL_SOCKET) {
4818                 switch (optname) {
4819 #ifdef SO_DOMAIN
4820                 case SO_DOMAIN:
4821                         if (optval == NULL || optlen == NULL ||
4822                             *optlen < (socklen_t)sizeof(int)) {
4823                                 errno = EINVAL;
4824                                 ret = -1;
4825                                 goto done;
4826                         }
4827
4828                         *optlen = sizeof(int);
4829                         *(int *)optval = si->family;
4830                         ret = 0;
4831                         goto done;
4832 #endif /* SO_DOMAIN */
4833
4834 #ifdef SO_PROTOCOL
4835                 case SO_PROTOCOL:
4836                         if (optval == NULL || optlen == NULL ||
4837                             *optlen < (socklen_t)sizeof(int)) {
4838                                 errno = EINVAL;
4839                                 ret = -1;
4840                                 goto done;
4841                         }
4842
4843                         *optlen = sizeof(int);
4844                         *(int *)optval = si->protocol;
4845                         ret = 0;
4846                         goto done;
4847 #endif /* SO_PROTOCOL */
4848                 case SO_TYPE:
4849                         if (optval == NULL || optlen == NULL ||
4850                             *optlen < (socklen_t)sizeof(int)) {
4851                                 errno = EINVAL;
4852                                 ret = -1;
4853                                 goto done;
4854                         }
4855
4856                         *optlen = sizeof(int);
4857                         *(int *)optval = si->type;
4858                         ret = 0;
4859                         goto done;
4860                 default:
4861                         ret = libc_getsockopt(s,
4862                                               level,
4863                                               optname,
4864                                               optval,
4865                                               optlen);
4866                         goto done;
4867                 }
4868         } else if (level == IPPROTO_TCP) {
4869                 switch (optname) {
4870 #ifdef TCP_NODELAY
4871                 case TCP_NODELAY:
4872                         /*
4873                          * This enables sending packets directly out over TCP.
4874                          * As a unix socket is doing that any way, report it as
4875                          * enabled.
4876                          */
4877                         if (optval == NULL || optlen == NULL ||
4878                             *optlen < (socklen_t)sizeof(int)) {
4879                                 errno = EINVAL;
4880                                 ret = -1;
4881                                 goto done;
4882                         }
4883
4884                         *optlen = sizeof(int);
4885                         *(int *)optval = si->tcp_nodelay;
4886
4887                         ret = 0;
4888                         goto done;
4889 #endif /* TCP_NODELAY */
4890 #ifdef TCP_INFO
4891                 case TCP_INFO: {
4892                         struct tcp_info info;
4893                         socklen_t ilen = sizeof(info);
4894
4895 #ifdef HAVE_NETINET_TCP_FSM_H
4896 /* This is FreeBSD */
4897 # define __TCP_LISTEN TCPS_LISTEN
4898 # define __TCP_ESTABLISHED TCPS_ESTABLISHED
4899 # define __TCP_CLOSE TCPS_CLOSED
4900 #else
4901 /* This is Linux */
4902 # define __TCP_LISTEN TCP_LISTEN
4903 # define __TCP_ESTABLISHED TCP_ESTABLISHED
4904 # define __TCP_CLOSE TCP_CLOSE
4905 #endif
4906
4907                         ZERO_STRUCT(info);
4908                         if (si->listening) {
4909                                 info.tcpi_state = __TCP_LISTEN;
4910                         } else if (si->connected) {
4911                                 /*
4912                                  * For now we just fake a few values
4913                                  * supported both by FreeBSD and Linux
4914                                  */
4915                                 info.tcpi_state = __TCP_ESTABLISHED;
4916                                 info.tcpi_rto = 200000;  /* 200 msec */
4917                                 info.tcpi_rtt = 5000;    /* 5 msec */
4918                                 info.tcpi_rttvar = 5000; /* 5 msec */
4919                         } else {
4920                                 info.tcpi_state = __TCP_CLOSE;
4921                                 info.tcpi_rto = 1000000;  /* 1 sec */
4922                                 info.tcpi_rtt = 0;
4923                                 info.tcpi_rttvar = 250000; /* 250 msec */
4924                         }
4925
4926                         if (optval == NULL || optlen == NULL ||
4927                             *optlen < (socklen_t)ilen) {
4928                                 errno = EINVAL;
4929                                 ret = -1;
4930                                 goto done;
4931                         }
4932
4933                         *optlen = ilen;
4934                         memcpy(optval, &info, ilen);
4935
4936                         ret = 0;
4937                         goto done;
4938                 }
4939 #endif /* TCP_INFO */
4940                 default:
4941                         break;
4942                 }
4943         }
4944
4945         errno = ENOPROTOOPT;
4946         ret = -1;
4947
4948 done:
4949         SWRAP_UNLOCK_SI(si);
4950         return ret;
4951 }
4952
4953 #ifdef HAVE_ACCEPT_PSOCKLEN_T
4954 int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
4955 #else
4956 int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
4957 #endif
4958 {
4959         return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
4960 }
4961
4962 /****************************************************************************
4963  *   SETSOCKOPT
4964  ***************************************************************************/
4965
4966 static int swrap_setsockopt(int s, int level, int optname,
4967                             const void *optval, socklen_t optlen)
4968 {
4969         struct socket_info *si = find_socket_info(s);
4970         int ret;
4971
4972         if (!si) {
4973                 return libc_setsockopt(s,
4974                                        level,
4975                                        optname,
4976                                        optval,
4977                                        optlen);
4978         }
4979
4980         if (level == SOL_SOCKET) {
4981                 return libc_setsockopt(s,
4982                                        level,
4983                                        optname,
4984                                        optval,
4985                                        optlen);
4986         }
4987
4988         SWRAP_LOCK_SI(si);
4989
4990         if (level == IPPROTO_TCP) {
4991                 switch (optname) {
4992 #ifdef TCP_NODELAY
4993                 case TCP_NODELAY: {
4994                         int i;
4995
4996                         /*
4997                          * This enables sending packets directly out over TCP.
4998                          * A unix socket is doing that any way.
4999                          */
5000                         if (optval == NULL || optlen == 0 ||
5001                             optlen < (socklen_t)sizeof(int)) {
5002                                 errno = EINVAL;
5003                                 ret = -1;
5004                                 goto done;
5005                         }
5006
5007                         i = *discard_const_p(int, optval);
5008                         if (i != 0 && i != 1) {
5009                                 errno = EINVAL;
5010                                 ret = -1;
5011                                 goto done;
5012                         }
5013                         si->tcp_nodelay = i;
5014
5015                         ret = 0;
5016                         goto done;
5017                 }
5018 #endif /* TCP_NODELAY */
5019                 default:
5020                         break;
5021                 }
5022         }
5023
5024         switch (si->family) {
5025         case AF_INET:
5026                 if (level == IPPROTO_IP) {
5027 #ifdef IP_PKTINFO
5028                         if (optname == IP_PKTINFO) {
5029                                 si->pktinfo = AF_INET;
5030                         }
5031 #endif /* IP_PKTINFO */
5032                 }
5033                 ret = 0;
5034                 goto done;
5035 #ifdef HAVE_IPV6
5036         case AF_INET6:
5037                 if (level == IPPROTO_IPV6) {
5038 #ifdef IPV6_RECVPKTINFO
5039                         if (optname == IPV6_RECVPKTINFO) {
5040                                 si->pktinfo = AF_INET6;
5041                         }
5042 #endif /* IPV6_PKTINFO */
5043                 }
5044                 ret = 0;
5045                 goto done;
5046 #endif
5047         default:
5048                 errno = ENOPROTOOPT;
5049                 ret = -1;
5050                 goto done;
5051         }
5052
5053 done:
5054         SWRAP_UNLOCK_SI(si);
5055         return ret;
5056 }
5057
5058 int setsockopt(int s, int level, int optname,
5059                const void *optval, socklen_t optlen)
5060 {
5061         return swrap_setsockopt(s, level, optname, optval, optlen);
5062 }
5063
5064 /****************************************************************************
5065  *   IOCTL
5066  ***************************************************************************/
5067
5068 static int swrap_vioctl(int s, unsigned long int r, va_list va)
5069 {
5070         struct socket_info *si = find_socket_info(s);
5071         va_list ap;
5072         int *value_ptr = NULL;
5073         int rc;
5074
5075         if (!si) {
5076                 return libc_vioctl(s, r, va);
5077         }
5078
5079         SWRAP_LOCK_SI(si);
5080
5081         va_copy(ap, va);
5082
5083         rc = libc_vioctl(s, r, va);
5084
5085         switch (r) {
5086         case FIONREAD:
5087                 if (rc == 0) {
5088                         value_ptr = ((int *)va_arg(ap, int *));
5089                 }
5090
5091                 if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
5092                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
5093                 } else if (value_ptr != NULL && *value_ptr == 0) { /* END OF FILE */
5094                         swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
5095                 }
5096                 break;
5097 #ifdef FIONWRITE
5098         case FIONWRITE:
5099                 /* this is FreeBSD */
5100                 FALL_THROUGH; /* to TIOCOUTQ */
5101 #endif /* FIONWRITE */
5102         case TIOCOUTQ: /* same as SIOCOUTQ on Linux */
5103                 /*
5104                  * This may return more bytes then the application
5105                  * sent into the socket, for tcp it should
5106                  * return the number of unacked bytes.
5107                  *
5108                  * On AF_UNIX, all bytes are immediately acked!
5109                  */
5110                 if (rc == 0) {
5111                         value_ptr = ((int *)va_arg(ap, int *));
5112                         *value_ptr = 0;
5113                 }
5114                 break;
5115         }
5116
5117         va_end(ap);
5118
5119         SWRAP_UNLOCK_SI(si);
5120         return rc;
5121 }
5122
5123 #ifdef HAVE_IOCTL_INT
5124 int ioctl(int s, int r, ...)
5125 #else
5126 int ioctl(int s, unsigned long int r, ...)
5127 #endif
5128 {
5129         va_list va;
5130         int rc;
5131
5132         va_start(va, r);
5133
5134         rc = swrap_vioctl(s, (unsigned long int) r, va);
5135
5136         va_end(va);
5137
5138         return rc;
5139 }
5140
5141 /*****************
5142  * CMSG
5143  *****************/
5144
5145 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
5146
5147 #ifndef CMSG_ALIGN
5148 # ifdef _ALIGN /* BSD */
5149 #define CMSG_ALIGN _ALIGN
5150 # else
5151 #define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
5152 # endif /* _ALIGN */
5153 #endif /* CMSG_ALIGN */
5154
5155 /**
5156  * @brief Add a cmsghdr to a msghdr.
5157  *
5158  * This is an function to add any type of cmsghdr. It will operate on the
5159  * msg->msg_control and msg->msg_controllen you pass in by adapting them to
5160  * the buffer position after the added cmsg element. Hence, this function is
5161  * intended to be used with an intermediate msghdr and not on the original
5162  * one handed in by the client.
5163  *
5164  * @param[in]  msg      The msghdr to which to add the cmsg.
5165  *
5166  * @param[in]  level    The cmsg level to set.
5167  *
5168  * @param[in]  type     The cmsg type to set.
5169  *
5170  * @param[in]  data     The cmsg data to set.
5171  *
5172  * @param[in]  len      the length of the data to set.
5173  */
5174 static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
5175                                      int level,
5176                                      int type,
5177                                      const void *data,
5178                                      size_t len)
5179 {
5180         size_t cmlen = CMSG_LEN(len);
5181         size_t cmspace = CMSG_SPACE(len);
5182         uint8_t cmbuf[cmspace];
5183         void *cast_ptr = (void *)cmbuf;
5184         struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
5185         uint8_t *p;
5186
5187         memset(cmbuf, 0, cmspace);
5188
5189         if (msg->msg_controllen < cmlen) {
5190                 cmlen = msg->msg_controllen;
5191                 msg->msg_flags |= MSG_CTRUNC;
5192         }
5193
5194         if (msg->msg_controllen < cmspace) {
5195                 cmspace = msg->msg_controllen;
5196         }
5197
5198         /*
5199          * We copy the full input data into an intermediate cmsghdr first
5200          * in order to more easily cope with truncation.
5201          */
5202         cm->cmsg_len = cmlen;
5203         cm->cmsg_level = level;
5204         cm->cmsg_type = type;
5205         memcpy(CMSG_DATA(cm), data, len);
5206
5207         /*
5208          * We now copy the possibly truncated buffer.
5209          * We copy cmlen bytes, but consume cmspace bytes,
5210          * leaving the possible padding uninitialiazed.
5211          */
5212         p = (uint8_t *)msg->msg_control;
5213         memcpy(p, cm, cmlen);
5214         p += cmspace;
5215         msg->msg_control = p;
5216         msg->msg_controllen -= cmspace;
5217
5218         return;
5219 }
5220
5221 static int swrap_msghdr_add_pktinfo(struct socket_info *si,
5222                                     struct msghdr *msg)
5223 {
5224         /* Add packet info */
5225         switch (si->pktinfo) {
5226 #if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
5227         case AF_INET: {
5228                 struct sockaddr_in *sin;
5229 #if defined(HAVE_STRUCT_IN_PKTINFO)
5230                 struct in_pktinfo pkt;
5231 #elif defined(IP_RECVDSTADDR)
5232                 struct in_addr pkt;
5233 #endif
5234
5235                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
5236                         sin = &si->bindname.sa.in;
5237                 } else {
5238                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
5239                                 return 0;
5240                         }
5241                         sin = &si->myname.sa.in;
5242                 }
5243
5244                 ZERO_STRUCT(pkt);
5245
5246 #if defined(HAVE_STRUCT_IN_PKTINFO)
5247                 pkt.ipi_ifindex = socket_wrapper_default_iface();
5248                 pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
5249 #elif defined(IP_RECVDSTADDR)
5250                 pkt = sin->sin_addr;
5251 #endif
5252
5253                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
5254                                          &pkt, sizeof(pkt));
5255
5256                 break;
5257         }
5258 #endif /* IP_PKTINFO */
5259 #if defined(HAVE_IPV6)
5260         case AF_INET6: {
5261 #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
5262                 struct sockaddr_in6 *sin6;
5263                 struct in6_pktinfo pkt6;
5264
5265                 if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
5266                         sin6 = &si->bindname.sa.in6;
5267                 } else {
5268                         if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
5269                                 return 0;
5270                         }
5271                         sin6 = &si->myname.sa.in6;
5272                 }
5273
5274                 ZERO_STRUCT(pkt6);
5275
5276                 pkt6.ipi6_ifindex = socket_wrapper_default_iface();
5277                 pkt6.ipi6_addr = sin6->sin6_addr;
5278
5279                 swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
5280                                         &pkt6, sizeof(pkt6));
5281 #endif /* HAVE_STRUCT_IN6_PKTINFO */
5282
5283                 break;
5284         }
5285 #endif /* IPV6_PKTINFO */
5286         default:
5287                 return -1;
5288         }
5289
5290         return 0;
5291 }
5292
5293 static int swrap_msghdr_add_socket_info(struct socket_info *si,
5294                                         struct msghdr *omsg)
5295 {
5296         int rc = 0;
5297
5298         if (si->pktinfo > 0) {
5299                 rc = swrap_msghdr_add_pktinfo(si, omsg);
5300         }
5301
5302         return rc;
5303 }
5304
5305 static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
5306                                    uint8_t **cm_data,
5307                                    size_t *cm_data_space);
5308 static int swrap_sendmsg_filter_cmsg_ipproto_ip(const struct cmsghdr *cmsg,
5309                                                 uint8_t **cm_data,
5310                                                 size_t *cm_data_space);
5311 static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg,
5312                                                 uint8_t **cm_data,
5313                                                 size_t *cm_data_space);
5314
5315 static int swrap_sendmsg_filter_cmsghdr(const struct msghdr *_msg,
5316                                         uint8_t **cm_data,
5317                                         size_t *cm_data_space)
5318 {
5319         struct msghdr *msg = discard_const_p(struct msghdr, _msg);
5320         struct cmsghdr *cmsg;
5321         int rc = -1;
5322
5323         /* Nothing to do */
5324         if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
5325                 return 0;
5326         }
5327
5328         for (cmsg = CMSG_FIRSTHDR(msg);
5329              cmsg != NULL;
5330              cmsg = CMSG_NXTHDR(msg, cmsg)) {
5331                 switch (cmsg->cmsg_level) {
5332                 case IPPROTO_IP:
5333                         rc = swrap_sendmsg_filter_cmsg_ipproto_ip(cmsg,
5334                                                                   cm_data,
5335                                                                   cm_data_space);
5336                         break;
5337                 case SOL_SOCKET:
5338                         rc = swrap_sendmsg_filter_cmsg_sol_socket(cmsg,
5339                                                                   cm_data,
5340                                                                   cm_data_space);
5341                         break;
5342                 default:
5343                         rc = swrap_sendmsg_copy_cmsg(cmsg,
5344                                                      cm_data,
5345                                                      cm_data_space);
5346                         break;
5347                 }
5348                 if (rc < 0) {
5349                         int saved_errno = errno;
5350                         SAFE_FREE(*cm_data);
5351                         *cm_data_space = 0;
5352                         errno = saved_errno;
5353                         return rc;
5354                 }
5355         }
5356
5357         return rc;
5358 }
5359
5360 static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
5361                                    uint8_t **cm_data,
5362                                    size_t *cm_data_space)
5363 {
5364         size_t cmspace;
5365         uint8_t *p;
5366
5367         cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len);
5368
5369         p = realloc((*cm_data), cmspace);
5370         if (p == NULL) {
5371                 return -1;
5372         }
5373         (*cm_data) = p;
5374
5375         p = (*cm_data) + (*cm_data_space);
5376         *cm_data_space = cmspace;
5377
5378         memcpy(p, cmsg, cmsg->cmsg_len);
5379
5380         return 0;
5381 }
5382
5383 static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
5384                                             uint8_t **cm_data,
5385                                             size_t *cm_data_space);
5386
5387
5388 static int swrap_sendmsg_filter_cmsg_ipproto_ip(const struct cmsghdr *cmsg,
5389                                                 uint8_t **cm_data,
5390                                                 size_t *cm_data_space)
5391 {
5392         int rc = -1;
5393
5394         switch(cmsg->cmsg_type) {
5395 #ifdef IP_PKTINFO
5396         case IP_PKTINFO:
5397                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
5398                                                        cm_data,
5399                                                        cm_data_space);
5400                 break;
5401 #endif
5402 #ifdef IPV6_PKTINFO
5403         case IPV6_PKTINFO:
5404                 rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
5405                                                        cm_data,
5406                                                        cm_data_space);
5407                 break;
5408 #endif
5409         default:
5410                 break;
5411         }
5412
5413         return rc;
5414 }
5415
5416 static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
5417                                              uint8_t **cm_data,
5418                                              size_t *cm_data_space)
5419 {
5420         (void)cmsg; /* unused */
5421         (void)cm_data; /* unused */
5422         (void)cm_data_space; /* unused */
5423
5424         /*
5425          * Passing a IP pktinfo to a unix socket might be rejected by the
5426          * Kernel, at least on FreeBSD. So skip this cmsg.
5427          */
5428         return 0;
5429 }
5430
5431 static int swrap_sendmsg_filter_cmsg_sol_socket(const struct cmsghdr *cmsg,
5432                                                 uint8_t **cm_data,
5433                                                 size_t *cm_data_space)
5434 {
5435         int rc = -1;
5436
5437         switch (cmsg->cmsg_type) {
5438         case SCM_RIGHTS:
5439                 SWRAP_LOG(SWRAP_LOG_TRACE,
5440                           "Ignoring SCM_RIGHTS on inet socket!");
5441                 rc = 0;
5442                 break;
5443 #ifdef SCM_CREDENTIALS
5444         case SCM_CREDENTIALS:
5445                 SWRAP_LOG(SWRAP_LOG_TRACE,
5446                           "Ignoring SCM_CREDENTIALS on inet socket!");
5447                 rc = 0;
5448                 break;
5449 #endif /* SCM_CREDENTIALS */
5450         default:
5451                 rc = swrap_sendmsg_copy_cmsg(cmsg,
5452                                              cm_data,
5453                                              cm_data_space);
5454                 break;
5455         }
5456
5457         return rc;
5458 }
5459
5460 static const uint64_t swrap_unix_scm_right_magic = 0x8e0e13f27c42fc36;
5461
5462 /*
5463  * We only allow up to 6 fds at a time
5464  * as that's more than enough for Samba
5465  * and it means we can keep the logic simple
5466  * and work with fixed size arrays.
5467  *
5468  * We also keep sizeof(struct swrap_unix_scm_rights)
5469  * under PIPE_BUF (4096) in order to allow a non-blocking
5470  * write into the pipe.
5471  */
5472 #ifndef PIPE_BUF
5473 #define PIPE_BUF 4096
5474 #endif
5475 #define SWRAP_MAX_PASSED_FDS ((size_t)6)
5476 #define SWRAP_MAX_PASSED_SOCKET_INFO SWRAP_MAX_PASSED_FDS
5477 struct swrap_unix_scm_rights_payload {
5478         uint8_t num_idxs;
5479         int8_t idxs[SWRAP_MAX_PASSED_FDS];
5480         struct socket_info infos[SWRAP_MAX_PASSED_SOCKET_INFO];
5481 };
5482 struct swrap_unix_scm_rights {
5483         uint64_t magic;
5484         char package_name[sizeof(SOCKET_WRAPPER_PACKAGE)];
5485         char package_version[sizeof(SOCKET_WRAPPER_VERSION)];
5486         uint32_t full_size;
5487         uint32_t payload_size;
5488         struct swrap_unix_scm_rights_payload payload;
5489 };
5490
5491 static void swrap_dec_fd_passed_array(size_t num, struct socket_info **array)
5492 {
5493         int saved_errno = errno;
5494         size_t i;
5495
5496         for (i = 0; i < num; i++) {
5497                 struct socket_info *si = array[i];
5498                 if (si == NULL) {
5499                         continue;
5500                 }
5501
5502                 SWRAP_LOCK_SI(si);
5503                 swrap_dec_refcount(si);
5504                 if (si->fd_passed > 0) {
5505                         si->fd_passed -= 1;
5506                 }
5507                 SWRAP_UNLOCK_SI(si);
5508                 array[i] = NULL;
5509         }
5510
5511         errno = saved_errno;
5512 }
5513
5514 static void swrap_undo_si_idx_array(size_t num, int *array)
5515 {
5516         int saved_errno = errno;
5517         size_t i;
5518
5519         swrap_mutex_lock(&first_free_mutex);
5520
5521         for (i = 0; i < num; i++) {
5522                 struct socket_info *si = NULL;
5523
5524                 if (array[i] == -1) {
5525                         continue;
5526                 }
5527
5528                 si = swrap_get_socket_info(array[i]);
5529                 if (si == NULL) {
5530                         continue;
5531                 }
5532
5533                 SWRAP_LOCK_SI(si);
5534                 swrap_dec_refcount(si);
5535                 SWRAP_UNLOCK_SI(si);
5536
5537                 swrap_set_next_free(si, first_free);
5538                 first_free = array[i];
5539                 array[i] = -1;
5540         }
5541
5542         swrap_mutex_unlock(&first_free_mutex);
5543         errno = saved_errno;
5544 }
5545
5546 static void swrap_close_fd_array(size_t num, const int *array)
5547 {
5548         int saved_errno = errno;
5549         size_t i;
5550
5551         for (i = 0; i < num; i++) {
5552                 if (array[i] == -1) {
5553                         continue;
5554                 }
5555                 libc_close(array[i]);
5556         }
5557
5558         errno = saved_errno;
5559 }
5560
5561 union __swrap_fds {
5562         const uint8_t *p;
5563         int *fds;
5564 };
5565
5566 union __swrap_cmsghdr {
5567         const uint8_t *p;
5568         struct cmsghdr *cmsg;
5569 };
5570
5571 static int swrap_sendmsg_unix_scm_rights(struct cmsghdr *cmsg,
5572                                          uint8_t **cm_data,
5573                                          size_t *cm_data_space,
5574                                          int *scm_rights_pipe_fd)
5575 {
5576         struct swrap_unix_scm_rights info;
5577         struct swrap_unix_scm_rights_payload *payload = NULL;
5578         int si_idx_array[SWRAP_MAX_PASSED_FDS];
5579         struct socket_info *si_array[SWRAP_MAX_PASSED_FDS] = { NULL, };
5580         size_t info_idx = 0;
5581         size_t size_fds_in;
5582         size_t num_fds_in;
5583         union __swrap_fds __fds_in = { .p = NULL, };
5584         const int *fds_in = NULL;
5585         size_t num_fds_out;
5586         size_t size_fds_out;
5587         union __swrap_fds __fds_out = { .p = NULL, };
5588         int *fds_out = NULL;
5589         size_t cmsg_len;
5590         size_t cmsg_space;
5591         size_t new_cm_data_space;
5592         union __swrap_cmsghdr __new_cmsg = { .p = NULL, };
5593         struct cmsghdr *new_cmsg = NULL;
5594         uint8_t *p = NULL;
5595         size_t i;
5596         int pipefd[2] = { -1, -1 };
5597         int rc;
5598         ssize_t sret;
5599
5600         /*
5601          * We pass this a buffer to the kernel make sure any padding
5602          * is also cleared.
5603          */
5604         ZERO_STRUCT(info);
5605         info.magic = swrap_unix_scm_right_magic;
5606         memcpy(info.package_name,
5607                SOCKET_WRAPPER_PACKAGE,
5608                sizeof(info.package_name));
5609         memcpy(info.package_version,
5610                SOCKET_WRAPPER_VERSION,
5611                sizeof(info.package_version));
5612         info.full_size = sizeof(info);
5613         info.payload_size = sizeof(info.payload);
5614         payload = &info.payload;
5615
5616         if (*scm_rights_pipe_fd != -1) {
5617                 SWRAP_LOG(SWRAP_LOG_ERROR,
5618                           "Two SCM_RIGHTS headers are not supported by socket_wrapper");
5619                 errno = EINVAL;
5620                 return -1;
5621         }
5622
5623         if (cmsg->cmsg_len < CMSG_LEN(0)) {
5624                 SWRAP_LOG(SWRAP_LOG_ERROR,
5625                           "cmsg->cmsg_len=%zu < CMSG_LEN(0)=%zu",
5626                           (size_t)cmsg->cmsg_len,
5627                           CMSG_LEN(0));
5628                 errno = EINVAL;
5629                 return -1;
5630         }
5631         size_fds_in = cmsg->cmsg_len - CMSG_LEN(0);
5632         if ((size_fds_in % sizeof(int)) != 0) {
5633                 SWRAP_LOG(SWRAP_LOG_ERROR,
5634                           "cmsg->cmsg_len=%zu => (size_fds_in=%zu %% sizeof(int)=%zu) != 0",
5635                           (size_t)cmsg->cmsg_len,
5636                           size_fds_in,
5637                           sizeof(int));
5638                 errno = EINVAL;
5639                 return -1;
5640         }
5641         num_fds_in = size_fds_in / sizeof(int);
5642         if (num_fds_in > SWRAP_MAX_PASSED_FDS) {
5643                 SWRAP_LOG(SWRAP_LOG_ERROR,
5644                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5645                           "num_fds_in=%zu > "
5646                           "SWRAP_MAX_PASSED_FDS(%zu)",
5647                           (size_t)cmsg->cmsg_len,
5648                           size_fds_in,
5649                           num_fds_in,
5650                           SWRAP_MAX_PASSED_FDS);
5651                 errno = EINVAL;
5652                 return -1;
5653         }
5654         if (num_fds_in == 0) {
5655                 SWRAP_LOG(SWRAP_LOG_ERROR,
5656                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5657                           "num_fds_in=%zu",
5658                           (size_t)cmsg->cmsg_len,
5659                           size_fds_in,
5660                           num_fds_in);
5661                 errno = EINVAL;
5662                 return -1;
5663         }
5664         __fds_in.p = CMSG_DATA(cmsg);
5665         fds_in = __fds_in.fds;
5666         num_fds_out = num_fds_in + 1;
5667
5668         SWRAP_LOG(SWRAP_LOG_TRACE,
5669                   "num_fds_in=%zu num_fds_out=%zu",
5670                   num_fds_in, num_fds_out);
5671
5672         size_fds_out = sizeof(int) * num_fds_out;
5673         cmsg_len = CMSG_LEN(size_fds_out);
5674         cmsg_space = CMSG_SPACE(size_fds_out);
5675
5676         new_cm_data_space = *cm_data_space + cmsg_space;
5677
5678         p = realloc((*cm_data), new_cm_data_space);
5679         if (p == NULL) {
5680                 return -1;
5681         }
5682         (*cm_data) = p;
5683         p = (*cm_data) + (*cm_data_space);
5684         memset(p, 0, cmsg_space);
5685         __new_cmsg.p = p;
5686         new_cmsg = __new_cmsg.cmsg;
5687         *new_cmsg = *cmsg;
5688         __fds_out.p = CMSG_DATA(new_cmsg);
5689         fds_out = __fds_out.fds;
5690         memcpy(fds_out, fds_in, size_fds_in);
5691         new_cmsg->cmsg_len = cmsg->cmsg_len;
5692
5693         for (i = 0; i < num_fds_in; i++) {
5694                 size_t j;
5695
5696                 payload->idxs[i] = -1;
5697                 payload->num_idxs++;
5698
5699                 si_idx_array[i] = find_socket_info_index(fds_in[i]);
5700                 if (si_idx_array[i] == -1) {
5701                         continue;
5702                 }
5703
5704                 si_array[i] = swrap_get_socket_info(si_idx_array[i]);
5705                 if (si_array[i] == NULL) {
5706                         SWRAP_LOG(SWRAP_LOG_ERROR,
5707                                   "fds_in[%zu]=%d si_idx_array[%zu]=%d missing!",
5708                                   i, fds_in[i], i, si_idx_array[i]);
5709                         errno = EINVAL;
5710                         return -1;
5711                 }
5712
5713                 for (j = 0; j < i; j++) {
5714                         if (si_array[j] == si_array[i]) {
5715                                 payload->idxs[i] = payload->idxs[j];
5716                                 break;
5717                         }
5718                 }
5719                 if (payload->idxs[i] == -1) {
5720                         if (info_idx >= SWRAP_MAX_PASSED_SOCKET_INFO) {
5721                                 SWRAP_LOG(SWRAP_LOG_ERROR,
5722                                           "fds_in[%zu]=%d,si_idx_array[%zu]=%d: "
5723                                           "info_idx=%zu >= SWRAP_MAX_PASSED_FDS(%zu)!",
5724                                           i, fds_in[i], i, si_idx_array[i],
5725                                           info_idx,
5726                                           SWRAP_MAX_PASSED_SOCKET_INFO);
5727                                 errno = EINVAL;
5728                                 return -1;
5729                         }
5730                         payload->idxs[i] = info_idx;
5731                         info_idx += 1;
5732                         continue;
5733                 }
5734         }
5735
5736         for (i = 0; i < num_fds_in; i++) {
5737                 struct socket_info *si = si_array[i];
5738
5739                 if (si == NULL) {
5740                         SWRAP_LOG(SWRAP_LOG_TRACE,
5741                                   "fds_in[%zu]=%d not an inet socket",
5742                                   i, fds_in[i]);
5743                         continue;
5744                 }
5745
5746                 SWRAP_LOG(SWRAP_LOG_TRACE,
5747                           "fds_in[%zu]=%d si_idx_array[%zu]=%d "
5748                           "passing as info.idxs[%zu]=%d!",
5749                           i, fds_in[i],
5750                           i, si_idx_array[i],
5751                           i, payload->idxs[i]);
5752
5753                 SWRAP_LOCK_SI(si);
5754                 si->fd_passed += 1;
5755                 payload->infos[payload->idxs[i]] = *si;
5756                 payload->infos[payload->idxs[i]].fd_passed = 0;
5757                 SWRAP_UNLOCK_SI(si);
5758         }
5759
5760         rc = pipe(pipefd);
5761         if (rc == -1) {
5762                 int saved_errno = errno;
5763                 SWRAP_LOG(SWRAP_LOG_ERROR,
5764                           "pipe() failed - %d %s",
5765                           saved_errno,
5766                           strerror(saved_errno));
5767                 swrap_dec_fd_passed_array(num_fds_in, si_array);
5768                 errno = saved_errno;
5769                 return -1;
5770         }
5771
5772         sret = libc_write(pipefd[1], &info, sizeof(info));
5773         if (sret != sizeof(info)) {
5774                 int saved_errno = errno;
5775                 if (sret != -1) {
5776                         saved_errno = EINVAL;
5777                 }
5778                 SWRAP_LOG(SWRAP_LOG_ERROR,
5779                           "write() failed - sret=%zd - %d %s",
5780                           sret, saved_errno,
5781                           strerror(saved_errno));
5782                 swrap_dec_fd_passed_array(num_fds_in, si_array);
5783                 libc_close(pipefd[1]);
5784                 libc_close(pipefd[0]);
5785                 errno = saved_errno;
5786                 return -1;
5787         }
5788         libc_close(pipefd[1]);
5789
5790         /*
5791          * Add the pipe read end to the end of the passed fd array
5792          */
5793         fds_out[num_fds_in] = pipefd[0];
5794         new_cmsg->cmsg_len = cmsg_len;
5795
5796         /* we're done ... */
5797         *scm_rights_pipe_fd = pipefd[0];
5798         *cm_data_space = new_cm_data_space;
5799
5800         return 0;
5801 }
5802
5803 static int swrap_sendmsg_unix_sol_socket(struct cmsghdr *cmsg,
5804                                          uint8_t **cm_data,
5805                                          size_t *cm_data_space,
5806                                          int *scm_rights_pipe_fd)
5807 {
5808         int rc = -1;
5809
5810         switch (cmsg->cmsg_type) {
5811         case SCM_RIGHTS:
5812                 rc = swrap_sendmsg_unix_scm_rights(cmsg,
5813                                                    cm_data,
5814                                                    cm_data_space,
5815                                                    scm_rights_pipe_fd);
5816                 break;
5817         default:
5818                 rc = swrap_sendmsg_copy_cmsg(cmsg,
5819                                              cm_data,
5820                                              cm_data_space);
5821                 break;
5822         }
5823
5824         return rc;
5825 }
5826
5827 static int swrap_recvmsg_unix_scm_rights(struct cmsghdr *cmsg,
5828                                          uint8_t **cm_data,
5829                                          size_t *cm_data_space)
5830 {
5831         int scm_rights_pipe_fd = -1;
5832         struct swrap_unix_scm_rights info;
5833         struct swrap_unix_scm_rights_payload *payload = NULL;
5834         int si_idx_array[SWRAP_MAX_PASSED_FDS];
5835         size_t size_fds_in;
5836         size_t num_fds_in;
5837         union __swrap_fds __fds_in = { .p = NULL, };
5838         const int *fds_in = NULL;
5839         size_t num_fds_out;
5840         size_t size_fds_out;
5841         union __swrap_fds __fds_out = { .p = NULL, };
5842         int *fds_out = NULL;
5843         size_t cmsg_len;
5844         size_t cmsg_space;
5845         size_t new_cm_data_space;
5846         union __swrap_cmsghdr __new_cmsg = { .p = NULL, };
5847         struct cmsghdr *new_cmsg = NULL;
5848         uint8_t *p = NULL;
5849         ssize_t sret;
5850         size_t i;
5851         int cmp;
5852
5853         if (cmsg->cmsg_len < CMSG_LEN(0)) {
5854                 SWRAP_LOG(SWRAP_LOG_ERROR,
5855                           "cmsg->cmsg_len=%zu < CMSG_LEN(0)=%zu",
5856                           (size_t)cmsg->cmsg_len,
5857                           CMSG_LEN(0));
5858                 errno = EINVAL;
5859                 return -1;
5860         }
5861         size_fds_in = cmsg->cmsg_len - CMSG_LEN(0);
5862         if ((size_fds_in % sizeof(int)) != 0) {
5863                 SWRAP_LOG(SWRAP_LOG_ERROR,
5864                           "cmsg->cmsg_len=%zu => (size_fds_in=%zu %% sizeof(int)=%zu) != 0",
5865                           (size_t)cmsg->cmsg_len,
5866                           size_fds_in,
5867                           sizeof(int));
5868                 errno = EINVAL;
5869                 return -1;
5870         }
5871         num_fds_in = size_fds_in / sizeof(int);
5872         if (num_fds_in > (SWRAP_MAX_PASSED_FDS + 1)) {
5873                 SWRAP_LOG(SWRAP_LOG_ERROR,
5874                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5875                           "num_fds_in=%zu > SWRAP_MAX_PASSED_FDS+1(%zu)",
5876                           (size_t)cmsg->cmsg_len,
5877                           size_fds_in,
5878                           num_fds_in,
5879                           SWRAP_MAX_PASSED_FDS+1);
5880                 errno = EINVAL;
5881                 return -1;
5882         }
5883         if (num_fds_in <= 1) {
5884                 SWRAP_LOG(SWRAP_LOG_ERROR,
5885                           "cmsg->cmsg_len=%zu,size_fds_in=%zu => "
5886                           "num_fds_in=%zu",
5887                           (size_t)cmsg->cmsg_len,
5888                           size_fds_in,
5889                           num_fds_in);
5890                 errno = EINVAL;
5891                 return -1;
5892         }
5893         __fds_in.p = CMSG_DATA(cmsg);
5894         fds_in = __fds_in.fds;
5895         num_fds_out = num_fds_in - 1;
5896
5897         SWRAP_LOG(SWRAP_LOG_TRACE,
5898                   "num_fds_in=%zu num_fds_out=%zu",
5899                   num_fds_in, num_fds_out);
5900
5901         for (i = 0; i < num_fds_in; i++) {
5902                 /* Check if we have a stale fd and remove it */
5903                 swrap_remove_stale(fds_in[i]);
5904         }
5905
5906         scm_rights_pipe_fd = fds_in[num_fds_out];
5907         size_fds_out = sizeof(int) * num_fds_out;
5908         cmsg_len = CMSG_LEN(size_fds_out);
5909         cmsg_space = CMSG_SPACE(size_fds_out);
5910
5911         new_cm_data_space = *cm_data_space + cmsg_space;
5912
5913         p = realloc((*cm_data), new_cm_data_space);
5914         if (p == NULL) {
5915                 swrap_close_fd_array(num_fds_in, fds_in);
5916                 return -1;
5917         }
5918         (*cm_data) = p;
5919         p = (*cm_data) + (*cm_data_space);
5920         memset(p, 0, cmsg_space);
5921         __new_cmsg.p = p;
5922         new_cmsg = __new_cmsg.cmsg;
5923         *new_cmsg = *cmsg;
5924         __fds_out.p = CMSG_DATA(new_cmsg);
5925         fds_out = __fds_out.fds;
5926         memcpy(fds_out, fds_in, size_fds_out);
5927         new_cmsg->cmsg_len = cmsg_len;
5928
5929         sret = read(scm_rights_pipe_fd, &info, sizeof(info));
5930         if (sret != sizeof(info)) {
5931                 int saved_errno = errno;
5932                 if (sret != -1) {
5933                         saved_errno = EINVAL;
5934                 }
5935                 SWRAP_LOG(SWRAP_LOG_ERROR,
5936                           "read() failed - sret=%zd - %d %s",
5937                           sret, saved_errno,
5938                           strerror(saved_errno));
5939                 swrap_close_fd_array(num_fds_in, fds_in);
5940                 errno = saved_errno;
5941                 return -1;
5942         }
5943         libc_close(scm_rights_pipe_fd);
5944         payload = &info.payload;
5945
5946         if (info.magic != swrap_unix_scm_right_magic) {
5947                 SWRAP_LOG(SWRAP_LOG_ERROR,
5948                           "info.magic=0x%llx != swrap_unix_scm_right_magic=0x%llx",
5949                           (unsigned long long)info.magic,
5950                           (unsigned long long)swrap_unix_scm_right_magic);
5951                 swrap_close_fd_array(num_fds_out, fds_out);
5952                 errno = EINVAL;
5953                 return -1;
5954         }
5955
5956         cmp = memcmp(info.package_name,
5957                      SOCKET_WRAPPER_PACKAGE,
5958                      sizeof(info.package_name));
5959         if (cmp != 0) {
5960                 SWRAP_LOG(SWRAP_LOG_ERROR,
5961                           "info.package_name='%.*s' != '%s'",
5962                           (int)sizeof(info.package_name),
5963                           info.package_name,
5964                           SOCKET_WRAPPER_PACKAGE);
5965                 swrap_close_fd_array(num_fds_out, fds_out);
5966                 errno = EINVAL;
5967                 return -1;
5968         }
5969
5970         cmp = memcmp(info.package_version,
5971                      SOCKET_WRAPPER_VERSION,
5972                      sizeof(info.package_version));
5973         if (cmp != 0) {
5974                 SWRAP_LOG(SWRAP_LOG_ERROR,
5975                           "info.package_version='%.*s' != '%s'",
5976                           (int)sizeof(info.package_version),
5977                           info.package_version,
5978                           SOCKET_WRAPPER_VERSION);
5979                 swrap_close_fd_array(num_fds_out, fds_out);
5980                 errno = EINVAL;
5981                 return -1;
5982         }
5983
5984         if (info.full_size != sizeof(info)) {
5985                 SWRAP_LOG(SWRAP_LOG_ERROR,
5986                           "info.full_size=%zu != sizeof(info)=%zu",
5987                           (size_t)info.full_size,
5988                           sizeof(info));
5989                 swrap_close_fd_array(num_fds_out, fds_out);
5990                 errno = EINVAL;
5991                 return -1;
5992         }
5993
5994         if (info.payload_size != sizeof(info.payload)) {
5995                 SWRAP_LOG(SWRAP_LOG_ERROR,
5996                           "info.payload_size=%zu != sizeof(info.payload)=%zu",
5997                           (size_t)info.payload_size,
5998                           sizeof(info.payload));
5999                 swrap_close_fd_array(num_fds_out, fds_out);
6000                 errno = EINVAL;
6001                 return -1;
6002         }
6003
6004         if (payload->num_idxs != num_fds_out) {
6005                 SWRAP_LOG(SWRAP_LOG_ERROR,
6006                           "info.num_idxs=%u != num_fds_out=%zu",
6007                           payload->num_idxs, num_fds_out);
6008                 swrap_close_fd_array(num_fds_out, fds_out);
6009                 errno = EINVAL;
6010                 return -1;
6011         }
6012
6013         for (i = 0; i < num_fds_out; i++) {
6014                 size_t j;
6015
6016                 si_idx_array[i] = -1;
6017
6018                 if (payload->idxs[i] == -1) {
6019                         SWRAP_LOG(SWRAP_LOG_TRACE,
6020                                   "fds_out[%zu]=%d not an inet socket",
6021                                   i, fds_out[i]);
6022                         continue;
6023                 }
6024
6025                 if (payload->idxs[i] < 0) {
6026                         SWRAP_LOG(SWRAP_LOG_ERROR,
6027                                   "fds_out[%zu]=%d info.idxs[%zu]=%d < 0!",
6028                                   i, fds_out[i], i, payload->idxs[i]);
6029                         swrap_close_fd_array(num_fds_out, fds_out);
6030                         errno = EINVAL;
6031                         return -1;
6032                 }
6033
6034                 if (payload->idxs[i] >= payload->num_idxs) {
6035                         SWRAP_LOG(SWRAP_LOG_ERROR,
6036                                   "fds_out[%zu]=%d info.idxs[%zu]=%d >= %u!",
6037                                   i, fds_out[i], i, payload->idxs[i],
6038                                   payload->num_idxs);
6039                         swrap_close_fd_array(num_fds_out, fds_out);
6040                         errno = EINVAL;
6041                         return -1;
6042                 }
6043
6044                 if ((size_t)fds_out[i] >= socket_fds_max) {
6045                         SWRAP_LOG(SWRAP_LOG_ERROR,
6046                                   "The max socket index limit of %zu has been reached, "
6047                                   "trying to add %d",
6048                                   socket_fds_max,
6049                                   fds_out[i]);
6050                         swrap_close_fd_array(num_fds_out, fds_out);
6051                         errno = EMFILE;
6052                         return -1;
6053                 }
6054
6055                 SWRAP_LOG(SWRAP_LOG_TRACE,
6056                           "fds_in[%zu]=%d "
6057                           "received as info.idxs[%zu]=%d!",
6058                           i, fds_out[i],
6059                           i, payload->idxs[i]);
6060
6061                 for (j = 0; j < i; j++) {
6062                         if (payload->idxs[j] == -1) {
6063                                 continue;
6064                         }
6065                         if (payload->idxs[j] == payload->idxs[i]) {
6066                                 si_idx_array[i] = si_idx_array[j];
6067                         }
6068                 }
6069                 if (si_idx_array[i] == -1) {
6070                         const struct socket_info *si = &payload->infos[payload->idxs[i]];
6071
6072                         si_idx_array[i] = swrap_add_socket_info(si);
6073                         if (si_idx_array[i] == -1) {
6074                                 int saved_errno = errno;
6075                                 SWRAP_LOG(SWRAP_LOG_ERROR,
6076                                           "The max socket index limit of %zu has been reached, "
6077                                           "trying to add %d",
6078                                           socket_fds_max,
6079                                           fds_out[i]);
6080                                 swrap_undo_si_idx_array(i, si_idx_array);
6081                                 swrap_close_fd_array(num_fds_out, fds_out);
6082                                 errno = saved_errno;
6083                                 return -1;
6084                         }
6085                         SWRAP_LOG(SWRAP_LOG_TRACE,
6086                                   "Imported %s socket for protocol %s, fd=%d",
6087                                   si->family == AF_INET ? "IPv4" : "IPv6",
6088                                   si->type == SOCK_DGRAM ? "UDP" : "TCP",
6089                                   fds_out[i]);
6090                 }
6091         }
6092
6093         for (i = 0; i < num_fds_out; i++) {
6094                 if (si_idx_array[i] == -1) {
6095                         continue;
6096                 }
6097                 set_socket_info_index(fds_out[i], si_idx_array[i]);
6098         }
6099
6100         /* we're done ... */
6101         *cm_data_space = new_cm_data_space;
6102
6103         return 0;
6104 }
6105
6106 static int swrap_recvmsg_unix_sol_socket(struct cmsghdr *cmsg,
6107                                          uint8_t **cm_data,
6108                                          size_t *cm_data_space)
6109 {
6110         int rc = -1;
6111
6112         switch (cmsg->cmsg_type) {
6113         case SCM_RIGHTS:
6114                 rc = swrap_recvmsg_unix_scm_rights(cmsg,
6115                                                    cm_data,
6116                                                    cm_data_space);
6117                 break;
6118         default:
6119                 rc = swrap_sendmsg_copy_cmsg(cmsg,
6120                                              cm_data,
6121                                              cm_data_space);
6122                 break;
6123         }
6124
6125         return rc;
6126 }
6127
6128 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6129
6130 static int swrap_sendmsg_before_unix(const struct msghdr *_msg_in,
6131                                      struct msghdr *msg_tmp,
6132                                      int *scm_rights_pipe_fd)
6133 {
6134 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6135         struct msghdr *msg_in = discard_const_p(struct msghdr, _msg_in);
6136         struct cmsghdr *cmsg = NULL;
6137         uint8_t *cm_data = NULL;
6138         size_t cm_data_space = 0;
6139         int rc = -1;
6140
6141         *msg_tmp = *msg_in;
6142         *scm_rights_pipe_fd = -1;
6143
6144         /* Nothing to do */
6145         if (msg_in->msg_controllen == 0 || msg_in->msg_control == NULL) {
6146                 return 0;
6147         }
6148
6149         for (cmsg = CMSG_FIRSTHDR(msg_in);
6150              cmsg != NULL;
6151              cmsg = CMSG_NXTHDR(msg_in, cmsg)) {
6152                 switch (cmsg->cmsg_level) {
6153                 case SOL_SOCKET:
6154                         rc = swrap_sendmsg_unix_sol_socket(cmsg,
6155                                                            &cm_data,
6156                                                            &cm_data_space,
6157                                                            scm_rights_pipe_fd);
6158                         break;
6159
6160                 default:
6161                         rc = swrap_sendmsg_copy_cmsg(cmsg,
6162                                                      &cm_data,
6163                                                      &cm_data_space);
6164                         break;
6165                 }
6166                 if (rc < 0) {
6167                         int saved_errno = errno;
6168                         SAFE_FREE(cm_data);
6169                         errno = saved_errno;
6170                         return rc;
6171                 }
6172         }
6173
6174         msg_tmp->msg_controllen = cm_data_space;
6175         msg_tmp->msg_control = cm_data;
6176
6177         return 0;
6178 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6179         *msg_tmp = *_msg_in;
6180         return 0;
6181 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6182 }
6183
6184 static ssize_t swrap_sendmsg_after_unix(struct msghdr *msg_tmp,
6185                                         ssize_t ret,
6186                                         int scm_rights_pipe_fd)
6187 {
6188 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6189         int saved_errno = errno;
6190         SAFE_FREE(msg_tmp->msg_control);
6191         if (scm_rights_pipe_fd != -1) {
6192                 libc_close(scm_rights_pipe_fd);
6193         }
6194         errno = saved_errno;
6195 #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6196         return ret;
6197 }
6198
6199 static int swrap_recvmsg_before_unix(struct msghdr *msg_in,
6200                                      struct msghdr *msg_tmp,
6201                                      uint8_t **tmp_control)
6202 {
6203 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6204         const size_t cm_extra_space = CMSG_SPACE(sizeof(int));
6205         uint8_t *cm_data = NULL;
6206         size_t cm_data_space = 0;
6207
6208         *msg_tmp = *msg_in;
6209         *tmp_control = NULL;
6210
6211         SWRAP_LOG(SWRAP_LOG_TRACE,
6212                   "msg_in->msg_controllen=%zu",
6213                   (size_t)msg_in->msg_controllen);
6214
6215         /* Nothing to do */
6216         if (msg_in->msg_controllen == 0 || msg_in->msg_control == NULL) {
6217                 return 0;
6218         }
6219
6220         /*
6221          * We need to give the kernel a bit more space in order
6222          * recv the pipe fd, added by swrap_sendmsg_before_unix()).
6223          * swrap_recvmsg_after_unix() will hide it again.
6224          */
6225         cm_data_space = msg_in->msg_controllen;
6226         if (cm_data_space < (INT32_MAX - cm_extra_space)) {
6227                 cm_data_space += cm_extra_space;
6228         }
6229         cm_data = calloc(1, cm_data_space);
6230         if (cm_data == NULL) {
6231                 return -1;
6232         }
6233
6234         msg_tmp->msg_controllen = cm_data_space;
6235         msg_tmp->msg_control = cm_data;
6236         *tmp_control = cm_data;
6237
6238         SWRAP_LOG(SWRAP_LOG_TRACE,
6239                   "msg_tmp->msg_controllen=%zu",
6240                   (size_t)msg_tmp->msg_controllen);
6241         return 0;
6242 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6243         *msg_tmp = *msg_in;
6244         *tmp_control = NULL;
6245         return 0;
6246 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6247 }
6248
6249 static ssize_t swrap_recvmsg_after_unix(struct msghdr *msg_tmp,
6250                                         uint8_t **tmp_control,
6251                                         struct msghdr *msg_out,
6252                                         ssize_t ret)
6253 {
6254 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6255         struct cmsghdr *cmsg = NULL;
6256         uint8_t *cm_data = NULL;
6257         size_t cm_data_space = 0;
6258         int rc = -1;
6259
6260         if (ret < 0) {
6261                 int saved_errno = errno;
6262                 SWRAP_LOG(SWRAP_LOG_TRACE, "ret=%zd - %d - %s", ret,
6263                           saved_errno, strerror(saved_errno));
6264                 SAFE_FREE(*tmp_control);
6265                 /* msg_out should not be touched on error */
6266                 errno = saved_errno;
6267                 return ret;
6268         }
6269
6270         SWRAP_LOG(SWRAP_LOG_TRACE,
6271                   "msg_tmp->msg_controllen=%zu",
6272                   (size_t)msg_tmp->msg_controllen);
6273
6274         /* Nothing to do */
6275         if (msg_tmp->msg_controllen == 0 || msg_tmp->msg_control == NULL) {
6276                 int saved_errno = errno;
6277                 *msg_out = *msg_tmp;
6278                 SAFE_FREE(*tmp_control);
6279                 errno = saved_errno;
6280                 return ret;
6281         }
6282
6283         for (cmsg = CMSG_FIRSTHDR(msg_tmp);
6284              cmsg != NULL;
6285              cmsg = CMSG_NXTHDR(msg_tmp, cmsg)) {
6286                 switch (cmsg->cmsg_level) {
6287                 case SOL_SOCKET:
6288                         rc = swrap_recvmsg_unix_sol_socket(cmsg,
6289                                                            &cm_data,
6290                                                            &cm_data_space);
6291                         break;
6292
6293                 default:
6294                         rc = swrap_sendmsg_copy_cmsg(cmsg,
6295                                                      &cm_data,
6296                                                      &cm_data_space);
6297                         break;
6298                 }
6299                 if (rc < 0) {
6300                         int saved_errno = errno;
6301                         SAFE_FREE(cm_data);
6302                         SAFE_FREE(*tmp_control);
6303                         errno = saved_errno;
6304                         return rc;
6305                 }
6306         }
6307
6308         /*
6309          * msg_tmp->msg_control (*tmp_control) was created by
6310          * swrap_recvmsg_before_unix() and msg_out->msg_control
6311          * is still the buffer of the caller.
6312          */
6313         msg_tmp->msg_control = msg_out->msg_control;
6314         msg_tmp->msg_controllen = msg_out->msg_controllen;
6315         *msg_out = *msg_tmp;
6316
6317         cm_data_space = MIN(cm_data_space, msg_out->msg_controllen);
6318         memcpy(msg_out->msg_control, cm_data, cm_data_space);
6319         msg_out->msg_controllen = cm_data_space;
6320         SAFE_FREE(cm_data);
6321         SAFE_FREE(*tmp_control);
6322
6323         SWRAP_LOG(SWRAP_LOG_TRACE,
6324                   "msg_out->msg_controllen=%zu",
6325                   (size_t)msg_out->msg_controllen);
6326         return ret;
6327 #else /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6328         int saved_errno = errno;
6329         *msg_out = *msg_tmp;
6330         SAFE_FREE(*tmp_control);
6331         errno = saved_errno;
6332         return ret;
6333 #endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
6334 }
6335
6336 static ssize_t swrap_sendmsg_before(int fd,
6337                                     struct socket_info *si,
6338                                     struct msghdr *msg,
6339                                     struct iovec *tmp_iov,
6340                                     struct sockaddr_un *tmp_un,
6341                                     const struct sockaddr_un **to_un,
6342                                     const struct sockaddr **to,
6343                                     int *bcast)
6344 {
6345         size_t i, len = 0;
6346         ssize_t ret = -1;
6347         struct swrap_sockaddr_buf buf = {};
6348
6349         if (to_un) {
6350                 *to_un = NULL;
6351         }
6352         if (to) {
6353                 *to = NULL;
6354         }
6355         if (bcast) {
6356                 *bcast = 0;
6357         }
6358
6359         SWRAP_LOCK_SI(si);
6360
6361         switch (si->type) {
6362         case SOCK_STREAM: {
6363                 unsigned long mtu;
6364
6365                 if (!si->connected) {
6366                         errno = ENOTCONN;
6367                         goto out;
6368                 }
6369
6370                 if (msg->msg_iovlen == 0) {
6371                         break;
6372                 }
6373
6374                 mtu = socket_wrapper_mtu();
6375                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6376                         size_t nlen;
6377                         nlen = len + msg->msg_iov[i].iov_len;
6378                         if (nlen < len) {
6379                                 /* overflow */
6380                                 errno = EMSGSIZE;
6381                                 goto out;
6382                         }
6383                         if (nlen > mtu) {
6384                                 break;
6385                         }
6386                 }
6387                 msg->msg_iovlen = i;
6388                 if (msg->msg_iovlen == 0) {
6389                         *tmp_iov = msg->msg_iov[0];
6390                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
6391                                                (size_t)mtu);
6392                         msg->msg_iov = tmp_iov;
6393                         msg->msg_iovlen = 1;
6394                 }
6395                 break;
6396         }
6397         case SOCK_DGRAM:
6398                 if (si->connected) {
6399                         if (msg->msg_name != NULL) {
6400                                 /*
6401                                  * We are dealing with unix sockets and if we
6402                                  * are connected, we should only talk to the
6403                                  * connected unix path. Using the fd to send
6404                                  * to another server would be hard to achieve.
6405                                  */
6406                                 msg->msg_name = NULL;
6407                                 msg->msg_namelen = 0;
6408                         }
6409                         SWRAP_LOG(SWRAP_LOG_TRACE,
6410                                   "connected(%s) fd=%d",
6411                                   swrap_sockaddr_string(&buf, &si->peername.sa.s),
6412                                   fd);
6413                 } else {
6414                         const struct sockaddr *msg_name;
6415                         msg_name = (const struct sockaddr *)msg->msg_name;
6416
6417                         if (msg_name == NULL) {
6418                                 errno = ENOTCONN;
6419                                 goto out;
6420                         }
6421
6422
6423                         ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
6424                                                      tmp_un, 0, bcast);
6425                         if (ret == -1) {
6426                                 goto out;
6427                         }
6428
6429                         if (to_un) {
6430                                 *to_un = tmp_un;
6431                         }
6432                         if (to) {
6433                                 *to = msg_name;
6434                         }
6435                         msg->msg_name = tmp_un;
6436                         msg->msg_namelen = sizeof(*tmp_un);
6437                 }
6438
6439                 if (si->bound == 0) {
6440                         ret = swrap_auto_bind(fd, si, si->family);
6441                         if (ret == -1) {
6442                                 SWRAP_UNLOCK_SI(si);
6443                                 if (errno == ENOTSOCK) {
6444                                         swrap_remove_stale(fd);
6445                                         ret = -ENOTSOCK;
6446                                 } else {
6447                                         SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
6448                                 }
6449                                 return ret;
6450                         }
6451                 }
6452
6453                 if (!si->defer_connect) {
6454                         break;
6455                 }
6456
6457                 ret = sockaddr_convert_to_un(si,
6458                                              &si->peername.sa.s,
6459                                              si->peername.sa_socklen,
6460                                              tmp_un,
6461                                              0,
6462                                              NULL);
6463                 if (ret == -1) {
6464                         goto out;
6465                 }
6466
6467                 SWRAP_LOG(SWRAP_LOG_TRACE,
6468                           "deferred connect(%s) path=%s, fd=%d",
6469                           swrap_sockaddr_string(&buf, &si->peername.sa.s),
6470                           tmp_un->sun_path, fd);
6471
6472                 ret = libc_connect(fd,
6473                                    (struct sockaddr *)(void *)tmp_un,
6474                                    sizeof(*tmp_un));
6475
6476                 /* to give better errors */
6477                 if (ret == -1 && errno == ENOENT) {
6478                         errno = EHOSTUNREACH;
6479                 }
6480
6481                 if (ret == -1) {
6482                         goto out;
6483                 }
6484
6485                 si->defer_connect = 0;
6486                 break;
6487         default:
6488                 errno = EHOSTUNREACH;
6489                 goto out;
6490         }
6491
6492         ret = 0;
6493 out:
6494         SWRAP_UNLOCK_SI(si);
6495
6496         return ret;
6497 }
6498
6499 static void swrap_sendmsg_after(int fd,
6500                                 struct socket_info *si,
6501                                 struct msghdr *msg,
6502                                 const struct sockaddr *to,
6503                                 ssize_t ret)
6504 {
6505         int saved_errno = errno;
6506         size_t i, len = 0;
6507         uint8_t *buf;
6508         off_t ofs = 0;
6509         size_t avail = 0;
6510         size_t remain;
6511
6512         /* to give better errors */
6513         if (ret == -1) {
6514                 if (saved_errno == ENOENT) {
6515                         saved_errno = EHOSTUNREACH;
6516                 } else if (saved_errno == ENOTSOCK) {
6517                         /* If the fd is not a socket, remove it */
6518                         swrap_remove_stale(fd);
6519                 }
6520         }
6521
6522         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6523                 avail += msg->msg_iov[i].iov_len;
6524         }
6525
6526         if (ret == -1) {
6527                 remain = MIN(80, avail);
6528         } else {
6529                 remain = ret;
6530         }
6531
6532         /* we capture it as one single packet */
6533         buf = (uint8_t *)malloc(remain);
6534         if (!buf) {
6535                 /* we just not capture the packet */
6536                 errno = saved_errno;
6537                 return;
6538         }
6539
6540         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6541                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
6542                 if (this_time > 0) {
6543                         memcpy(buf + ofs,
6544                                msg->msg_iov[i].iov_base,
6545                                this_time);
6546                 }
6547                 ofs += this_time;
6548                 remain -= this_time;
6549         }
6550         len = ofs;
6551
6552         SWRAP_LOCK_SI(si);
6553
6554         switch (si->type) {
6555         case SOCK_STREAM:
6556                 if (ret == -1) {
6557                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
6558                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
6559                 } else {
6560                         swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
6561                 }
6562                 break;
6563
6564         case SOCK_DGRAM:
6565                 if (si->connected) {
6566                         to = &si->peername.sa.s;
6567                 }
6568                 if (ret == -1) {
6569                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6570                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
6571                 } else {
6572                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6573                 }
6574                 break;
6575         }
6576
6577         SWRAP_UNLOCK_SI(si);
6578
6579         free(buf);
6580         errno = saved_errno;
6581 }
6582
6583 static int swrap_recvmsg_before(int fd,
6584                                 struct socket_info *si,
6585                                 struct msghdr *msg,
6586                                 struct iovec *tmp_iov)
6587 {
6588         size_t i, len = 0;
6589         int ret = -1;
6590
6591         SWRAP_LOCK_SI(si);
6592
6593         (void)fd; /* unused */
6594
6595         switch (si->type) {
6596         case SOCK_STREAM: {
6597                 unsigned int mtu;
6598                 if (!si->connected) {
6599                         errno = ENOTCONN;
6600                         goto out;
6601                 }
6602
6603                 if (msg->msg_iovlen == 0) {
6604                         break;
6605                 }
6606
6607                 mtu = socket_wrapper_mtu();
6608                 for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6609                         size_t nlen;
6610                         nlen = len + msg->msg_iov[i].iov_len;
6611                         if (nlen > mtu) {
6612                                 break;
6613                         }
6614                 }
6615                 msg->msg_iovlen = i;
6616                 if (msg->msg_iovlen == 0) {
6617                         *tmp_iov = msg->msg_iov[0];
6618                         tmp_iov->iov_len = MIN((size_t)tmp_iov->iov_len,
6619                                                (size_t)mtu);
6620                         msg->msg_iov = tmp_iov;
6621                         msg->msg_iovlen = 1;
6622                 }
6623                 break;
6624         }
6625         case SOCK_DGRAM:
6626                 if (msg->msg_name == NULL) {
6627                         errno = EINVAL;
6628                         goto out;
6629                 }
6630
6631                 if (msg->msg_iovlen == 0) {
6632                         break;
6633                 }
6634
6635                 if (si->bound == 0) {
6636                         ret = swrap_auto_bind(fd, si, si->family);
6637                         if (ret == -1) {
6638                                 SWRAP_UNLOCK_SI(si);
6639                                 /*
6640                                  * When attempting to read or write to a
6641                                  * descriptor, if an underlying autobind fails
6642                                  * because it's not a socket, stop intercepting
6643                                  * uses of that descriptor.
6644                                  */
6645                                 if (errno == ENOTSOCK) {
6646                                         swrap_remove_stale(fd);
6647                                         ret = -ENOTSOCK;
6648                                 } else {
6649                                         SWRAP_LOG(SWRAP_LOG_ERROR,
6650                                                   "swrap_recvmsg_before failed");
6651                                 }
6652                                 return ret;
6653                         }
6654                 }
6655                 break;
6656         default:
6657                 errno = EHOSTUNREACH;
6658                 goto out;
6659         }
6660
6661         ret = 0;
6662 out:
6663         SWRAP_UNLOCK_SI(si);
6664
6665         return ret;
6666 }
6667
6668 static int swrap_recvmsg_after(int fd,
6669                                struct socket_info *si,
6670                                struct msghdr *msg,
6671                                const struct sockaddr_un *un_addr,
6672                                socklen_t un_addrlen,
6673                                ssize_t ret)
6674 {
6675         int saved_errno = errno;
6676         size_t i;
6677         uint8_t *buf = NULL;
6678         off_t ofs = 0;
6679         size_t avail = 0;
6680         size_t remain;
6681         int rc;
6682
6683         /* to give better errors */
6684         if (ret == -1) {
6685                 if (saved_errno == ENOENT) {
6686                         saved_errno = EHOSTUNREACH;
6687                 } else if (saved_errno == ENOTSOCK) {
6688                         /* If the fd is not a socket, remove it */
6689                         swrap_remove_stale(fd);
6690                 }
6691         }
6692
6693         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6694                 avail += msg->msg_iov[i].iov_len;
6695         }
6696
6697         SWRAP_LOCK_SI(si);
6698
6699         /* Convert the socket address before we leave */
6700         if (si->type == SOCK_DGRAM && un_addr != NULL) {
6701                 rc = sockaddr_convert_from_un(si,
6702                                               un_addr,
6703                                               un_addrlen,
6704                                               si->family,
6705                                               msg->msg_name,
6706                                               &msg->msg_namelen);
6707                 if (rc == -1) {
6708                         goto done;
6709                 }
6710         }
6711
6712         if (avail == 0) {
6713                 rc = 0;
6714                 goto done;
6715         }
6716
6717         if (ret == -1) {
6718                 remain = MIN(80, avail);
6719         } else {
6720                 remain = ret;
6721         }
6722
6723         /* we capture it as one single packet */
6724         buf = (uint8_t *)malloc(remain);
6725         if (buf == NULL) {
6726                 /* we just not capture the packet */
6727                 SWRAP_UNLOCK_SI(si);
6728                 errno = saved_errno;
6729                 return -1;
6730         }
6731
6732         for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
6733                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
6734                 memcpy(buf + ofs,
6735                        msg->msg_iov[i].iov_base,
6736                        this_time);
6737                 ofs += this_time;
6738                 remain -= this_time;
6739         }
6740
6741         switch (si->type) {
6742         case SOCK_STREAM:
6743                 if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
6744                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
6745                 } else if (ret == 0) { /* END OF FILE */
6746                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
6747                 } else if (ret > 0) {
6748                         swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
6749                 }
6750                 break;
6751
6752         case SOCK_DGRAM:
6753                 if (ret == -1) {
6754                         break;
6755                 }
6756
6757                 if (un_addr != NULL) {
6758                         swrap_pcap_dump_packet(si,
6759                                           msg->msg_name,
6760                                           SWRAP_RECVFROM,
6761                                           buf,
6762                                           ret);
6763                 } else {
6764                         swrap_pcap_dump_packet(si,
6765                                           msg->msg_name,
6766                                           SWRAP_RECV,
6767                                           buf,
6768                                           ret);
6769                 }
6770
6771                 break;
6772         }
6773
6774         rc = 0;
6775 done:
6776         free(buf);
6777         errno = saved_errno;
6778
6779 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6780         if (rc == 0 &&
6781             msg->msg_controllen > 0 &&
6782             msg->msg_control != NULL) {
6783                 rc = swrap_msghdr_add_socket_info(si, msg);
6784                 if (rc < 0) {
6785                         SWRAP_UNLOCK_SI(si);
6786                         return -1;
6787                 }
6788         }
6789 #endif
6790
6791         SWRAP_UNLOCK_SI(si);
6792         return rc;
6793 }
6794
6795 /****************************************************************************
6796  *   RECVFROM
6797  ***************************************************************************/
6798
6799 static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
6800                               struct sockaddr *from, socklen_t *fromlen)
6801 {
6802         struct swrap_address from_addr = {
6803                 .sa_socklen = sizeof(struct sockaddr_un),
6804         };
6805         ssize_t ret;
6806         struct socket_info *si = find_socket_info(s);
6807         struct swrap_address saddr = {
6808                 .sa_socklen = sizeof(struct sockaddr_storage),
6809         };
6810         struct msghdr msg;
6811         struct iovec tmp;
6812         int tret;
6813
6814         if (!si) {
6815                 return libc_recvfrom(s,
6816                                      buf,
6817                                      len,
6818                                      flags,
6819                                      from,
6820                                      fromlen);
6821         }
6822
6823         tmp.iov_base = buf;
6824         tmp.iov_len = len;
6825
6826         ZERO_STRUCT(msg);
6827         if (from != NULL && fromlen != NULL) {
6828                 msg.msg_name = from;   /* optional address */
6829                 msg.msg_namelen = *fromlen; /* size of address */
6830         } else {
6831                 msg.msg_name = &saddr.sa.s; /* optional address */
6832                 msg.msg_namelen = saddr.sa_socklen; /* size of address */
6833         }
6834         msg.msg_iov = &tmp;            /* scatter/gather array */
6835         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6836 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6837         msg.msg_control = NULL;        /* ancillary data, see below */
6838         msg.msg_controllen = 0;        /* ancillary data buffer len */
6839         msg.msg_flags = 0;             /* flags on received message */
6840 #endif
6841
6842         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
6843         if (tret < 0) {
6844                 return -1;
6845         }
6846
6847         buf = msg.msg_iov[0].iov_base;
6848         len = msg.msg_iov[0].iov_len;
6849
6850         ret = libc_recvfrom(s,
6851                             buf,
6852                             len,
6853                             flags,
6854                             &from_addr.sa.s,
6855                             &from_addr.sa_socklen);
6856         if (ret == -1) {
6857                 return ret;
6858         }
6859
6860         tret = swrap_recvmsg_after(s,
6861                                    si,
6862                                    &msg,
6863                                    &from_addr.sa.un,
6864                                    from_addr.sa_socklen,
6865                                    ret);
6866         if (tret != 0) {
6867                 return tret;
6868         }
6869
6870         if (from != NULL && fromlen != NULL) {
6871                 *fromlen = msg.msg_namelen;
6872         }
6873
6874         return ret;
6875 }
6876
6877 #ifdef HAVE_ACCEPT_PSOCKLEN_T
6878 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
6879                  struct sockaddr *from, Psocklen_t fromlen)
6880 #else
6881 ssize_t recvfrom(int s, void *buf, size_t len, int flags,
6882                  struct sockaddr *from, socklen_t *fromlen)
6883 #endif
6884 {
6885         return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
6886 }
6887
6888 /****************************************************************************
6889  *   SENDTO
6890  ***************************************************************************/
6891
6892 static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
6893                             const struct sockaddr *to, socklen_t tolen)
6894 {
6895         struct msghdr msg;
6896         struct iovec tmp;
6897         struct swrap_address un_addr = {
6898                 .sa_socklen = sizeof(struct sockaddr_un),
6899         };
6900         const struct sockaddr_un *to_un = NULL;
6901         ssize_t ret;
6902         int rc;
6903         struct socket_info *si = find_socket_info(s);
6904         int bcast = 0;
6905
6906         if (!si) {
6907                 return libc_sendto(s, buf, len, flags, to, tolen);
6908         }
6909
6910         tmp.iov_base = discard_const_p(char, buf);
6911         tmp.iov_len = len;
6912
6913         ZERO_STRUCT(msg);
6914         msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
6915         msg.msg_namelen = tolen;       /* size of address */
6916         msg.msg_iov = &tmp;            /* scatter/gather array */
6917         msg.msg_iovlen = 1;            /* # elements in msg_iov */
6918 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
6919         msg.msg_control = NULL;        /* ancillary data, see below */
6920         msg.msg_controllen = 0;        /* ancillary data buffer len */
6921         msg.msg_flags = 0;             /* flags on received message */
6922 #endif
6923
6924         rc = swrap_sendmsg_before(s,
6925                                   si,
6926                                   &msg,
6927                                   &tmp,
6928                                   &un_addr.sa.un,
6929                                   &to_un,
6930                                   &to,
6931                                   &bcast);
6932         if (rc < 0) {
6933                 return -1;
6934         }
6935
6936         buf = msg.msg_iov[0].iov_base;
6937         len = msg.msg_iov[0].iov_len;
6938
6939         if (bcast) {
6940                 struct stat st;
6941                 unsigned int iface;
6942                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
6943                 char type;
6944                 char *swrap_dir = NULL;
6945
6946                 type = SOCKET_TYPE_CHAR_UDP;
6947
6948                 swrap_dir = socket_wrapper_dir();
6949                 if (swrap_dir == NULL) {
6950                         return -1;
6951                 }
6952
6953                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
6954                         swrap_un_path(&un_addr.sa.un,
6955                                       swrap_dir,
6956                                       type,
6957                                       iface,
6958                                       prt);
6959                         if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
6960
6961                         /* ignore the any errors in broadcast sends */
6962                         libc_sendto(s,
6963                                     buf,
6964                                     len,
6965                                     flags,
6966                                     &un_addr.sa.s,
6967                                     un_addr.sa_socklen);
6968                 }
6969
6970                 SAFE_FREE(swrap_dir);
6971
6972                 SWRAP_LOCK_SI(si);
6973
6974                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
6975
6976                 SWRAP_UNLOCK_SI(si);
6977
6978                 return len;
6979         }
6980
6981         SWRAP_LOCK_SI(si);
6982         /*
6983          * If it is a dgram socket and we are connected, don't include the
6984          * 'to' address.
6985          */
6986         if (si->type == SOCK_DGRAM && si->connected) {
6987                 ret = libc_sendto(s,
6988                                   buf,
6989                                   len,
6990                                   flags,
6991                                   NULL,
6992                                   0);
6993         } else {
6994                 ret = libc_sendto(s,
6995                                   buf,
6996                                   len,
6997                                   flags,
6998                                   (struct sockaddr *)msg.msg_name,
6999                                   msg.msg_namelen);
7000         }
7001
7002         SWRAP_UNLOCK_SI(si);
7003
7004         swrap_sendmsg_after(s, si, &msg, to, ret);
7005
7006         return ret;
7007 }
7008
7009 ssize_t sendto(int s, const void *buf, size_t len, int flags,
7010                const struct sockaddr *to, socklen_t tolen)
7011 {
7012         return swrap_sendto(s, buf, len, flags, to, tolen);
7013 }
7014
7015 /****************************************************************************
7016  *   READV
7017  ***************************************************************************/
7018
7019 static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
7020 {
7021         struct socket_info *si;
7022         struct msghdr msg;
7023         struct swrap_address saddr = {
7024                 .sa_socklen = sizeof(struct sockaddr_storage),
7025         };
7026         struct iovec tmp;
7027         ssize_t ret;
7028         int tret;
7029
7030         si = find_socket_info(s);
7031         if (si == NULL) {
7032                 return libc_recv(s, buf, len, flags);
7033         }
7034
7035         tmp.iov_base = buf;
7036         tmp.iov_len = len;
7037
7038         ZERO_STRUCT(msg);
7039         msg.msg_name = &saddr.sa.s;    /* optional address */
7040         msg.msg_namelen = saddr.sa_socklen; /* size of address */
7041         msg.msg_iov = &tmp;            /* scatter/gather array */
7042         msg.msg_iovlen = 1;            /* # elements in msg_iov */
7043 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7044         msg.msg_control = NULL;        /* ancillary data, see below */
7045         msg.msg_controllen = 0;        /* ancillary data buffer len */
7046         msg.msg_flags = 0;             /* flags on received message */
7047 #endif
7048
7049         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
7050         if (tret < 0) {
7051                 return -1;
7052         }
7053
7054         buf = msg.msg_iov[0].iov_base;
7055         len = msg.msg_iov[0].iov_len;
7056
7057         ret = libc_recv(s, buf, len, flags);
7058
7059         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
7060         if (tret != 0) {
7061                 return tret;
7062         }
7063
7064         return ret;
7065 }
7066
7067 ssize_t recv(int s, void *buf, size_t len, int flags)
7068 {
7069         return swrap_recv(s, buf, len, flags);
7070 }
7071
7072 /****************************************************************************
7073  *   READ
7074  ***************************************************************************/
7075
7076 static ssize_t swrap_read(int s, void *buf, size_t len)
7077 {
7078         struct socket_info *si;
7079         struct msghdr msg;
7080         struct iovec tmp;
7081         struct swrap_address saddr = {
7082                 .sa_socklen = sizeof(struct sockaddr_storage),
7083         };
7084         ssize_t ret;
7085         int tret;
7086
7087         si = find_socket_info(s);
7088         if (si == NULL) {
7089                 return libc_read(s, buf, len);
7090         }
7091
7092         tmp.iov_base = buf;
7093         tmp.iov_len = len;
7094
7095         ZERO_STRUCT(msg);
7096         msg.msg_name = &saddr.sa.ss;   /* optional address */
7097         msg.msg_namelen = saddr.sa_socklen; /* size of address */
7098         msg.msg_iov = &tmp;            /* scatter/gather array */
7099         msg.msg_iovlen = 1;            /* # elements in msg_iov */
7100 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7101         msg.msg_control = NULL;        /* ancillary data, see below */
7102         msg.msg_controllen = 0;        /* ancillary data buffer len */
7103         msg.msg_flags = 0;             /* flags on received message */
7104 #endif
7105
7106         tret = swrap_recvmsg_before(s, si, &msg, &tmp);
7107         if (tret < 0) {
7108                 if (tret == -ENOTSOCK) {
7109                         return libc_read(s, buf, len);
7110                 }
7111                 return -1;
7112         }
7113
7114         buf = msg.msg_iov[0].iov_base;
7115         len = msg.msg_iov[0].iov_len;
7116
7117         ret = libc_read(s, buf, len);
7118
7119         tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
7120         if (tret != 0) {
7121                 return tret;
7122         }
7123
7124         return ret;
7125 }
7126
7127 ssize_t read(int s, void *buf, size_t len)
7128 {
7129         return swrap_read(s, buf, len);
7130 }
7131
7132 /****************************************************************************
7133  *   WRITE
7134  ***************************************************************************/
7135
7136 static ssize_t swrap_write(int s, const void *buf, size_t len)
7137 {
7138         struct msghdr msg;
7139         struct iovec tmp;
7140         struct sockaddr_un un_addr;
7141         ssize_t ret;
7142         int rc;
7143         struct socket_info *si;
7144
7145         si = find_socket_info(s);
7146         if (si == NULL) {
7147                 return libc_write(s, buf, len);
7148         }
7149
7150         tmp.iov_base = discard_const_p(char, buf);
7151         tmp.iov_len = len;
7152
7153         ZERO_STRUCT(msg);
7154         msg.msg_name = NULL;           /* optional address */
7155         msg.msg_namelen = 0;           /* size of address */
7156         msg.msg_iov = &tmp;            /* scatter/gather array */
7157         msg.msg_iovlen = 1;            /* # elements in msg_iov */
7158 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7159         msg.msg_control = NULL;        /* ancillary data, see below */
7160         msg.msg_controllen = 0;        /* ancillary data buffer len */
7161         msg.msg_flags = 0;             /* flags on received message */
7162 #endif
7163
7164         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
7165         if (rc < 0) {
7166                 return -1;
7167         }
7168
7169         buf = msg.msg_iov[0].iov_base;
7170         len = msg.msg_iov[0].iov_len;
7171
7172         ret = libc_write(s, buf, len);
7173
7174         swrap_sendmsg_after(s, si, &msg, NULL, ret);
7175
7176         return ret;
7177 }
7178
7179 ssize_t write(int s, const void *buf, size_t len)
7180 {
7181         return swrap_write(s, buf, len);
7182 }
7183
7184 /****************************************************************************
7185  *   SEND
7186  ***************************************************************************/
7187
7188 static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
7189 {
7190         struct msghdr msg;
7191         struct iovec tmp;
7192         struct sockaddr_un un_addr;
7193         ssize_t ret;
7194         int rc;
7195         struct socket_info *si = find_socket_info(s);
7196
7197         if (!si) {
7198                 return libc_send(s, buf, len, flags);
7199         }
7200
7201         tmp.iov_base = discard_const_p(char, buf);
7202         tmp.iov_len = len;
7203
7204         ZERO_STRUCT(msg);
7205         msg.msg_name = NULL;           /* optional address */
7206         msg.msg_namelen = 0;           /* size of address */
7207         msg.msg_iov = &tmp;            /* scatter/gather array */
7208         msg.msg_iovlen = 1;            /* # elements in msg_iov */
7209 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7210         msg.msg_control = NULL;        /* ancillary data, see below */
7211         msg.msg_controllen = 0;        /* ancillary data buffer len */
7212         msg.msg_flags = 0;             /* flags on received message */
7213 #endif
7214
7215         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
7216         if (rc < 0) {
7217                 return -1;
7218         }
7219
7220         buf = msg.msg_iov[0].iov_base;
7221         len = msg.msg_iov[0].iov_len;
7222
7223         ret = libc_send(s, buf, len, flags);
7224
7225         swrap_sendmsg_after(s, si, &msg, NULL, ret);
7226
7227         return ret;
7228 }
7229
7230 ssize_t send(int s, const void *buf, size_t len, int flags)
7231 {
7232         return swrap_send(s, buf, len, flags);
7233 }
7234
7235 /****************************************************************************
7236  *   RECVMSG
7237  ***************************************************************************/
7238
7239 static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
7240 {
7241         struct swrap_address from_addr = {
7242                 .sa_socklen = sizeof(struct sockaddr_un),
7243         };
7244         struct swrap_address convert_addr = {
7245                 .sa_socklen = sizeof(struct sockaddr_storage),
7246         };
7247         struct socket_info *si;
7248         struct msghdr msg;
7249         struct iovec tmp;
7250 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7251         size_t msg_ctrllen_filled;
7252         size_t msg_ctrllen_left;
7253 #endif
7254
7255         ssize_t ret;
7256         int rc;
7257
7258         si = find_socket_info(s);
7259         if (si == NULL) {
7260                 uint8_t *tmp_control = NULL;
7261                 rc = swrap_recvmsg_before_unix(omsg, &msg, &tmp_control);
7262                 if (rc < 0) {
7263                         return rc;
7264                 }
7265                 ret = libc_recvmsg(s, &msg, flags);
7266                 return swrap_recvmsg_after_unix(&msg, &tmp_control, omsg, ret);
7267         }
7268
7269         tmp.iov_base = NULL;
7270         tmp.iov_len = 0;
7271
7272         ZERO_STRUCT(msg);
7273         msg.msg_name = &from_addr.sa;              /* optional address */
7274         msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
7275         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
7276         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7277 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7278         msg_ctrllen_filled = 0;
7279         msg_ctrllen_left = omsg->msg_controllen;
7280
7281         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
7282         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
7283         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
7284 #endif
7285
7286         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
7287         if (rc < 0) {
7288                 return -1;
7289         }
7290
7291         ret = libc_recvmsg(s, &msg, flags);
7292
7293 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7294         msg_ctrllen_filled += msg.msg_controllen;
7295         msg_ctrllen_left -= msg.msg_controllen;
7296
7297         if (omsg->msg_control != NULL) {
7298                 uint8_t *p;
7299
7300                 p = omsg->msg_control;
7301                 p += msg_ctrllen_filled;
7302
7303                 msg.msg_control = p;
7304                 msg.msg_controllen = msg_ctrllen_left;
7305         } else {
7306                 msg.msg_control = NULL;
7307                 msg.msg_controllen = 0;
7308         }
7309 #endif
7310
7311         /*
7312          * We convert the unix address to a IP address so we need a buffer
7313          * which can store the address in case of SOCK_DGRAM, see below.
7314          */
7315         msg.msg_name = &convert_addr.sa;
7316         msg.msg_namelen = convert_addr.sa_socklen;
7317
7318         rc = swrap_recvmsg_after(s,
7319                                  si,
7320                                  &msg,
7321                                  &from_addr.sa.un,
7322                                  from_addr.sa_socklen,
7323                                  ret);
7324         if (rc != 0) {
7325                 return rc;
7326         }
7327
7328 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7329         if (omsg->msg_control != NULL) {
7330                 /* msg.msg_controllen = space left */
7331                 msg_ctrllen_left = msg.msg_controllen;
7332                 msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
7333         }
7334
7335         /* Update the original message length */
7336         omsg->msg_controllen = msg_ctrllen_filled;
7337         omsg->msg_flags = msg.msg_flags;
7338 #endif
7339         omsg->msg_iovlen = msg.msg_iovlen;
7340
7341         SWRAP_LOCK_SI(si);
7342
7343         /*
7344          * From the manpage:
7345          *
7346          * The  msg_name  field  points  to a caller-allocated buffer that is
7347          * used to return the source address if the socket is unconnected.  The
7348          * caller should set msg_namelen to the size of this buffer before this
7349          * call; upon return from a successful call, msg_name will contain the
7350          * length of the returned address.  If the application  does  not  need
7351          * to know the source address, msg_name can be specified as NULL.
7352          */
7353         if (si->type == SOCK_STREAM) {
7354                 omsg->msg_namelen = 0;
7355         } else if (omsg->msg_name != NULL &&
7356                    omsg->msg_namelen != 0 &&
7357                    omsg->msg_namelen >= msg.msg_namelen) {
7358                 memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
7359                 omsg->msg_namelen = msg.msg_namelen;
7360         }
7361
7362         SWRAP_UNLOCK_SI(si);
7363
7364         return ret;
7365 }
7366
7367 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
7368 {
7369         return swrap_recvmsg(sockfd, msg, flags);
7370 }
7371
7372 /****************************************************************************
7373  *   RECVMMSG
7374  ***************************************************************************/
7375
7376 #ifdef HAVE_RECVMMSG
7377 #if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT)
7378 /* FreeBSD */
7379 static ssize_t swrap_recvmmsg(int s, struct mmsghdr *omsgvec, size_t _vlen, int flags, const struct timespec *timeout)
7380 #elif defined(HAVE_RECVMMSG_CONST_TIMEOUT)
7381 /* Linux legacy glibc < 2.21 */
7382 static int swrap_recvmmsg(int s, struct mmsghdr *omsgvec, unsigned int _vlen, int flags, const struct timespec *timeout)
7383 #else
7384 /* Linux glibc >= 2.21 */
7385 static int swrap_recvmmsg(int s, struct mmsghdr *omsgvec, unsigned int _vlen, int flags, struct timespec *timeout)
7386 #endif
7387 {
7388         struct socket_info *si = find_socket_info(s);
7389 #define __SWRAP_RECVMMSG_MAX_VLEN 16
7390         struct mmsghdr msgvec[__SWRAP_RECVMMSG_MAX_VLEN] = {};
7391         struct {
7392                 struct iovec iov;
7393                 struct swrap_address from_addr;
7394                 struct swrap_address convert_addr;
7395 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7396                 size_t msg_ctrllen_filled;
7397                 size_t msg_ctrllen_left;
7398 #endif
7399         } tmp[__SWRAP_RECVMMSG_MAX_VLEN] = {};
7400         int vlen;
7401         int i;
7402         int ret;
7403         int rc;
7404         int saved_errno;
7405
7406         if (_vlen > __SWRAP_RECVMMSG_MAX_VLEN) {
7407                 vlen = __SWRAP_RECVMMSG_MAX_VLEN;
7408         } else {
7409                 vlen = _vlen;
7410         }
7411
7412         if (si == NULL) {
7413                 uint8_t *tmp_control[__SWRAP_RECVMMSG_MAX_VLEN] = { NULL, };
7414
7415                 for (i = 0; i < vlen; i++) {
7416                         struct msghdr *omsg = &omsgvec[i].msg_hdr;
7417                         struct msghdr *msg = &msgvec[i].msg_hdr;
7418
7419                         rc = swrap_recvmsg_before_unix(omsg, msg,
7420                                                        &tmp_control[i]);
7421                         if (rc < 0) {
7422                                 ret = rc;
7423                                 goto fail_libc;
7424                         }
7425                 }
7426
7427                 ret = libc_recvmmsg(s, msgvec, vlen, flags, timeout);
7428                 if (ret < 0) {
7429                         goto fail_libc;
7430                 }
7431
7432                 for (i = 0; i < ret; i++) {
7433                         omsgvec[i].msg_len = msgvec[i].msg_len;
7434                 }
7435
7436 fail_libc:
7437                 saved_errno = errno;
7438                 for (i = 0; i < vlen; i++) {
7439                         struct msghdr *omsg = &omsgvec[i].msg_hdr;
7440                         struct msghdr *msg = &msgvec[i].msg_hdr;
7441
7442                         if (i == 0 || i < ret) {
7443                                 swrap_recvmsg_after_unix(msg, &tmp_control[i], omsg, ret);
7444                         }
7445                         SAFE_FREE(tmp_control[i]);
7446                 }
7447                 errno = saved_errno;
7448
7449                 return ret;
7450         }
7451
7452         for (i = 0; i < vlen; i++) {
7453                 struct msghdr *omsg = &omsgvec[i].msg_hdr;
7454                 struct msghdr *msg = &msgvec[i].msg_hdr;
7455
7456                 tmp[i].from_addr.sa_socklen = sizeof(struct sockaddr_un);
7457                 tmp[i].convert_addr.sa_socklen = sizeof(struct sockaddr_storage);
7458
7459                 msg->msg_name = &tmp[i].from_addr.sa;              /* optional address */
7460                 msg->msg_namelen = tmp[i].from_addr.sa_socklen;    /* size of address */
7461                 msg->msg_iov = omsg->msg_iov;               /* scatter/gather array */
7462                 msg->msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7463 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7464                 tmp[i].msg_ctrllen_filled = 0;
7465                 tmp[i].msg_ctrllen_left = omsg->msg_controllen;
7466
7467                 msg->msg_control = omsg->msg_control;       /* ancillary data, see below */
7468                 msg->msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
7469                 msg->msg_flags = omsg->msg_flags;           /* flags on received message */
7470 #endif
7471
7472                 rc = swrap_recvmsg_before(s, si, msg, &tmp[i].iov);
7473                 if (rc < 0) {
7474                         ret = rc;
7475                         goto fail_swrap;
7476                 }
7477         }
7478
7479         ret = libc_recvmmsg(s, msgvec, vlen, flags, timeout);
7480         if (ret < 0) {
7481                 goto fail_swrap;
7482         }
7483
7484         for (i = 0; i < ret; i++) {
7485                 omsgvec[i].msg_len = msgvec[i].msg_len;
7486         }
7487
7488 fail_swrap:
7489
7490         saved_errno = errno;
7491         for (i = 0; i < vlen; i++) {
7492                 struct msghdr *omsg = &omsgvec[i].msg_hdr;
7493                 struct msghdr *msg = &msgvec[i].msg_hdr;
7494
7495                 if (!(i == 0 || i < ret)) {
7496                         break;
7497                 }
7498
7499 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7500                 tmp[i].msg_ctrllen_filled += msg->msg_controllen;
7501                 tmp[i].msg_ctrllen_left -= msg->msg_controllen;
7502
7503                 if (omsg->msg_control != NULL) {
7504                         uint8_t *p;
7505
7506                         p = omsg->msg_control;
7507                         p += tmp[i].msg_ctrllen_filled;
7508
7509                         msg->msg_control = p;
7510                         msg->msg_controllen = tmp[i].msg_ctrllen_left;
7511                 } else {
7512                         msg->msg_control = NULL;
7513                         msg->msg_controllen = 0;
7514                 }
7515 #endif
7516
7517                 /*
7518                  * We convert the unix address to a IP address so we need a buffer
7519                  * which can store the address in case of SOCK_DGRAM, see below.
7520                  */
7521                 msg->msg_name = &tmp[i].convert_addr.sa;
7522                 msg->msg_namelen = tmp[i].convert_addr.sa_socklen;
7523
7524                 swrap_recvmsg_after(s, si, msg,
7525                                     &tmp[i].from_addr.sa.un,
7526                                     tmp[i].from_addr.sa_socklen,
7527                                     ret);
7528
7529 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7530                 if (omsg->msg_control != NULL) {
7531                         /* msg->msg_controllen = space left */
7532                         tmp[i].msg_ctrllen_left = msg->msg_controllen;
7533                         tmp[i].msg_ctrllen_filled = omsg->msg_controllen - tmp[i].msg_ctrllen_left;
7534                 }
7535
7536                 /* Update the original message length */
7537                 omsg->msg_controllen = tmp[i].msg_ctrllen_filled;
7538                 omsg->msg_flags = msg->msg_flags;
7539 #endif
7540                 omsg->msg_iovlen = msg->msg_iovlen;
7541
7542                 SWRAP_LOCK_SI(si);
7543
7544                 /*
7545                  * From the manpage:
7546                  *
7547                  * The  msg_name  field  points  to a caller-allocated buffer that is
7548                  * used to return the source address if the socket is unconnected.  The
7549                  * caller should set msg_namelen to the size of this buffer before this
7550                  * call; upon return from a successful call, msg_name will contain the
7551                  * length of the returned address.  If the application  does  not  need
7552                  * to know the source address, msg_name can be specified as NULL.
7553                  */
7554                 if (si->type == SOCK_STREAM) {
7555                         omsg->msg_namelen = 0;
7556                 } else if (omsg->msg_name != NULL &&
7557                            omsg->msg_namelen != 0 &&
7558                            omsg->msg_namelen >= msg->msg_namelen) {
7559                         memcpy(omsg->msg_name, msg->msg_name, msg->msg_namelen);
7560                         omsg->msg_namelen = msg->msg_namelen;
7561                 }
7562
7563                 SWRAP_UNLOCK_SI(si);
7564         }
7565         errno = saved_errno;
7566
7567         return ret;
7568 }
7569
7570 #if defined(HAVE_RECVMMSG_SSIZE_T_CONST_TIMEOUT)
7571 /* FreeBSD */
7572 ssize_t recvmmsg(int sockfd, struct mmsghdr *msgvec, size_t vlen, int flags, const struct timespec *timeout)
7573 #elif defined(HAVE_RECVMMSG_CONST_TIMEOUT)
7574 /* Linux legacy glibc < 2.21 */
7575 int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout)
7576 #else
7577 /* Linux glibc >= 2.21 */
7578 int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout)
7579 #endif
7580 {
7581         return swrap_recvmmsg(sockfd, msgvec, vlen, flags, timeout);
7582 }
7583 #endif /* HAVE_RECVMMSG */
7584
7585 /****************************************************************************
7586  *   SENDMSG
7587  ***************************************************************************/
7588
7589 static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
7590 {
7591         struct msghdr msg;
7592         struct iovec tmp;
7593         struct sockaddr_un un_addr;
7594         const struct sockaddr_un *to_un = NULL;
7595         const struct sockaddr *to = NULL;
7596         ssize_t ret;
7597         int rc;
7598         struct socket_info *si = find_socket_info(s);
7599         int bcast = 0;
7600
7601         if (!si) {
7602                 int scm_rights_pipe_fd = -1;
7603
7604                 rc = swrap_sendmsg_before_unix(omsg, &msg,
7605                                                &scm_rights_pipe_fd);
7606                 if (rc < 0) {
7607                         return rc;
7608                 }
7609                 ret = libc_sendmsg(s, &msg, flags);
7610                 return swrap_sendmsg_after_unix(&msg, ret, scm_rights_pipe_fd);
7611         }
7612
7613         ZERO_STRUCT(un_addr);
7614
7615         tmp.iov_base = NULL;
7616         tmp.iov_len = 0;
7617
7618         ZERO_STRUCT(msg);
7619
7620         SWRAP_LOCK_SI(si);
7621
7622         if (si->connected == 0) {
7623                 msg.msg_name = omsg->msg_name;             /* optional address */
7624                 msg.msg_namelen = omsg->msg_namelen;       /* size of address */
7625         }
7626         msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
7627         msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7628
7629         SWRAP_UNLOCK_SI(si);
7630
7631 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7632         if (omsg != NULL && omsg->msg_controllen > 0 && omsg->msg_control != NULL) {
7633                 uint8_t *cmbuf = NULL;
7634                 size_t cmlen = 0;
7635
7636                 rc = swrap_sendmsg_filter_cmsghdr(omsg, &cmbuf, &cmlen);
7637                 if (rc < 0) {
7638                         return rc;
7639                 }
7640
7641                 if (cmlen == 0) {
7642                         msg.msg_controllen = 0;
7643                         msg.msg_control = NULL;
7644                 } else {
7645                         msg.msg_control = cmbuf;
7646                         msg.msg_controllen = cmlen;
7647                 }
7648         }
7649         msg.msg_flags = omsg->msg_flags;           /* flags on received message */
7650 #endif
7651         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
7652         if (rc < 0) {
7653                 int saved_errno = errno;
7654 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7655                 SAFE_FREE(msg.msg_control);
7656 #endif
7657                 errno = saved_errno;
7658                 return -1;
7659         }
7660
7661         if (bcast) {
7662                 struct stat st;
7663                 unsigned int iface;
7664                 unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
7665                 char type;
7666                 size_t i, len = 0;
7667                 uint8_t *buf;
7668                 off_t ofs = 0;
7669                 size_t avail = 0;
7670                 size_t remain;
7671                 char *swrap_dir = NULL;
7672
7673                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
7674                         avail += msg.msg_iov[i].iov_len;
7675                 }
7676
7677                 len = avail;
7678                 remain = avail;
7679
7680                 /* we capture it as one single packet */
7681                 buf = (uint8_t *)malloc(remain);
7682                 if (!buf) {
7683                         int saved_errno = errno;
7684 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7685                         SAFE_FREE(msg.msg_control);
7686 #endif
7687                         errno = saved_errno;
7688                         return -1;
7689                 }
7690
7691                 for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
7692                         size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
7693                         memcpy(buf + ofs,
7694                                msg.msg_iov[i].iov_base,
7695                                this_time);
7696                         ofs += this_time;
7697                         remain -= this_time;
7698                 }
7699
7700                 type = SOCKET_TYPE_CHAR_UDP;
7701
7702                 swrap_dir = socket_wrapper_dir();
7703                 if (swrap_dir == NULL) {
7704                         int saved_errno = errno;
7705 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7706                         SAFE_FREE(msg.msg_control);
7707 #endif
7708                         SAFE_FREE(buf);
7709                         errno = saved_errno;
7710                         return -1;
7711                 }
7712
7713                 for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
7714                         swrap_un_path(&un_addr, swrap_dir, type, iface, prt);
7715                         if (stat(un_addr.sun_path, &st) != 0) continue;
7716
7717                         msg.msg_name = &un_addr;           /* optional address */
7718                         msg.msg_namelen = sizeof(un_addr); /* size of address */
7719
7720                         /* ignore the any errors in broadcast sends */
7721                         libc_sendmsg(s, &msg, flags);
7722                 }
7723
7724                 SAFE_FREE(swrap_dir);
7725
7726                 SWRAP_LOCK_SI(si);
7727
7728                 swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
7729                 free(buf);
7730
7731                 SWRAP_UNLOCK_SI(si);
7732
7733                 return len;
7734         }
7735
7736         ret = libc_sendmsg(s, &msg, flags);
7737
7738         swrap_sendmsg_after(s, si, &msg, to, ret);
7739
7740 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7741         {
7742                 int saved_errno = errno;
7743                 SAFE_FREE(msg.msg_control);
7744                 errno = saved_errno;
7745         }
7746 #endif
7747
7748         return ret;
7749 }
7750
7751 ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
7752 {
7753         return swrap_sendmsg(s, omsg, flags);
7754 }
7755
7756 /****************************************************************************
7757  *   SENDMMSG
7758  ***************************************************************************/
7759
7760 #ifdef HAVE_SENDMMSG
7761 #if defined(HAVE_SENDMMSG_SSIZE_T)
7762 /* FreeBSD */
7763 static ssize_t swrap_sendmmsg(int s, struct mmsghdr *omsgvec, size_t _vlen, int flags)
7764 #else
7765 /* Linux */
7766 static int swrap_sendmmsg(int s, struct mmsghdr *omsgvec, unsigned int _vlen, int flags)
7767 #endif
7768 {
7769         struct socket_info *si = find_socket_info(s);
7770 #define __SWRAP_SENDMMSG_MAX_VLEN 16
7771         struct mmsghdr msgvec[__SWRAP_SENDMMSG_MAX_VLEN] = {};
7772         struct {
7773                 struct iovec iov;
7774                 struct sockaddr_un un_addr;
7775                 const struct sockaddr_un *to_un;
7776                 const struct sockaddr *to;
7777                 int bcast;
7778         } tmp[__SWRAP_SENDMMSG_MAX_VLEN] = {};
7779         int vlen;
7780         int i;
7781         char *swrap_dir = NULL;
7782         int connected = 0;
7783         int found_bcast = 0;
7784         int ret;
7785         int rc;
7786         int saved_errno;
7787
7788         if (_vlen > __SWRAP_SENDMMSG_MAX_VLEN) {
7789                 vlen = __SWRAP_SENDMMSG_MAX_VLEN;
7790         } else {
7791                 vlen = _vlen;
7792         }
7793
7794         if (!si) {
7795                 int scm_rights_pipe_fd[__SWRAP_SENDMMSG_MAX_VLEN];
7796
7797                 for (i = 0; i < __SWRAP_SENDMMSG_MAX_VLEN; i++) {
7798                         scm_rights_pipe_fd[i] = -1;
7799                 }
7800
7801                 for (i = 0; i < vlen; i++) {
7802                         struct msghdr *omsg = &omsgvec[i].msg_hdr;
7803                         struct msghdr *msg = &msgvec[i].msg_hdr;
7804
7805                         rc = swrap_sendmsg_before_unix(omsg, msg,
7806                                                        &scm_rights_pipe_fd[i]);
7807                         if (rc < 0) {
7808                                 ret = rc;
7809                                 goto fail_libc;
7810                         }
7811                 }
7812
7813                 ret = libc_sendmmsg(s, msgvec, vlen, flags);
7814                 if (ret < 0) {
7815                         goto fail_libc;
7816                 }
7817
7818                 for (i = 0; i < ret; i++) {
7819                         omsgvec[i].msg_len = msgvec[i].msg_len;
7820                 }
7821
7822 fail_libc:
7823                 saved_errno = errno;
7824                 for (i = 0; i < vlen; i++) {
7825                         struct msghdr *msg = &msgvec[i].msg_hdr;
7826
7827                         swrap_sendmsg_after_unix(msg, ret,
7828                                                  scm_rights_pipe_fd[i]);
7829                 }
7830                 errno = saved_errno;
7831
7832                 return ret;
7833         }
7834
7835         SWRAP_LOCK_SI(si);
7836         connected = si->connected;
7837         SWRAP_UNLOCK_SI(si);
7838
7839         for (i = 0; i < vlen; i++) {
7840                 struct msghdr *omsg = &omsgvec[i].msg_hdr;
7841                 struct msghdr *msg = &msgvec[i].msg_hdr;
7842
7843                 if (connected == 0) {
7844                         msg->msg_name = omsg->msg_name;             /* optional address */
7845                         msg->msg_namelen = omsg->msg_namelen;       /* size of address */
7846                 }
7847                 msg->msg_iov = omsg->msg_iov;               /* scatter/gather array */
7848                 msg->msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
7849
7850 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7851                 if (omsg->msg_controllen > 0 && omsg->msg_control != NULL) {
7852                         uint8_t *cmbuf = NULL;
7853                         size_t cmlen = 0;
7854
7855                         rc = swrap_sendmsg_filter_cmsghdr(omsg, &cmbuf, &cmlen);
7856                         if (rc < 0) {
7857                                 ret = rc;
7858                                 goto fail_swrap;
7859                         }
7860
7861                         if (cmlen != 0) {
7862                                 msg->msg_control = cmbuf;
7863                                 msg->msg_controllen = cmlen;
7864                         }
7865                 }
7866                 msg->msg_flags = omsg->msg_flags;           /* flags on received message */
7867 #endif
7868
7869                 rc = swrap_sendmsg_before(s, si, msg,
7870                                           &tmp[i].iov,
7871                                           &tmp[i].un_addr,
7872                                           &tmp[i].to_un,
7873                                           &tmp[i].to,
7874                                           &tmp[i].bcast);
7875                 if (rc < 0) {
7876                         ret = rc;
7877                         goto fail_swrap;
7878                 }
7879
7880                 if (tmp[i].bcast) {
7881                         found_bcast = 1;
7882                 }
7883         }
7884
7885         if (found_bcast) {
7886
7887                 swrap_dir = socket_wrapper_dir();
7888                 if (swrap_dir == NULL) {
7889                         ret = -1;
7890                         goto fail_swrap;
7891                 }
7892
7893                 for (i = 0; i < vlen; i++) {
7894                         struct msghdr *msg = &msgvec[i].msg_hdr;
7895                         struct sockaddr_un *un_addr = &tmp[i].un_addr;
7896                         const struct sockaddr *to = tmp[i].to;
7897                         struct stat st;
7898                         unsigned int iface;
7899                         unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
7900                         char type;
7901                         size_t l, len = 0;
7902                         uint8_t *buf;
7903                         off_t ofs = 0;
7904                         size_t avail = 0;
7905                         size_t remain;
7906
7907                         for (l = 0; l < (size_t)msg->msg_iovlen; l++) {
7908                                 avail += msg->msg_iov[l].iov_len;
7909                         }
7910
7911                         len = avail;
7912                         remain = avail;
7913
7914                         /* we capture it as one single packet */
7915                         buf = (uint8_t *)malloc(remain);
7916                         if (!buf) {
7917                                 ret = -1;
7918                                 goto fail_swrap;
7919                         }
7920
7921                         for (l = 0; l < (size_t)msg->msg_iovlen; l++) {
7922                                 size_t this_time = MIN(remain, (size_t)msg->msg_iov[l].iov_len);
7923                                 memcpy(buf + ofs,
7924                                        msg->msg_iov[l].iov_base,
7925                                        this_time);
7926                                 ofs += this_time;
7927                                 remain -= this_time;
7928                         }
7929
7930                         type = SOCKET_TYPE_CHAR_UDP;
7931
7932                         for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
7933                                 swrap_un_path(un_addr, swrap_dir, type, iface, prt);
7934                                 if (stat(un_addr->sun_path, &st) != 0) continue;
7935
7936                                 msg->msg_name = un_addr;             /* optional address */
7937                                 msg->msg_namelen = sizeof(*un_addr); /* size of address */
7938
7939                                 /*
7940                                  * ignore the any errors in broadcast sends and
7941                                  * do a single sendmsg instead of sendmmsg
7942                                  */
7943                                 libc_sendmsg(s, msg, flags);
7944                         }
7945
7946                         SWRAP_LOCK_SI(si);
7947                         swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
7948                         SWRAP_UNLOCK_SI(si);
7949
7950                         SAFE_FREE(buf);
7951
7952                         msgvec[i].msg_len = len;
7953                 }
7954
7955                 ret = vlen;
7956                 goto bcast_done;
7957         }
7958
7959         ret = libc_sendmmsg(s, msgvec, vlen, flags);
7960         if (ret < 0) {
7961                 goto fail_swrap;
7962         }
7963
7964 bcast_done:
7965         for (i = 0; i < ret; i++) {
7966                 omsgvec[i].msg_len = msgvec[i].msg_len;
7967         }
7968
7969 fail_swrap:
7970         saved_errno = errno;
7971         for (i = 0; i < vlen; i++) {
7972                 struct msghdr *msg = &msgvec[i].msg_hdr;
7973
7974                 if (i == 0 || i < ret) {
7975                         swrap_sendmsg_after(s, si, msg, tmp[i].to, ret);
7976                 }
7977 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
7978                 SAFE_FREE(msg->msg_control);
7979 #endif
7980         }
7981         SAFE_FREE(swrap_dir);
7982         errno = saved_errno;
7983
7984         return ret;
7985 }
7986
7987 #if defined(HAVE_SENDMMSG_SSIZE_T)
7988 /* FreeBSD */
7989 ssize_t sendmmsg(int s, struct mmsghdr *msgvec, size_t vlen, int flags)
7990 #else
7991 /* Linux */
7992 int sendmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags)
7993 #endif
7994 {
7995         return swrap_sendmmsg(s, msgvec, vlen, flags);
7996 }
7997 #endif /* HAVE_SENDMMSG */
7998
7999 /****************************************************************************
8000  *   READV
8001  ***************************************************************************/
8002
8003 static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
8004 {
8005         struct socket_info *si;
8006         struct msghdr msg;
8007         struct iovec tmp;
8008         struct swrap_address saddr = {
8009                 .sa_socklen = sizeof(struct sockaddr_storage)
8010         };
8011         ssize_t ret;
8012         int rc;
8013
8014         si = find_socket_info(s);
8015         if (si == NULL) {
8016                 return libc_readv(s, vector, count);
8017         }
8018
8019         tmp.iov_base = NULL;
8020         tmp.iov_len = 0;
8021
8022         ZERO_STRUCT(msg);
8023         msg.msg_name = &saddr.sa.s; /* optional address */
8024         msg.msg_namelen = saddr.sa_socklen;      /* size of address */
8025         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
8026         msg.msg_iovlen = count;        /* # elements in msg_iov */
8027 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
8028         msg.msg_control = NULL;        /* ancillary data, see below */
8029         msg.msg_controllen = 0;        /* ancillary data buffer len */
8030         msg.msg_flags = 0;             /* flags on received message */
8031 #endif
8032
8033         rc = swrap_recvmsg_before(s, si, &msg, &tmp);
8034         if (rc < 0) {
8035                 if (rc == -ENOTSOCK) {
8036                         return libc_readv(s, vector, count);
8037                 }
8038                 return -1;
8039         }
8040
8041         ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
8042
8043         rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
8044         if (rc != 0) {
8045                 return rc;
8046         }
8047
8048         return ret;
8049 }
8050
8051 ssize_t readv(int s, const struct iovec *vector, int count)
8052 {
8053         return swrap_readv(s, vector, count);
8054 }
8055
8056 /****************************************************************************
8057  *   WRITEV
8058  ***************************************************************************/
8059
8060 static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
8061 {
8062         struct msghdr msg;
8063         struct iovec tmp;
8064         struct sockaddr_un un_addr;
8065         ssize_t ret;
8066         int rc;
8067         struct socket_info *si = find_socket_info(s);
8068
8069         if (!si) {
8070                 return libc_writev(s, vector, count);
8071         }
8072
8073         tmp.iov_base = NULL;
8074         tmp.iov_len = 0;
8075
8076         ZERO_STRUCT(msg);
8077         msg.msg_name = NULL;           /* optional address */
8078         msg.msg_namelen = 0;           /* size of address */
8079         msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
8080         msg.msg_iovlen = count;        /* # elements in msg_iov */
8081 #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
8082         msg.msg_control = NULL;        /* ancillary data, see below */
8083         msg.msg_controllen = 0;        /* ancillary data buffer len */
8084         msg.msg_flags = 0;             /* flags on received message */
8085 #endif
8086
8087         rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
8088         if (rc < 0) {
8089                 if (rc == -ENOTSOCK) {
8090                         return libc_readv(s, vector, count);
8091                 }
8092                 return -1;
8093         }
8094
8095         ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
8096
8097         swrap_sendmsg_after(s, si, &msg, NULL, ret);
8098
8099         return ret;
8100 }
8101
8102 ssize_t writev(int s, const struct iovec *vector, int count)
8103 {
8104         return swrap_writev(s, vector, count);
8105 }
8106
8107 /****************************
8108  * CLOSE
8109  ***************************/
8110
8111 static int swrap_remove_wrapper(const char *__func_name,
8112                                 int (*__close_fd_fn)(int fd),
8113                                 int fd)
8114 {
8115         struct socket_info *si = NULL;
8116         int si_index;
8117         int ret_errno = errno;
8118         int ret;
8119
8120         swrap_mutex_lock(&socket_reset_mutex);
8121
8122         si_index = find_socket_info_index(fd);
8123         if (si_index == -1) {
8124                 swrap_mutex_unlock(&socket_reset_mutex);
8125                 return __close_fd_fn(fd);
8126         }
8127
8128         swrap_log(SWRAP_LOG_TRACE, __func_name, "Remove wrapper for fd=%d", fd);
8129         reset_socket_info_index(fd);
8130
8131         si = swrap_get_socket_info(si_index);
8132
8133         swrap_mutex_lock(&first_free_mutex);
8134         SWRAP_LOCK_SI(si);
8135
8136         ret = __close_fd_fn(fd);
8137         if (ret == -1) {
8138                 ret_errno = errno;
8139         }
8140
8141         swrap_dec_refcount(si);
8142
8143         if (swrap_get_refcount(si) > 0) {
8144                 /* there are still references left */
8145                 goto out;
8146         }
8147
8148         if (si->fd_passed) {
8149                 goto set_next_free;
8150         }
8151
8152         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
8153                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
8154         }
8155
8156         if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
8157                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
8158                 swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
8159         }
8160
8161         if (si->un_addr.sun_path[0] != '\0') {
8162                 unlink(si->un_addr.sun_path);
8163         }
8164
8165 set_next_free:
8166         swrap_set_next_free(si, first_free);
8167         first_free = si_index;
8168
8169 out:
8170         SWRAP_UNLOCK_SI(si);
8171         swrap_mutex_unlock(&first_free_mutex);
8172         swrap_mutex_unlock(&socket_reset_mutex);
8173
8174         errno = ret_errno;
8175         return ret;
8176 }
8177
8178 static int swrap_noop_close(int fd)
8179 {
8180         (void)fd; /* unused */
8181         return 0;
8182 }
8183
8184 static void swrap_remove_stale(int fd)
8185 {
8186         swrap_remove_wrapper(__func__, swrap_noop_close, fd);
8187 }
8188
8189 /*
8190  * This allows socket_wrapper aware applications to
8191  * indicate that the given fd does not belong to
8192  * an inet socket.
8193  *
8194  * We already overload a lot of unrelated functions
8195  * like eventfd(), timerfd_create(), ... in order to
8196  * call swrap_remove_stale() on the returned fd, but
8197  * we'll never be able to handle all possible syscalls.
8198  *
8199  * socket_wrapper_indicate_no_inet_fd() gives them a way
8200  * to do the same.
8201  *
8202  * We don't export swrap_remove_stale() in order to
8203  * make it easier to analyze SOCKET_WRAPPER_DEBUGLEVEL=3
8204  * log files.
8205  */
8206 void socket_wrapper_indicate_no_inet_fd(int fd)
8207 {
8208         swrap_remove_wrapper(__func__, swrap_noop_close, fd);
8209 }
8210
8211 static int swrap_close(int fd)
8212 {
8213         return swrap_remove_wrapper(__func__, libc_close, fd);
8214 }
8215
8216 int close(int fd)
8217 {
8218         return swrap_close(fd);
8219 }
8220
8221 #ifdef HAVE___CLOSE_NOCANCEL
8222
8223 static int swrap___close_nocancel(int fd)
8224 {
8225         return swrap_remove_wrapper(__func__, libc___close_nocancel, fd);
8226 }
8227
8228 int __close_nocancel(int fd);
8229 int __close_nocancel(int fd)
8230 {
8231         return swrap___close_nocancel(fd);
8232 }
8233
8234 #endif /* HAVE___CLOSE_NOCANCEL */
8235
8236 /****************************
8237  * DUP
8238  ***************************/
8239
8240 static int swrap_dup(int fd)
8241 {
8242         struct socket_info *si;
8243         int dup_fd, idx;
8244
8245         idx = find_socket_info_index(fd);
8246         if (idx == -1) {
8247                 return libc_dup(fd);
8248         }
8249
8250         si = swrap_get_socket_info(idx);
8251
8252         dup_fd = libc_dup(fd);
8253         if (dup_fd == -1) {
8254                 int saved_errno = errno;
8255                 errno = saved_errno;
8256                 return -1;
8257         }
8258
8259         if ((size_t)dup_fd >= socket_fds_max) {
8260                 SWRAP_LOG(SWRAP_LOG_ERROR,
8261                           "The max socket index limit of %zu has been reached, "
8262                           "trying to add %d",
8263                           socket_fds_max,
8264                           dup_fd);
8265                 libc_close(dup_fd);
8266                 errno = EMFILE;
8267                 return -1;
8268         }
8269
8270         SWRAP_LOCK_SI(si);
8271
8272         swrap_inc_refcount(si);
8273
8274         SWRAP_UNLOCK_SI(si);
8275
8276         /* Make sure we don't have an entry for the fd */
8277         swrap_remove_stale(dup_fd);
8278
8279         set_socket_info_index(dup_fd, idx);
8280
8281         return dup_fd;
8282 }
8283
8284 int dup(int fd)
8285 {
8286         return swrap_dup(fd);
8287 }
8288
8289 /****************************
8290  * DUP2
8291  ***************************/
8292
8293 static int swrap_dup2(int fd, int newfd)
8294 {
8295         struct socket_info *si;
8296         int dup_fd, idx;
8297
8298         idx = find_socket_info_index(fd);
8299         if (idx == -1) {
8300                 return libc_dup2(fd, newfd);
8301         }
8302
8303         si = swrap_get_socket_info(idx);
8304
8305         if (fd == newfd) {
8306                 /*
8307                  * According to the manpage:
8308                  *
8309                  * "If oldfd is a valid file descriptor, and newfd has the same
8310                  * value as oldfd, then dup2() does nothing, and returns newfd."
8311                  */
8312                 return newfd;
8313         }
8314
8315         if ((size_t)newfd >= socket_fds_max) {
8316                 SWRAP_LOG(SWRAP_LOG_ERROR,
8317                           "The max socket index limit of %zu has been reached, "
8318                           "trying to add %d",
8319                           socket_fds_max,
8320                           newfd);
8321                 errno = EMFILE;
8322                 return -1;
8323         }
8324
8325         if (find_socket_info(newfd)) {
8326                 /* dup2() does an implicit close of newfd, which we
8327                  * need to emulate */
8328                 swrap_close(newfd);
8329         }
8330
8331         dup_fd = libc_dup2(fd, newfd);
8332         if (dup_fd == -1) {
8333                 int saved_errno = errno;
8334                 errno = saved_errno;
8335                 return -1;
8336         }
8337
8338         SWRAP_LOCK_SI(si);
8339
8340         swrap_inc_refcount(si);
8341
8342         SWRAP_UNLOCK_SI(si);
8343
8344         /* Make sure we don't have an entry for the fd */
8345         swrap_remove_stale(dup_fd);
8346
8347         set_socket_info_index(dup_fd, idx);
8348
8349         return dup_fd;
8350 }
8351
8352 int dup2(int fd, int newfd)
8353 {
8354         return swrap_dup2(fd, newfd);
8355 }
8356
8357 /****************************
8358  * FCNTL
8359  ***************************/
8360
8361 static int swrap_vfcntl(int fd, int cmd, va_list va)
8362 {
8363         struct socket_info *si;
8364         int rc, dup_fd, idx;
8365
8366         idx = find_socket_info_index(fd);
8367         if (idx == -1) {
8368                 return libc_vfcntl(fd, cmd, va);
8369         }
8370
8371         si = swrap_get_socket_info(idx);
8372
8373         switch (cmd) {
8374         case F_DUPFD:
8375                 dup_fd = libc_vfcntl(fd, cmd, va);
8376                 if (dup_fd == -1) {
8377                         int saved_errno = errno;
8378                         errno = saved_errno;
8379                         return -1;
8380                 }
8381
8382                 /* Make sure we don't have an entry for the fd */
8383                 swrap_remove_stale(dup_fd);
8384
8385                 if ((size_t)dup_fd >= socket_fds_max) {
8386                         SWRAP_LOG(SWRAP_LOG_ERROR,
8387                           "The max socket index limit of %zu has been reached, "
8388                           "trying to add %d",
8389                           socket_fds_max,
8390                           dup_fd);
8391                         libc_close(dup_fd);
8392                         errno = EMFILE;
8393                         return -1;
8394                 }
8395
8396                 SWRAP_LOCK_SI(si);
8397
8398                 swrap_inc_refcount(si);
8399
8400                 SWRAP_UNLOCK_SI(si);
8401
8402
8403                 set_socket_info_index(dup_fd, idx);
8404
8405                 rc = dup_fd;
8406                 break;
8407         default:
8408                 rc = libc_vfcntl(fd, cmd, va);
8409                 break;
8410         }
8411
8412         return rc;
8413 }
8414
8415 int fcntl(int fd, int cmd, ...)
8416 {
8417         va_list va;
8418         int rc;
8419
8420         va_start(va, cmd);
8421
8422         rc = swrap_vfcntl(fd, cmd, va);
8423
8424         va_end(va);
8425
8426         return rc;
8427 }
8428
8429 /****************************
8430  * EVENTFD
8431  ***************************/
8432
8433 #ifdef HAVE_EVENTFD
8434 static int swrap_eventfd(int count, int flags)
8435 {
8436         int fd;
8437
8438         fd = libc_eventfd(count, flags);
8439         if (fd != -1) {
8440                 swrap_remove_stale(fd);
8441         }
8442
8443         return fd;
8444 }
8445
8446 #ifdef HAVE_EVENTFD_UNSIGNED_INT
8447 int eventfd(unsigned int count, int flags)
8448 #else
8449 int eventfd(int count, int flags)
8450 #endif
8451 {
8452         return swrap_eventfd(count, flags);
8453 }
8454 #endif
8455
8456 #ifdef HAVE_PLEDGE
8457 int pledge(const char *promises, const char *paths[])
8458 {
8459         (void)promises; /* unused */
8460         (void)paths; /* unused */
8461
8462         return 0;
8463 }
8464 #endif /* HAVE_PLEDGE */
8465
8466 #ifdef HAVE_SYSCALL
8467 static bool swrap_is_swrap_related_syscall(long int sysno)
8468 {
8469         switch (sysno) {
8470 #ifdef SYS_close
8471         case SYS_close:
8472                 return true;
8473 #endif /* SYS_close */
8474
8475 #ifdef SYS_recvmmsg
8476         case SYS_recvmmsg:
8477                 return true;
8478 #endif /* SYS_recvmmsg */
8479
8480 #ifdef SYS_sendmmsg
8481         case SYS_sendmmsg:
8482                 return true;
8483 #endif /* SYS_sendmmsg */
8484
8485         default:
8486                 return false;
8487         }
8488 }
8489
8490 static long int swrap_syscall(long int sysno, va_list vp)
8491 {
8492         long int rc;
8493
8494         switch (sysno) {
8495 #ifdef SYS_close
8496         case SYS_close:
8497                 {
8498                         int fd = (int)va_arg(vp, int);
8499
8500                         SWRAP_LOG(SWRAP_LOG_TRACE,
8501                                   "calling swrap_close syscall %lu",
8502                                   sysno);
8503                         rc = swrap_close(fd);
8504                 }
8505                 break;
8506 #endif /* SYS_close */
8507
8508 #ifdef SYS_recvmmsg
8509         case SYS_recvmmsg:
8510                 {
8511                         int fd = (int)va_arg(vp, int);
8512                         struct mmsghdr *msgvec = va_arg(vp, struct mmsghdr *);
8513                         unsigned int vlen = va_arg(vp, unsigned int);
8514                         int flags = va_arg(vp, int);
8515                         struct timespec *timeout = va_arg(vp, struct timespec *);
8516
8517                         SWRAP_LOG(SWRAP_LOG_TRACE,
8518                                   "calling swrap_recvmmsg syscall %lu",
8519                                   sysno);
8520                         rc = swrap_recvmmsg(fd, msgvec, vlen, flags, timeout);
8521                 }
8522                 break;
8523 #endif /* SYS_recvmmsg */
8524
8525 #ifdef SYS_sendmmsg
8526         case SYS_sendmmsg:
8527                 {
8528                         int fd = (int)va_arg(vp, int);
8529                         struct mmsghdr *msgvec = va_arg(vp, struct mmsghdr *);
8530                         unsigned int vlen = va_arg(vp, unsigned int);
8531                         int flags = va_arg(vp, int);
8532
8533                         SWRAP_LOG(SWRAP_LOG_TRACE,
8534                                   "calling swrap_sendmmsg syscall %lu",
8535                                   sysno);
8536                         rc = swrap_sendmmsg(fd, msgvec, vlen, flags);
8537                 }
8538                 break;
8539 #endif /* SYS_sendmmsg */
8540
8541         default:
8542                 rc = -1;
8543                 errno = ENOSYS;
8544                 break;
8545         }
8546
8547         return rc;
8548 }
8549
8550 #ifdef HAVE_SYSCALL_INT
8551 int syscall(int sysno, ...)
8552 #else
8553 long int syscall(long int sysno, ...)
8554 #endif
8555 {
8556 #ifdef HAVE_SYSCALL_INT
8557         int rc;
8558 #else
8559         long int rc;
8560 #endif
8561         va_list va;
8562
8563         va_start(va, sysno);
8564
8565         /*
8566          * We should only handle the syscall numbers
8567          * we care about...
8568          */
8569         if (!swrap_is_swrap_related_syscall(sysno)) {
8570                 /*
8571                  * We need to give socket_wrapper a
8572                  * chance to take over...
8573                  */
8574                 if (swrap_uwrap_syscall_valid(sysno)) {
8575                         rc = swrap_uwrap_syscall_va(sysno, va);
8576                         va_end(va);
8577                         return rc;
8578                 }
8579
8580                 rc = libc_vsyscall(sysno, va);
8581                 va_end(va);
8582                 return rc;
8583         }
8584
8585         if (!socket_wrapper_enabled()) {
8586                 rc = libc_vsyscall(sysno, va);
8587                 va_end(va);
8588                 return rc;
8589         }
8590
8591         rc = swrap_syscall(sysno, va);
8592         va_end(va);
8593
8594         return rc;
8595 }
8596
8597 /* used by uid_wrapper */
8598 bool socket_wrapper_syscall_valid(long int sysno);
8599 bool socket_wrapper_syscall_valid(long int sysno)
8600 {
8601         if (!swrap_is_swrap_related_syscall(sysno)) {
8602                 return false;
8603         }
8604
8605         if (!socket_wrapper_enabled()) {
8606                 return false;
8607         }
8608
8609         return true;
8610 }
8611
8612 /* used by uid_wrapper */
8613 long int socket_wrapper_syscall_va(long int sysno, va_list va);
8614 long int socket_wrapper_syscall_va(long int sysno, va_list va)
8615 {
8616         if (!swrap_is_swrap_related_syscall(sysno)) {
8617                 errno = ENOSYS;
8618                 return -1;
8619         }
8620
8621         if (!socket_wrapper_enabled()) {
8622                 return libc_vsyscall(sysno, va);
8623         }
8624
8625         return swrap_syscall(sysno, va);
8626 }
8627 #endif /* HAVE_SYSCALL */
8628
8629 static void swrap_thread_prepare(void)
8630 {
8631         /*
8632          * This function should only be called here!!
8633          *
8634          * We bind all symobls to avoid deadlocks of the fork is
8635          * interrupted by a signal handler using a symbol of this
8636          * library.
8637          */
8638         swrap_bind_symbol_all();
8639
8640         SWRAP_LOCK_ALL;
8641 }
8642
8643 static void swrap_thread_parent(void)
8644 {
8645         SWRAP_UNLOCK_ALL;
8646 }
8647
8648 static void swrap_thread_child(void)
8649 {
8650         SWRAP_REINIT_ALL;
8651 }
8652
8653 /****************************
8654  * CONSTRUCTOR
8655  ***************************/
8656 void swrap_constructor(void)
8657 {
8658         if (PIPE_BUF < sizeof(struct swrap_unix_scm_rights)) {
8659                 SWRAP_LOG(SWRAP_LOG_ERROR,
8660                           "PIPE_BUF=%zu < "
8661                           "sizeof(struct swrap_unix_scm_rights)=%zu\n"
8662                           "sizeof(struct swrap_unix_scm_rights_payload)=%zu "
8663                           "sizeof(struct socket_info)=%zu",
8664                           (size_t)PIPE_BUF,
8665                           sizeof(struct swrap_unix_scm_rights),
8666                           sizeof(struct swrap_unix_scm_rights_payload),
8667                           sizeof(struct socket_info));
8668                 exit(-1);
8669         }
8670
8671         SWRAP_REINIT_ALL;
8672
8673         /*
8674         * If we hold a lock and the application forks, then the child
8675         * is not able to unlock the mutex and we are in a deadlock.
8676         * This should prevent such deadlocks.
8677         */
8678         pthread_atfork(&swrap_thread_prepare,
8679                        &swrap_thread_parent,
8680                        &swrap_thread_child);
8681 }
8682
8683 /****************************
8684  * DESTRUCTOR
8685  ***************************/
8686
8687 /*
8688  * This function is called when the library is unloaded and makes sure that
8689  * sockets get closed and the unix file for the socket are unlinked.
8690  */
8691 void swrap_destructor(void)
8692 {
8693         size_t i;
8694
8695         if (socket_fds_idx != NULL) {
8696                 for (i = 0; i < socket_fds_max; ++i) {
8697                         if (socket_fds_idx[i] != -1) {
8698                                 swrap_close(i);
8699                         }
8700                 }
8701                 SAFE_FREE(socket_fds_idx);
8702         }
8703
8704         SAFE_FREE(sockets);
8705
8706         if (swrap.libc.handle != NULL
8707 #ifdef RTLD_NEXT
8708             && swrap.libc.handle != RTLD_NEXT
8709 #endif
8710                         ) {
8711                 dlclose(swrap.libc.handle);
8712         }
8713         if (swrap.libc.socket_handle
8714 #ifdef RTLD_NEXT
8715             && swrap.libc.socket_handle != RTLD_NEXT
8716 #endif
8717                         ) {
8718                 dlclose(swrap.libc.socket_handle);
8719         }
8720 }
8721
8722 #if defined(HAVE__SOCKET) && defined(HAVE__CLOSE)
8723 /*
8724  * On FreeBSD 12 (and maybe other platforms)
8725  * system libraries like libresolv prefix there
8726  * syscalls with '_' in order to always use
8727  * the symbols from libc.
8728  *
8729  * In the interaction with resolv_wrapper,
8730  * we need to inject socket wrapper into libresolv,
8731  * which means we need to private all socket
8732  * related syscalls also with the '_' prefix.
8733  *
8734  * This is tested in Samba's 'make test',
8735  * there we noticed that providing '_read',
8736  * '_open' and '_close' would cause errors, which
8737  * means we skip '_read', '_write' and
8738  * all non socket related calls without
8739  * further analyzing the problem.
8740  */
8741 #define SWRAP_SYMBOL_ALIAS(__sym, __aliassym) \
8742         extern typeof(__sym) __aliassym __attribute__ ((alias(#__sym)))
8743
8744 #ifdef HAVE_ACCEPT4
8745 SWRAP_SYMBOL_ALIAS(accept4, _accept4);
8746 #endif
8747 SWRAP_SYMBOL_ALIAS(accept, _accept);
8748 SWRAP_SYMBOL_ALIAS(bind, _bind);
8749 SWRAP_SYMBOL_ALIAS(connect, _connect);
8750 SWRAP_SYMBOL_ALIAS(dup, _dup);
8751 SWRAP_SYMBOL_ALIAS(dup2, _dup2);
8752 SWRAP_SYMBOL_ALIAS(fcntl, _fcntl);
8753 SWRAP_SYMBOL_ALIAS(getpeername, _getpeername);
8754 SWRAP_SYMBOL_ALIAS(getsockname, _getsockname);
8755 SWRAP_SYMBOL_ALIAS(getsockopt, _getsockopt);
8756 SWRAP_SYMBOL_ALIAS(ioctl, _ioctl);
8757 SWRAP_SYMBOL_ALIAS(listen, _listen);
8758 SWRAP_SYMBOL_ALIAS(readv, _readv);
8759 SWRAP_SYMBOL_ALIAS(recv, _recv);
8760 SWRAP_SYMBOL_ALIAS(recvfrom, _recvfrom);
8761 SWRAP_SYMBOL_ALIAS(recvmsg, _recvmsg);
8762 SWRAP_SYMBOL_ALIAS(send, _send);
8763 SWRAP_SYMBOL_ALIAS(sendmsg, _sendmsg);
8764 SWRAP_SYMBOL_ALIAS(sendto, _sendto);
8765 SWRAP_SYMBOL_ALIAS(setsockopt, _setsockopt);
8766 SWRAP_SYMBOL_ALIAS(socket, _socket);
8767 SWRAP_SYMBOL_ALIAS(socketpair, _socketpair);
8768 SWRAP_SYMBOL_ALIAS(writev, _writev);
8769
8770 #endif /* SOCKET_WRAPPER_EXPORT_UNDERSCORE_SYMBOLS */