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