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