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