Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/lib/socket_wrapper
Files:
4 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/lib/socket_wrapper/socket_wrapper.c

    r740 r988  
    11/*
    2  * Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
    3  * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
     2 * Copyright (c) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
     3 * Copyright (C) 2006-2014 Stefan Metzmacher <metze@samba.org>
     4 * Copyright (C) 2013-2014 Andreas Schneider <asn@samba.org>
    45 *
    56 * All rights reserved.
    6  * 
     7 *
    78 * Redistribution and use in source and binary forms, with or without
    89 * modification, are permitted provided that the following conditions
    910 * are met:
    10  * 
     11 *
    1112 * 1. Redistributions of source code must retain the above copyright
    1213 *    notice, this list of conditions and the following disclaimer.
    13  * 
     14 *
    1415 * 2. Redistributions in binary form must reproduce the above copyright
    1516 *    notice, this list of conditions and the following disclaimer in the
    1617 *    documentation and/or other materials provided with the distribution.
    17  * 
     18 *
    1819 * 3. Neither the name of the author nor the names of its contributors
    1920 *    may be used to endorse or promote products derived from this software
    2021 *    without specific prior written permission.
    21  * 
     22 *
    2223 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
    2324 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     
    4041*/
    4142
    42 #ifdef _SAMBA_BUILD_
    43 
    44 #define SOCKET_WRAPPER_NOT_REPLACE
    45 #include "../replace/replace.h"
    46 #include "system/network.h"
    47 #include "system/filesys.h"
    48 #include "system/time.h"
    49 
    50 #else /* _SAMBA_BUILD_ */
     43#include "config.h"
    5144
    5245#include <sys/types.h>
     
    5548#include <sys/socket.h>
    5649#include <sys/ioctl.h>
     50#ifdef HAVE_SYS_FILIO_H
    5751#include <sys/filio.h>
     52#endif
     53#ifdef HAVE_SYS_SIGNALFD_H
     54#include <sys/signalfd.h>
     55#endif
     56#ifdef HAVE_SYS_EVENTFD_H
     57#include <sys/eventfd.h>
     58#endif
     59#ifdef HAVE_SYS_TIMERFD_H
     60#include <sys/timerfd.h>
     61#endif
     62#include <sys/uio.h>
    5863#include <errno.h>
    5964#include <sys/un.h>
    6065#include <netinet/in.h>
    6166#include <netinet/tcp.h>
     67#include <arpa/inet.h>
    6268#include <fcntl.h>
    6369#include <stdlib.h>
    64 #include <unistd.h>
    6570#include <string.h>
    6671#include <stdio.h>
    6772#include <stdint.h>
    68 
    69 #endif
    70 
    71 #ifndef _PUBLIC_
    72 #define _PUBLIC_
    73 #endif
     73#include <stdarg.h>
     74#include <stdbool.h>
     75#include <unistd.h>
     76#ifdef HAVE_GNU_LIB_NAMES_H
     77#include <gnu/lib-names.h>
     78#endif
     79#ifdef HAVE_RPC_RPC_H
     80#include <rpc/rpc.h>
     81#endif
     82
     83enum swrap_dbglvl_e {
     84        SWRAP_LOG_ERROR = 0,
     85        SWRAP_LOG_WARN,
     86        SWRAP_LOG_DEBUG,
     87        SWRAP_LOG_TRACE
     88};
     89
     90/* GCC have printf type attribute check. */
     91#ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
     92#define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
     93#else
     94#define PRINTF_ATTRIBUTE(a,b)
     95#endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
     96
     97#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
     98#define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
     99#else
     100#define DESTRUCTOR_ATTRIBUTE
     101#endif
     102
     103#ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
     104#define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address))
     105#else
     106#define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
     107#endif
     108
     109#ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
     110# define SWRAP_THREAD __thread
     111#else
     112# define SWRAP_THREAD
     113#endif
     114
     115#ifndef MIN
     116#define MIN(a,b) ((a)<(b)?(a):(b))
     117#endif
     118
     119#ifndef ZERO_STRUCT
     120#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
     121#endif
     122
     123#ifndef ZERO_STRUCTP
     124#define ZERO_STRUCTP(x) do { \
     125                if ((x) != NULL) \
     126                        memset((char *)(x), 0, sizeof(*(x))); \
     127        } while(0)
     128#endif
     129
     130#ifndef discard_const
     131#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
     132#endif
     133
     134#ifndef discard_const_p
     135#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
     136#endif
     137
     138#ifdef IPV6_PKTINFO
     139# ifndef IPV6_RECVPKTINFO
     140#  define IPV6_RECVPKTINFO IPV6_PKTINFO
     141# endif /* IPV6_RECVPKTINFO */
     142#endif /* IPV6_PKTINFO */
     143
     144/*
     145 * On BSD IP_PKTINFO has a different name because during
     146 * the time when they implemented it, there was no RFC.
     147 * The name for IPv6 is the same as on Linux.
     148 */
     149#ifndef IP_PKTINFO
     150# ifdef IP_RECVDSTADDR
     151#  define IP_PKTINFO IP_RECVDSTADDR
     152# endif
     153#endif
     154
    74155
    75156#define SWRAP_DLIST_ADD(list,item) do { \
     
    104185} while (0)
    105186
    106 /* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
    107  * for now */
    108 #define REWRITE_CALLS
    109 
    110 #ifdef REWRITE_CALLS
    111 #define real_accept accept
    112 #define real_connect connect
    113 #define real_bind bind
    114 #define real_listen listen
    115 #define real_getpeername getpeername
    116 #define real_getsockname getsockname
    117 #define real_getsockopt getsockopt
    118 #define real_setsockopt setsockopt
    119 #define real_recvfrom recvfrom
    120 #define real_sendto sendto
    121 #define real_sendmsg sendmsg
    122 #define real_ioctl ioctl
    123 #define real_recv recv
    124 #define real_read read
    125 #define real_send send
    126 #define real_readv readv
    127 #define real_writev writev
    128 #define real_socket socket
    129 #define real_close close
    130 #endif
    131 
    132 #ifdef HAVE_GETTIMEOFDAY_TZ
     187#if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
    133188#define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
    134189#else
     
    138193/* we need to use a very terse format here as IRIX 6.4 silently
    139194   truncates names to 16 chars, so if we use a longer name then we
    140    can't tell which port a packet came from with recvfrom() 
    141    
     195   can't tell which port a packet came from with recvfrom()
     196
    142197   with this format we have 8 chars left for the directory name
    143198*/
     
    148203#define SOCKET_TYPE_CHAR_UDP_V6         'Y'
    149204
    150 #define MAX_WRAPPED_INTERFACES 16
    151 
     205/*
     206 * Set the packet MTU to 1500 bytes for stream sockets to make it it easier to
     207 * format PCAP capture files (as the caller will simply continue from here).
     208 */
     209#define SOCKET_WRAPPER_MTU_DEFAULT 1500
     210#define SOCKET_WRAPPER_MTU_MIN     512
     211#define SOCKET_WRAPPER_MTU_MAX     32768
     212
     213#define SOCKET_MAX_SOCKETS 1024
     214
     215/* This limit is to avoid broadcast sendto() needing to stat too many
     216 * files.  It may be raised (with a performance cost) to up to 254
     217 * without changing the format above */
     218#define MAX_WRAPPED_INTERFACES 40
     219
     220struct swrap_address {
     221        socklen_t sa_socklen;
     222        union {
     223                struct sockaddr s;
     224                struct sockaddr_in in;
    152225#ifdef HAVE_IPV6
    153 /*
    154  * FD00::5357:5FXX
    155  */
    156 static const struct in6_addr *swrap_ipv6(void)
    157 {
    158         static struct in6_addr v;
    159         static int initialized;
    160         int ret;
    161 
    162         if (initialized) {
    163                 return &v;
    164         }
    165         initialized = 1;
    166 
    167         ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
    168         if (ret <= 0) {
    169                 abort();
    170         }
    171 
    172         return &v;
    173 }
    174 #endif
    175 
    176 static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
    177 {
    178         struct sockaddr *ret = (struct sockaddr *)malloc(len);
    179         memcpy(ret, data, len);
    180         return ret;
    181 }
    182 
    183 static void set_port(int family, int prt, struct sockaddr *addr)
    184 {
    185         switch (family) {
    186         case AF_INET:
    187                 ((struct sockaddr_in *)addr)->sin_port = htons(prt);
    188                 break;
    189 #ifdef HAVE_IPV6
    190         case AF_INET6:
    191                 ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt);
    192                 break;
    193 #endif
    194         }
    195 }
    196 
    197 static size_t socket_length(int family)
    198 {
    199         switch (family) {
    200         case AF_INET:
    201                 return sizeof(struct sockaddr_in);
    202 #ifdef HAVE_IPV6
    203         case AF_INET6:
    204                 return sizeof(struct sockaddr_in6);
    205 #endif
    206         }
    207         return 0;
    208 }
    209 
    210 
     226                struct sockaddr_in6 in6;
     227#endif
     228                struct sockaddr_un un;
     229                struct sockaddr_storage ss;
     230        } sa;
     231};
     232
     233struct socket_info_fd {
     234        struct socket_info_fd *prev, *next;
     235        int fd;
     236};
    211237
    212238struct socket_info
    213239{
    214         int fd;
     240        struct socket_info_fd *fds;
    215241
    216242        int family;
     
    222248        int connected;
    223249        int defer_connect;
    224 
    225         char *path;
    226         char *tmp_path;
    227 
    228         struct sockaddr *myname;
    229         socklen_t myname_len;
    230 
    231         struct sockaddr *peername;
    232         socklen_t peername_len;
     250        int pktinfo;
     251
     252        /* The unix path so we can unlink it on close() */
     253        struct sockaddr_un un_addr;
     254
     255        struct swrap_address bindname;
     256        struct swrap_address myname;
     257        struct swrap_address peername;
    233258
    234259        struct {
     
    240265};
    241266
    242 static struct socket_info *sockets;
    243 
    244 const char *socket_wrapper_dir(void)
     267/*
     268 * File descriptors are shared between threads so we should share socket
     269 * information too.
     270 */
     271struct socket_info *sockets;
     272
     273/* Function prototypes */
     274
     275bool socket_wrapper_enabled(void);
     276void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
     277
     278#ifdef NDEBUG
     279# define SWRAP_LOG(...)
     280#else
     281
     282static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
     283# define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
     284
     285static void swrap_log(enum swrap_dbglvl_e dbglvl,
     286                      const char *func,
     287                      const char *format, ...)
     288{
     289        char buffer[1024];
     290        va_list va;
     291        const char *d;
     292        unsigned int lvl = 0;
     293
     294        d = getenv("SOCKET_WRAPPER_DEBUGLEVEL");
     295        if (d != NULL) {
     296                lvl = atoi(d);
     297        }
     298
     299        va_start(va, format);
     300        vsnprintf(buffer, sizeof(buffer), format, va);
     301        va_end(va);
     302
     303        if (lvl >= dbglvl) {
     304                switch (dbglvl) {
     305                        case SWRAP_LOG_ERROR:
     306                                fprintf(stderr,
     307                                        "SWRAP_ERROR(%d) - %s: %s\n",
     308                                        (int)getpid(), func, buffer);
     309                                break;
     310                        case SWRAP_LOG_WARN:
     311                                fprintf(stderr,
     312                                        "SWRAP_WARN(%d) - %s: %s\n",
     313                                        (int)getpid(), func, buffer);
     314                                break;
     315                        case SWRAP_LOG_DEBUG:
     316                                fprintf(stderr,
     317                                        "SWRAP_DEBUG(%d) - %s: %s\n",
     318                                        (int)getpid(), func, buffer);
     319                                break;
     320                        case SWRAP_LOG_TRACE:
     321                                fprintf(stderr,
     322                                        "SWRAP_TRACE(%d) - %s: %s\n",
     323                                        (int)getpid(), func, buffer);
     324                                break;
     325                }
     326        }
     327}
     328#endif
     329
     330/*********************************************************
     331 * SWRAP LOADING LIBC FUNCTIONS
     332 *********************************************************/
     333
     334#include <dlfcn.h>
     335
     336struct swrap_libc_fns {
     337        int (*libc_accept)(int sockfd,
     338                           struct sockaddr *addr,
     339                           socklen_t *addrlen);
     340        int (*libc_bind)(int sockfd,
     341                         const struct sockaddr *addr,
     342                         socklen_t addrlen);
     343        int (*libc_close)(int fd);
     344        int (*libc_connect)(int sockfd,
     345                            const struct sockaddr *addr,
     346                            socklen_t addrlen);
     347        int (*libc_dup)(int fd);
     348        int (*libc_dup2)(int oldfd, int newfd);
     349        int (*libc_fcntl)(int fd, int cmd, ...);
     350        FILE *(*libc_fopen)(const char *name, const char *mode);
     351#ifdef HAVE_EVENTFD
     352        int (*libc_eventfd)(int count, int flags);
     353#endif
     354        int (*libc_getpeername)(int sockfd,
     355                                struct sockaddr *addr,
     356                                socklen_t *addrlen);
     357        int (*libc_getsockname)(int sockfd,
     358                                struct sockaddr *addr,
     359                                socklen_t *addrlen);
     360        int (*libc_getsockopt)(int sockfd,
     361                               int level,
     362                               int optname,
     363                               void *optval,
     364                               socklen_t *optlen);
     365        int (*libc_ioctl)(int d, unsigned long int request, ...);
     366        int (*libc_listen)(int sockfd, int backlog);
     367        int (*libc_open)(const char *pathname, int flags, mode_t mode);
     368        int (*libc_pipe)(int pipefd[2]);
     369        int (*libc_read)(int fd, void *buf, size_t count);
     370        ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
     371        int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
     372        int (*libc_recvfrom)(int sockfd,
     373                             void *buf,
     374                             size_t len,
     375                             int flags,
     376                             struct sockaddr *src_addr,
     377                             socklen_t *addrlen);
     378        int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
     379        int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
     380        int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
     381        int (*libc_sendto)(int sockfd,
     382                           const void *buf,
     383                           size_t len,
     384                           int flags,
     385                           const  struct sockaddr *dst_addr,
     386                           socklen_t addrlen);
     387        int (*libc_setsockopt)(int sockfd,
     388                               int level,
     389                               int optname,
     390                               const void *optval,
     391                               socklen_t optlen);
     392#ifdef HAVE_SIGNALFD
     393        int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
     394#endif
     395        int (*libc_socket)(int domain, int type, int protocol);
     396        int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
     397#ifdef HAVE_TIMERFD_CREATE
     398        int (*libc_timerfd_create)(int clockid, int flags);
     399#endif
     400        ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
     401};
     402
     403struct swrap {
     404        void *libc_handle;
     405        void *libsocket_handle;
     406
     407        bool initialised;
     408        bool enabled;
     409
     410        char *socket_dir;
     411
     412        struct swrap_libc_fns fns;
     413};
     414
     415static struct swrap swrap;
     416
     417/* prototypes */
     418static const char *socket_wrapper_dir(void);
     419
     420#define LIBC_NAME "libc.so"
     421
     422enum swrap_lib {
     423    SWRAP_LIBC,
     424    SWRAP_LIBNSL,
     425    SWRAP_LIBSOCKET,
     426};
     427
     428#ifndef NDEBUG
     429static const char *swrap_str_lib(enum swrap_lib lib)
     430{
     431        switch (lib) {
     432        case SWRAP_LIBC:
     433                return "libc";
     434        case SWRAP_LIBNSL:
     435                return "libnsl";
     436        case SWRAP_LIBSOCKET:
     437                return "libsocket";
     438        }
     439
     440        /* Compiler would warn us about unhandled enum value if we get here */
     441        return "unknown";
     442}
     443#endif
     444
     445static void *swrap_load_lib_handle(enum swrap_lib lib)
     446{
     447        int flags = RTLD_LAZY;
     448        void *handle = NULL;
     449        int i;
     450
     451#ifdef RTLD_DEEPBIND
     452        flags |= RTLD_DEEPBIND;
     453#endif
     454
     455        switch (lib) {
     456        case SWRAP_LIBNSL:
     457                /* FALL TROUGH */
     458        case SWRAP_LIBSOCKET:
     459#ifdef HAVE_LIBSOCKET
     460                handle = swrap.libsocket_handle;
     461                if (handle == NULL) {
     462                        for (i = 10; i >= 0; i--) {
     463                                char soname[256] = {0};
     464
     465                                snprintf(soname, sizeof(soname), "libsocket.so.%d", i);
     466                                handle = dlopen(soname, flags);
     467                                if (handle != NULL) {
     468                                        break;
     469                                }
     470                        }
     471
     472                        swrap.libsocket_handle = handle;
     473                }
     474                break;
     475#endif
     476                /* FALL TROUGH */
     477        case SWRAP_LIBC:
     478                handle = swrap.libc_handle;
     479#ifdef LIBC_SO
     480                if (handle == NULL) {
     481                        handle = dlopen(LIBC_SO, flags);
     482
     483                        swrap.libc_handle = handle;
     484                }
     485#endif
     486                if (handle == NULL) {
     487                        for (i = 10; i >= 0; i--) {
     488                                char soname[256] = {0};
     489
     490                                snprintf(soname, sizeof(soname), "libc.so.%d", i);
     491                                handle = dlopen(soname, flags);
     492                                if (handle != NULL) {
     493                                        break;
     494                                }
     495                        }
     496
     497                        swrap.libc_handle = handle;
     498                }
     499                break;
     500        }
     501
     502        if (handle == NULL) {
     503#ifdef RTLD_NEXT
     504                handle = swrap.libc_handle = swrap.libsocket_handle = RTLD_NEXT;
     505#else
     506                SWRAP_LOG(SWRAP_LOG_ERROR,
     507                          "Failed to dlopen library: %s\n",
     508                          dlerror());
     509                exit(-1);
     510#endif
     511        }
     512
     513        return handle;
     514}
     515
     516static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
     517{
     518        void *handle;
     519        void *func;
     520
     521        handle = swrap_load_lib_handle(lib);
     522
     523        func = dlsym(handle, fn_name);
     524        if (func == NULL) {
     525                SWRAP_LOG(SWRAP_LOG_ERROR,
     526                                "Failed to find %s: %s\n",
     527                                fn_name, dlerror());
     528                exit(-1);
     529        }
     530
     531        SWRAP_LOG(SWRAP_LOG_TRACE,
     532                        "Loaded %s from %s",
     533                        fn_name, swrap_str_lib(lib));
     534        return func;
     535}
     536
     537#define swrap_load_lib_function(lib, fn_name) \
     538        if (swrap.fns.libc_##fn_name == NULL) { \
     539                void *swrap_cast_ptr = _swrap_load_lib_function(lib, #fn_name); \
     540                *(void **) (&swrap.fns.libc_##fn_name) = \
     541                        swrap_cast_ptr; \
     542        }
     543
     544
     545/*
     546 * IMPORTANT
     547 *
     548 * Functions especially from libc need to be loaded individually, you can't load
     549 * all at once or gdb will segfault at startup. The same applies to valgrind and
     550 * has probably something todo with with the linker.
     551 * So we need load each function at the point it is called the first time.
     552 */
     553static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
     554{
     555        swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
     556
     557        return swrap.fns.libc_accept(sockfd, addr, addrlen);
     558}
     559
     560static int libc_bind(int sockfd,
     561                     const struct sockaddr *addr,
     562                     socklen_t addrlen)
     563{
     564        swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
     565
     566        return swrap.fns.libc_bind(sockfd, addr, addrlen);
     567}
     568
     569static int libc_close(int fd)
     570{
     571        swrap_load_lib_function(SWRAP_LIBC, close);
     572
     573        return swrap.fns.libc_close(fd);
     574}
     575
     576static int libc_connect(int sockfd,
     577                        const struct sockaddr *addr,
     578                        socklen_t addrlen)
     579{
     580        swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
     581
     582        return swrap.fns.libc_connect(sockfd, addr, addrlen);
     583}
     584
     585static int libc_dup(int fd)
     586{
     587        swrap_load_lib_function(SWRAP_LIBC, dup);
     588
     589        return swrap.fns.libc_dup(fd);
     590}
     591
     592static int libc_dup2(int oldfd, int newfd)
     593{
     594        swrap_load_lib_function(SWRAP_LIBC, dup2);
     595
     596        return swrap.fns.libc_dup2(oldfd, newfd);
     597}
     598
     599#ifdef HAVE_EVENTFD
     600static int libc_eventfd(int count, int flags)
     601{
     602        swrap_load_lib_function(SWRAP_LIBC, eventfd);
     603
     604        return swrap.fns.libc_eventfd(count, flags);
     605}
     606#endif
     607
     608DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
     609static int libc_vfcntl(int fd, int cmd, va_list ap)
     610{
     611        long int args[4];
     612        int rc;
     613        int i;
     614
     615        swrap_load_lib_function(SWRAP_LIBC, fcntl);
     616
     617        for (i = 0; i < 4; i++) {
     618                args[i] = va_arg(ap, long int);
     619        }
     620
     621        rc = swrap.fns.libc_fcntl(fd,
     622                                  cmd,
     623                                  args[0],
     624                                  args[1],
     625                                  args[2],
     626                                  args[3]);
     627
     628        return rc;
     629}
     630
     631static int libc_getpeername(int sockfd,
     632                            struct sockaddr *addr,
     633                            socklen_t *addrlen)
     634{
     635        swrap_load_lib_function(SWRAP_LIBSOCKET, getpeername);
     636
     637        return swrap.fns.libc_getpeername(sockfd, addr, addrlen);
     638}
     639
     640static int libc_getsockname(int sockfd,
     641                            struct sockaddr *addr,
     642                            socklen_t *addrlen)
     643{
     644        swrap_load_lib_function(SWRAP_LIBSOCKET, getsockname);
     645
     646        return swrap.fns.libc_getsockname(sockfd, addr, addrlen);
     647}
     648
     649static int libc_getsockopt(int sockfd,
     650                           int level,
     651                           int optname,
     652                           void *optval,
     653                           socklen_t *optlen)
     654{
     655        swrap_load_lib_function(SWRAP_LIBSOCKET, getsockopt);
     656
     657        return swrap.fns.libc_getsockopt(sockfd, level, optname, optval, optlen);
     658}
     659
     660DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
     661static int libc_vioctl(int d, unsigned long int request, va_list ap)
     662{
     663        long int args[4];
     664        int rc;
     665        int i;
     666
     667        swrap_load_lib_function(SWRAP_LIBC, ioctl);
     668
     669        for (i = 0; i < 4; i++) {
     670                args[i] = va_arg(ap, long int);
     671        }
     672
     673        rc = swrap.fns.libc_ioctl(d,
     674                                  request,
     675                                  args[0],
     676                                  args[1],
     677                                  args[2],
     678                                  args[3]);
     679
     680        return rc;
     681}
     682
     683static int libc_listen(int sockfd, int backlog)
     684{
     685        swrap_load_lib_function(SWRAP_LIBSOCKET, listen);
     686
     687        return swrap.fns.libc_listen(sockfd, backlog);
     688}
     689
     690static FILE *libc_fopen(const char *name, const char *mode)
     691{
     692        swrap_load_lib_function(SWRAP_LIBC, fopen);
     693
     694        return swrap.fns.libc_fopen(name, mode);
     695}
     696
     697static int libc_vopen(const char *pathname, int flags, va_list ap)
     698{
     699        long int mode = 0;
     700        int fd;
     701
     702        swrap_load_lib_function(SWRAP_LIBC, open);
     703
     704        mode = va_arg(ap, long int);
     705
     706        fd = swrap.fns.libc_open(pathname, flags, (mode_t)mode);
     707
     708        return fd;
     709}
     710
     711static int libc_open(const char *pathname, int flags, ...)
     712{
     713        va_list ap;
     714        int fd;
     715
     716        va_start(ap, flags);
     717        fd = libc_vopen(pathname, flags, ap);
     718        va_end(ap);
     719
     720        return fd;
     721}
     722
     723static int libc_pipe(int pipefd[2])
     724{
     725        swrap_load_lib_function(SWRAP_LIBSOCKET, pipe);
     726
     727        return swrap.fns.libc_pipe(pipefd);
     728}
     729
     730static int libc_read(int fd, void *buf, size_t count)
     731{
     732        swrap_load_lib_function(SWRAP_LIBC, read);
     733
     734        return swrap.fns.libc_read(fd, buf, count);
     735}
     736
     737static ssize_t libc_readv(int fd, const struct iovec *iov, int iovcnt)
     738{
     739        swrap_load_lib_function(SWRAP_LIBSOCKET, readv);
     740
     741        return swrap.fns.libc_readv(fd, iov, iovcnt);
     742}
     743
     744static int libc_recv(int sockfd, void *buf, size_t len, int flags)
     745{
     746        swrap_load_lib_function(SWRAP_LIBSOCKET, recv);
     747
     748        return swrap.fns.libc_recv(sockfd, buf, len, flags);
     749}
     750
     751static int libc_recvfrom(int sockfd,
     752                         void *buf,
     753                         size_t len,
     754                         int flags,
     755                         struct sockaddr *src_addr,
     756                         socklen_t *addrlen)
     757{
     758        swrap_load_lib_function(SWRAP_LIBSOCKET, recvfrom);
     759
     760        return swrap.fns.libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
     761}
     762
     763static int libc_recvmsg(int sockfd, struct msghdr *msg, int flags)
     764{
     765        swrap_load_lib_function(SWRAP_LIBSOCKET, recvmsg);
     766
     767        return swrap.fns.libc_recvmsg(sockfd, msg, flags);
     768}
     769
     770static int libc_send(int sockfd, const void *buf, size_t len, int flags)
     771{
     772        swrap_load_lib_function(SWRAP_LIBSOCKET, send);
     773
     774        return swrap.fns.libc_send(sockfd, buf, len, flags);
     775}
     776
     777static int libc_sendmsg(int sockfd, const struct msghdr *msg, int flags)
     778{
     779        swrap_load_lib_function(SWRAP_LIBSOCKET, sendmsg);
     780
     781        return swrap.fns.libc_sendmsg(sockfd, msg, flags);
     782}
     783
     784static int libc_sendto(int sockfd,
     785                       const void *buf,
     786                       size_t len,
     787                       int flags,
     788                       const  struct sockaddr *dst_addr,
     789                       socklen_t addrlen)
     790{
     791        swrap_load_lib_function(SWRAP_LIBSOCKET, sendto);
     792
     793        return swrap.fns.libc_sendto(sockfd, buf, len, flags, dst_addr, addrlen);
     794}
     795
     796static int libc_setsockopt(int sockfd,
     797                           int level,
     798                           int optname,
     799                           const void *optval,
     800                           socklen_t optlen)
     801{
     802        swrap_load_lib_function(SWRAP_LIBSOCKET, setsockopt);
     803
     804        return swrap.fns.libc_setsockopt(sockfd, level, optname, optval, optlen);
     805}
     806
     807#ifdef HAVE_SIGNALFD
     808static int libc_signalfd(int fd, const sigset_t *mask, int flags)
     809{
     810        swrap_load_lib_function(SWRAP_LIBSOCKET, signalfd);
     811
     812        return swrap.fns.libc_signalfd(fd, mask, flags);
     813}
     814#endif
     815
     816static int libc_socket(int domain, int type, int protocol)
     817{
     818        swrap_load_lib_function(SWRAP_LIBSOCKET, socket);
     819
     820        return swrap.fns.libc_socket(domain, type, protocol);
     821}
     822
     823static int libc_socketpair(int domain, int type, int protocol, int sv[2])
     824{
     825        swrap_load_lib_function(SWRAP_LIBSOCKET, socketpair);
     826
     827        return swrap.fns.libc_socketpair(domain, type, protocol, sv);
     828}
     829
     830#ifdef HAVE_TIMERFD_CREATE
     831static int libc_timerfd_create(int clockid, int flags)
     832{
     833        swrap_load_lib_function(SWRAP_LIBC, timerfd_create);
     834
     835        return swrap.fns.libc_timerfd_create(clockid, flags);
     836}
     837#endif
     838
     839static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt)
     840{
     841        swrap_load_lib_function(SWRAP_LIBSOCKET, writev);
     842
     843        return swrap.fns.libc_writev(fd, iov, iovcnt);
     844}
     845
     846/*********************************************************
     847 * SWRAP HELPER FUNCTIONS
     848 *********************************************************/
     849
     850#ifdef HAVE_IPV6
     851/*
     852 * FD00::5357:5FXX
     853 */
     854static const struct in6_addr *swrap_ipv6(void)
     855{
     856        static struct in6_addr v;
     857        static int initialized;
     858        int ret;
     859
     860        if (initialized) {
     861                return &v;
     862        }
     863        initialized = 1;
     864
     865        ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v);
     866        if (ret <= 0) {
     867                abort();
     868        }
     869
     870        return &v;
     871}
     872#endif
     873
     874static void set_port(int family, int prt, struct swrap_address *addr)
     875{
     876        switch (family) {
     877        case AF_INET:
     878                addr->sa.in.sin_port = htons(prt);
     879                break;
     880#ifdef HAVE_IPV6
     881        case AF_INET6:
     882                addr->sa.in6.sin6_port = htons(prt);
     883                break;
     884#endif
     885        }
     886}
     887
     888static size_t socket_length(int family)
     889{
     890        switch (family) {
     891        case AF_INET:
     892                return sizeof(struct sockaddr_in);
     893#ifdef HAVE_IPV6
     894        case AF_INET6:
     895                return sizeof(struct sockaddr_in6);
     896#endif
     897        }
     898        return 0;
     899}
     900
     901static const char *socket_wrapper_dir(void)
    245902{
    246903        const char *s = getenv("SOCKET_WRAPPER_DIR");
     
    248905                return NULL;
    249906        }
     907        /* TODO use realpath(3) here, when we add support for threads */
    250908        if (strncmp(s, "./", 2) == 0) {
    251909                s += 2;
    252910        }
     911
     912        SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s);
    253913        return s;
    254914}
    255915
    256 unsigned int socket_wrapper_default_iface(void)
     916static unsigned int socket_wrapper_mtu(void)
     917{
     918        static unsigned int max_mtu = 0;
     919        unsigned int tmp;
     920        const char *s;
     921        char *endp;
     922
     923        if (max_mtu != 0) {
     924                return max_mtu;
     925        }
     926
     927        max_mtu = SOCKET_WRAPPER_MTU_DEFAULT;
     928
     929        s = getenv("SOCKET_WRAPPER_MTU");
     930        if (s == NULL) {
     931                goto done;
     932        }
     933
     934        tmp = strtol(s, &endp, 10);
     935        if (s == endp) {
     936                goto done;
     937        }
     938
     939        if (tmp < SOCKET_WRAPPER_MTU_MIN || tmp > SOCKET_WRAPPER_MTU_MAX) {
     940                goto done;
     941        }
     942        max_mtu = tmp;
     943
     944done:
     945        return max_mtu;
     946}
     947
     948bool socket_wrapper_enabled(void)
     949{
     950        const char *s = socket_wrapper_dir();
     951
     952        return s != NULL ? true : false;
     953}
     954
     955static unsigned int socket_wrapper_default_iface(void)
    257956{
    258957        const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE");
     
    284983        }
    285984
     985        SWRAP_LOG(SWRAP_LOG_TRACE, "type %c iface %u port %u",
     986                        type, iface, prt);
     987
    286988        if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
    287989                errno = EINVAL;
     
    3521054        switch (inaddr->sa_family) {
    3531055        case AF_INET: {
    354                 const struct sockaddr_in *in = 
     1056                const struct sockaddr_in *in =
    3551057                    (const struct sockaddr_in *)(const void *)inaddr;
    3561058                unsigned int addr = ntohl(in->sin_addr.s_addr);
     
    3681070                        b_type = SOCKET_TYPE_CHAR_UDP;
    3691071                        break;
     1072                default:
     1073                        SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
     1074                        errno = ESOCKTNOSUPPORT;
     1075                        return -1;
    3701076                }
    3711077
     
    3951101#ifdef HAVE_IPV6
    3961102        case AF_INET6: {
    397                 const struct sockaddr_in6 *in = 
     1103                const struct sockaddr_in6 *in =
    3981104                    (const struct sockaddr_in6 *)(const void *)inaddr;
    3991105                struct in6_addr cmp1, cmp2;
     
    4061112                        type = SOCKET_TYPE_CHAR_UDP_V6;
    4071113                        break;
     1114                default:
     1115                        SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
     1116                        errno = ESOCKTNOSUPPORT;
     1117                        return -1;
    4081118                }
    4091119
     
    4261136#endif
    4271137        default:
     1138                SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family!\n");
    4281139                errno = ENETUNREACH;
    4291140                return -1;
     
    4311142
    4321143        if (prt == 0) {
     1144                SWRAP_LOG(SWRAP_LOG_WARN, "Port not set\n");
    4331145                errno = EINVAL;
    4341146                return -1;
     
    4361148
    4371149        if (is_bcast) {
    438                 snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 
     1150                snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL",
    4391151                         socket_wrapper_dir());
     1152                SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
    4401153                /* the caller need to do more processing */
    4411154                return 0;
    4421155        }
    4431156
    444         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
     1157        snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
    4451158                 socket_wrapper_dir(), type, iface, prt);
     1159        SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
    4461160
    4471161        return 0;
     
    4611175        switch (si->family) {
    4621176        case AF_INET: {
    463                 const struct sockaddr_in *in = 
     1177                const struct sockaddr_in *in =
    4641178                    (const struct sockaddr_in *)(const void *)inaddr;
    4651179                unsigned int addr = ntohl(in->sin_addr.s_addr);
     
    4821196                        b_type = SOCKET_TYPE_CHAR_UDP;
    4831197                        break;
     1198                default:
     1199                        SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
     1200                        errno = ESOCKTNOSUPPORT;
     1201                        return -1;
    4841202                }
    4851203
     
    5081226                        return -1;
    5091227                }
     1228
     1229                /* Store the bind address for connect() */
     1230                if (si->bindname.sa_socklen == 0) {
     1231                        struct sockaddr_in bind_in;
     1232                        socklen_t blen = sizeof(struct sockaddr_in);
     1233
     1234                        ZERO_STRUCT(bind_in);
     1235                        bind_in.sin_family = in->sin_family;
     1236                        bind_in.sin_port = in->sin_port;
     1237                        bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface);
     1238
     1239                        si->bindname.sa_socklen = blen;
     1240                        memcpy(&si->bindname.sa.in, &bind_in, blen);
     1241                }
     1242
    5101243                break;
    5111244        }
    5121245#ifdef HAVE_IPV6
    5131246        case AF_INET6: {
    514                 const struct sockaddr_in6 *in = 
     1247                const struct sockaddr_in6 *in =
    5151248                    (const struct sockaddr_in6 *)(const void *)inaddr;
    5161249                struct in6_addr cmp1, cmp2;
     
    5231256                        type = SOCKET_TYPE_CHAR_UDP_V6;
    5241257                        break;
     1258                default:
     1259                        SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
     1260                        errno = ESOCKTNOSUPPORT;
     1261                        return -1;
    5251262                }
    5261263
     
    5411278                }
    5421279
     1280                /* Store the bind address for connect() */
     1281                if (si->bindname.sa_socklen == 0) {
     1282                        struct sockaddr_in6 bind_in;
     1283                        socklen_t blen = sizeof(struct sockaddr_in6);
     1284
     1285                        ZERO_STRUCT(bind_in);
     1286                        bind_in.sin6_family = in->sin6_family;
     1287                        bind_in.sin6_port = in->sin6_port;
     1288
     1289                        bind_in.sin6_addr = *swrap_ipv6();
     1290                        bind_in.sin6_addr.s6_addr[15] = iface;
     1291
     1292                        memcpy(&si->bindname.sa.in6, &bind_in, blen);
     1293                        si->bindname.sa_socklen = blen;
     1294                }
     1295
    5431296                break;
    5441297        }
    5451298#endif
    5461299        default:
     1300                SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
    5471301                errno = EADDRNOTAVAIL;
    5481302                return -1;
     
    5511305
    5521306        if (bcast) *bcast = is_bcast;
     1307
     1308        if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) {
     1309                errno = EINVAL;
     1310                return -1;
     1311        }
    5531312
    5541313        if (prt == 0) {
    5551314                /* handle auto-allocation of ephemeral ports */
    5561315                for (prt = 5001; prt < 10000; prt++) {
    557                         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
     1316                        snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
    5581317                                 socket_wrapper_dir(), type, iface, prt);
    5591318                        if (stat(un->sun_path, &st) == 0) continue;
    5601319
    561                         set_port(si->family, prt, si->myname);
     1320                        set_port(si->family, prt, &si->myname);
     1321                        set_port(si->family, prt, &si->bindname);
     1322
    5621323                        break;
    5631324                }
     
    5681329        }
    5691330
    570         snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
     1331        snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT,
    5711332                 socket_wrapper_dir(), type, iface, prt);
     1333        SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path);
    5721334        return 0;
    5731335}
     
    5761338{
    5771339        struct socket_info *i;
     1340
    5781341        for (i = sockets; i; i = i->next) {
    579                 if (i->fd == fd)
    580                         return i;
     1342                struct socket_info_fd *f;
     1343                for (f = i->fds; f; f = f->next) {
     1344                        if (f->fd == fd) {
     1345                                return i;
     1346                        }
     1347                }
    5811348        }
    5821349
     
    5841351}
    5851352
    586 static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len,
    587                                   struct sockaddr_un *out_addr, int alloc_sock, int *bcast)
     1353#if 0 /* FIXME */
     1354static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
     1355{
     1356        struct socket_info *s;
     1357
     1358        /* first catch invalid input */
     1359        switch (sa->sa_family) {
     1360        case AF_INET:
     1361                if (len < sizeof(struct sockaddr_in)) {
     1362                        return false;
     1363                }
     1364                break;
     1365#if HAVE_IPV6
     1366        case AF_INET6:
     1367                if (len < sizeof(struct sockaddr_in6)) {
     1368                        return false;
     1369                }
     1370                break;
     1371#endif
     1372        default:
     1373                return false;
     1374                break;
     1375        }
     1376
     1377        for (s = sockets; s != NULL; s = s->next) {
     1378                if (s->myname == NULL) {
     1379                        continue;
     1380                }
     1381                if (s->myname->sa_family != sa->sa_family) {
     1382                        continue;
     1383                }
     1384                switch (s->myname->sa_family) {
     1385                case AF_INET: {
     1386                        struct sockaddr_in *sin1, *sin2;
     1387
     1388                        sin1 = (struct sockaddr_in *)s->myname;
     1389                        sin2 = (struct sockaddr_in *)sa;
     1390
     1391                        if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
     1392                                continue;
     1393                        }
     1394                        if (sin1->sin_port != sin2->sin_port) {
     1395                                continue;
     1396                        }
     1397                        if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
     1398                                continue;
     1399                        }
     1400
     1401                        /* found */
     1402                        return true;
     1403                        break;
     1404                }
     1405#if HAVE_IPV6
     1406                case AF_INET6: {
     1407                        struct sockaddr_in6 *sin1, *sin2;
     1408
     1409                        sin1 = (struct sockaddr_in6 *)s->myname;
     1410                        sin2 = (struct sockaddr_in6 *)sa;
     1411
     1412                        if (sin1->sin6_port != sin2->sin6_port) {
     1413                                continue;
     1414                        }
     1415                        if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
     1416                                                &sin2->sin6_addr))
     1417                        {
     1418                                continue;
     1419                        }
     1420
     1421                        /* found */
     1422                        return true;
     1423                        break;
     1424                }
     1425#endif
     1426                default:
     1427                        continue;
     1428                        break;
     1429
     1430                }
     1431        }
     1432
     1433        return false;
     1434}
     1435#endif
     1436
     1437static void swrap_remove_stale(int fd)
     1438{
     1439        struct socket_info *si = find_socket_info(fd);
     1440        struct socket_info_fd *fi;
     1441
     1442        if (si != NULL) {
     1443                for (fi = si->fds; fi; fi = fi->next) {
     1444                        if (fi->fd == fd) {
     1445                                SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
     1446                                SWRAP_DLIST_REMOVE(si->fds, fi);
     1447                                free(fi);
     1448                                break;
     1449                        }
     1450                }
     1451
     1452                if (si->fds == NULL) {
     1453                        SWRAP_DLIST_REMOVE(sockets, si);
     1454                        if (si->un_addr.sun_path[0] != '\0') {
     1455                                unlink(si->un_addr.sun_path);
     1456                        }
     1457                        free(si);
     1458                }
     1459        }
     1460}
     1461
     1462static int sockaddr_convert_to_un(struct socket_info *si,
     1463                                  const struct sockaddr *in_addr,
     1464                                  socklen_t in_len,
     1465                                  struct sockaddr_un *out_addr,
     1466                                  int alloc_sock,
     1467                                  int *bcast)
    5881468{
    5891469        struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
    590         if (!out_addr)
     1470
     1471        (void) in_len; /* unused */
     1472
     1473        if (out_addr == NULL) {
    5911474                return 0;
     1475        }
    5921476
    5931477        out->sa_family = AF_UNIX;
     
    5971481
    5981482        switch (in_addr->sa_family) {
     1483        case AF_UNSPEC: {
     1484                const struct sockaddr_in *sin;
     1485                if (si->family != AF_INET) {
     1486                        break;
     1487                }
     1488                if (in_len < sizeof(struct sockaddr_in)) {
     1489                        break;
     1490                }
     1491                sin = (const struct sockaddr_in *)(const void *)in_addr;
     1492                if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
     1493                        break;
     1494                }
     1495
     1496                /*
     1497                 * Note: in the special case of AF_UNSPEC and INADDR_ANY,
     1498                 * AF_UNSPEC is mapped to AF_INET and must be treated here.
     1499                 */
     1500
     1501                /* FALL THROUGH */
     1502        }
    5991503        case AF_INET:
    6001504#ifdef HAVE_IPV6
     
    6061510                        break;
    6071511                default:
     1512                        SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
    6081513                        errno = ESOCKTNOSUPPORT;
    6091514                        return -1;
     
    6191524
    6201525        errno = EAFNOSUPPORT;
     1526        SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
    6211527        return -1;
    6221528}
    6231529
    624 static int sockaddr_convert_from_un(const struct socket_info *si, 
    625                                     const struct sockaddr_un *in_addr, 
     1530static int sockaddr_convert_from_un(const struct socket_info *si,
     1531                                    const struct sockaddr_un *in_addr,
    6261532                                    socklen_t un_addrlen,
    6271533                                    int family,
     
    6311537        int ret;
    6321538
    633         if (out_addr == NULL || out_addrlen == NULL) 
     1539        if (out_addr == NULL || out_addrlen == NULL)
    6341540                return 0;
    6351541
     
    6491555                        break;
    6501556                default:
     1557                        SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown socket type!\n");
    6511558                        errno = ESOCKTNOSUPPORT;
    6521559                        return -1;
     
    6611568        }
    6621569
     1570        SWRAP_LOG(SWRAP_LOG_ERROR, "Unknown address family\n");
    6631571        errno = EAFNOSUPPORT;
    6641572        return -1;
     
    7771685         SWRAP_PACKET_PAYLOAD_SIZE)
    7781686
    779 static const char *socket_wrapper_pcap_file(void)
     1687static const char *swrap_pcap_init_file(void)
    7801688{
    7811689        static int initialized = 0;
     
    7941702         * TODO: don't use the structs use plain buffer offsets
    7951703         *       and PUSH_U8(), PUSH_U16() and PUSH_U32()
    796          * 
     1704         *
    7971705         * for now make sure we disable PCAP support
    7981706         * if the struct has alignment!
     
    8391747}
    8401748
    841 static uint8_t *swrap_packet_init(struct timeval *tval,
    842                                   const struct sockaddr *src,
    843                                   const struct sockaddr *dest,
    844                                   int socket_type,
    845                                   const uint8_t *payload,
    846                                   size_t payload_len,
    847                                   unsigned long tcp_seqno,
    848                                   unsigned long tcp_ack,
    849                                   unsigned char tcp_ctl,
    850                                   int unreachable,
    851                                   size_t *_packet_len)
     1749static uint8_t *swrap_pcap_packet_init(struct timeval *tval,
     1750                                       const struct sockaddr *src,
     1751                                       const struct sockaddr *dest,
     1752                                       int socket_type,
     1753                                       const uint8_t *payload,
     1754                                       size_t payload_len,
     1755                                       unsigned long tcp_seqno,
     1756                                       unsigned long tcp_ack,
     1757                                       unsigned char tcp_ctl,
     1758                                       int unreachable,
     1759                                       size_t *_packet_len)
    8521760{
    8531761        uint8_t *base;
     
    8761784        switch (src->sa_family) {
    8771785        case AF_INET:
    878                 src_in = (const struct sockaddr_in *)src;
    879                 dest_in = (const struct sockaddr_in *)dest;
     1786                src_in = (const struct sockaddr_in *)(const void *)src;
     1787                dest_in = (const struct sockaddr_in *)(const void *)dest;
    8801788                src_port = src_in->sin_port;
    8811789                dest_port = dest_in->sin_port;
     
    8841792#ifdef HAVE_IPV6
    8851793        case AF_INET6:
    886                 src_in6 = (const struct sockaddr_in6 *)src;
    887                 dest_in6 = (const struct sockaddr_in6 *)dest;
     1794                src_in6 = (const struct sockaddr_in6 *)(const void *)src;
     1795                dest_in6 = (const struct sockaddr_in6 *)(const void *)dest;
    8881796                src_port = src_in6->sin6_port;
    8891797                dest_port = dest_in6->sin6_port;
     
    9401848
    9411849        base = (uint8_t *)malloc(alloc_len);
    942         if (!base) return NULL;
     1850        if (base == NULL) {
     1851                return NULL;
     1852        }
     1853        memset(base, 0x0, alloc_len);
    9431854
    9441855        buf = base;
    9451856
    946         frame = (struct swrap_packet_frame *)buf;
     1857        frame = (struct swrap_packet_frame *)(void *)buf;
    9471858        frame->seconds          = tval->tv_sec;
    9481859        frame->micro_seconds    = tval->tv_usec;
     
    9511862        buf += SWRAP_PACKET_FRAME_SIZE;
    9521863
    953         ip = (union swrap_packet_ip *)buf;
     1864        ip = (union swrap_packet_ip *)(void *)buf;
    9541865        switch (src->sa_family) {
    9551866        case AF_INET:
     
    9581869                ip->v4.packet_length    = htons(wire_len - icmp_truncate_len);
    9591870                ip->v4.identification   = htons(0xFFFF);
    960                 ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
     1871                ip->v4.flags            = 0x40; /* BIT 1 set - means don't fragment */
    9611872                ip->v4.fragment         = htons(0x0000);
    9621873                ip->v4.ttl              = 0xFF;
     
    9821893
    9831894        if (unreachable) {
    984                 pay = (union swrap_packet_payload *)buf;
     1895                pay = (union swrap_packet_payload *)(void *)buf;
    9851896                switch (src->sa_family) {
    9861897                case AF_INET:
     
    9921903
    9931904                        /* set the ip header in the ICMP payload */
    994                         ip = (union swrap_packet_ip *)buf;
     1905                        ip = (union swrap_packet_ip *)(void *)buf;
    9951906                        ip->v4.ver_hdrlen       = 0x45; /* version 4 and 5 * 32 bit words */
    9961907                        ip->v4.tos              = 0x00;
    9971908                        ip->v4.packet_length    = htons(wire_len - icmp_hdr_len);
    9981909                        ip->v4.identification   = htons(0xFFFF);
    999                         ip->v4.flags            = 0x40; /* BIT 1 set - means don't fraqment */
     1910                        ip->v4.flags            = 0x40; /* BIT 1 set - means don't fragment */
    10001911                        ip->v4.fragment         = htons(0x0000);
    10011912                        ip->v4.ttl              = 0xFF;
     
    10181929
    10191930                        /* set the ip header in the ICMP payload */
    1020                         ip = (union swrap_packet_ip *)buf;
     1931                        ip = (union swrap_packet_ip *)(void *)buf;
    10211932                        ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
    10221933                        ip->v6.flow_label_high  = 0x00;
     
    10351946        }
    10361947
    1037         pay = (union swrap_packet_payload *)buf;
     1948        pay = (union swrap_packet_payload *)(void *)buf;
    10381949
    10391950        switch (socket_type) {
     
    10701981}
    10711982
    1072 static int swrap_get_pcap_fd(const char *fname)
     1983static int swrap_pcap_get_fd(const char *fname)
    10731984{
    10741985        static int fd = -1;
     
    10761987        if (fd != -1) return fd;
    10771988
    1078         fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
     1989        fd = libc_open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644);
    10791990        if (fd != -1) {
    10801991                struct swrap_file_hdr file_hdr;
     
    10942005        }
    10952006
    1096         fd = open(fname, O_WRONLY|O_APPEND, 0644);
     2007        fd = libc_open(fname, O_WRONLY|O_APPEND, 0644);
    10972008
    10982009        return fd;
    10992010}
    11002011
    1101 static uint8_t *swrap_marshall_packet(struct socket_info *si,
    1102                                       const struct sockaddr *addr,
    1103                                       enum swrap_packet_type type,
    1104                                       const void *buf, size_t len,
    1105                                       size_t *packet_len)
     2012static uint8_t *swrap_pcap_marshall_packet(struct socket_info *si,
     2013                                           const struct sockaddr *addr,
     2014                                           enum swrap_packet_type type,
     2015                                           const void *buf, size_t len,
     2016                                           size_t *packet_len)
    11062017{
    11072018        const struct sockaddr *src_addr;
     
    11292040                if (si->type != SOCK_STREAM) return NULL;
    11302041
    1131                 src_addr = si->myname;
     2042                src_addr  = &si->myname.sa.s;
    11322043                dest_addr = addr;
    11332044
     
    11432054                if (si->type != SOCK_STREAM) return NULL;
    11442055
    1145                 dest_addr = si->myname;
     2056                dest_addr = &si->myname.sa.s;
    11462057                src_addr = addr;
    11472058
     
    11572068                if (si->type != SOCK_STREAM) return NULL;
    11582069
    1159                 dest_addr = si->myname;
    1160                 src_addr = addr;
     2070                dest_addr = &si->myname.sa.s;
     2071                src_addr  = addr;
    11612072
    11622073                /* Unreachable: resend the data of SWRAP_CONNECT_SEND */
     
    11712082                if (si->type != SOCK_STREAM) return NULL;
    11722083
    1173                 src_addr = si->myname;
     2084                src_addr  = &si->myname.sa.s;
    11742085                dest_addr = addr;
    11752086
     
    11832094                if (si->type != SOCK_STREAM) return NULL;
    11842095
    1185                 dest_addr = si->myname;
     2096                dest_addr = &si->myname.sa.s;
    11862097                src_addr = addr;
    11872098
     
    11972108                if (si->type != SOCK_STREAM) return NULL;
    11982109
    1199                 src_addr = si->myname;
     2110                src_addr = &si->myname.sa.s;
    12002111                dest_addr = addr;
    12012112
     
    12112122                if (si->type != SOCK_STREAM) return NULL;
    12122123
    1213                 dest_addr = si->myname;
     2124                dest_addr = &si->myname.sa.s;
    12142125                src_addr = addr;
    12152126
     
    12212132
    12222133        case SWRAP_SEND:
    1223                 src_addr = si->myname;
    1224                 dest_addr = si->peername;
     2134                src_addr  = &si->myname.sa.s;
     2135                dest_addr = &si->peername.sa.s;
    12252136
    12262137                tcp_seqno = si->io.pck_snd;
     
    12332144
    12342145        case SWRAP_SEND_RST:
    1235                 dest_addr = si->myname;
    1236                 src_addr = si->peername;
     2146                dest_addr = &si->myname.sa.s;
     2147                src_addr  = &si->peername.sa.s;
    12372148
    12382149                if (si->type == SOCK_DGRAM) {
    1239                         return swrap_marshall_packet(si, si->peername,
    1240                                           SWRAP_SENDTO_UNREACH,
    1241                                           buf, len, packet_len);
     2150                        return swrap_pcap_marshall_packet(si,
     2151                                                          &si->peername.sa.s,
     2152                                                          SWRAP_SENDTO_UNREACH,
     2153                                                          buf,
     2154                                                          len,
     2155                                                          packet_len);
    12422156                }
    12432157
     
    12492163
    12502164        case SWRAP_PENDING_RST:
    1251                 dest_addr = si->myname;
    1252                 src_addr = si->peername;
     2165                dest_addr = &si->myname.sa.s;
     2166                src_addr  = &si->peername.sa.s;
    12532167
    12542168                if (si->type == SOCK_DGRAM) {
     
    12632177
    12642178        case SWRAP_RECV:
    1265                 dest_addr = si->myname;
    1266                 src_addr = si->peername;
     2179                dest_addr = &si->myname.sa.s;
     2180                src_addr  = &si->peername.sa.s;
    12672181
    12682182                tcp_seqno = si->io.pck_rcv;
     
    12752189
    12762190        case SWRAP_RECV_RST:
    1277                 dest_addr = si->myname;
    1278                 src_addr = si->peername;
     2191                dest_addr = &si->myname.sa.s;
     2192                src_addr  = &si->peername.sa.s;
    12792193
    12802194                if (si->type == SOCK_DGRAM) {
     
    12892203
    12902204        case SWRAP_SENDTO:
    1291                 src_addr = si->myname;
     2205                src_addr = &si->myname.sa.s;
    12922206                dest_addr = addr;
    12932207
     
    12972211
    12982212        case SWRAP_SENDTO_UNREACH:
    1299                 dest_addr = si->myname;
     2213                dest_addr = &si->myname.sa.s;
    13002214                src_addr = addr;
    13012215
     
    13052219
    13062220        case SWRAP_RECVFROM:
    1307                 dest_addr = si->myname;
     2221                dest_addr = &si->myname.sa.s;
    13082222                src_addr = addr;
    13092223
     
    13152229                if (si->type != SOCK_STREAM) return NULL;
    13162230
    1317                 src_addr = si->myname;
    1318                 dest_addr = si->peername;
     2231                src_addr  = &si->myname.sa.s;
     2232                dest_addr = &si->peername.sa.s;
    13192233
    13202234                tcp_seqno = si->io.pck_snd;
     
    13292243                if (si->type != SOCK_STREAM) return NULL;
    13302244
    1331                 dest_addr = si->myname;
    1332                 src_addr = si->peername;
     2245                dest_addr = &si->myname.sa.s;
     2246                src_addr  = &si->peername.sa.s;
    13332247
    13342248                tcp_seqno = si->io.pck_rcv;
     
    13432257                if (si->type != SOCK_STREAM) return NULL;
    13442258
    1345                 src_addr = si->myname;
    1346                 dest_addr = si->peername;
     2259                src_addr  = &si->myname.sa.s;
     2260                dest_addr = &si->peername.sa.s;
    13472261
    13482262                tcp_seqno = si->io.pck_snd;
     
    13572271        swrapGetTimeOfDay(&tv);
    13582272
    1359         return swrap_packet_init(&tv, src_addr, dest_addr, si->type,
    1360                                  (const uint8_t *)buf, len,
    1361                                  tcp_seqno, tcp_ack, tcp_ctl, unreachable,
    1362                                  packet_len);
    1363 }
    1364 
    1365 static void swrap_dump_packet(struct socket_info *si,
    1366                               const struct sockaddr *addr,
    1367                               enum swrap_packet_type type,
    1368                               const void *buf, size_t len)
     2273        return swrap_pcap_packet_init(&tv,
     2274                                      src_addr,
     2275                                      dest_addr,
     2276                                      si->type,
     2277                                      (const uint8_t *)buf,
     2278                                      len,
     2279                                      tcp_seqno,
     2280                                      tcp_ack,
     2281                                      tcp_ctl,
     2282                                      unreachable,
     2283                                      packet_len);
     2284}
     2285
     2286static void swrap_pcap_dump_packet(struct socket_info *si,
     2287                                   const struct sockaddr *addr,
     2288                                   enum swrap_packet_type type,
     2289                                   const void *buf, size_t len)
    13692290{
    13702291        const char *file_name;
     
    13732294        int fd;
    13742295
    1375         file_name = socket_wrapper_pcap_file();
     2296        file_name = swrap_pcap_init_file();
    13762297        if (!file_name) {
    13772298                return;
    13782299        }
    13792300
    1380         packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len);
    1381         if (!packet) {
     2301        packet = swrap_pcap_marshall_packet(si,
     2302                                            addr,
     2303                                            type,
     2304                                            buf,
     2305                                            len,
     2306                                            &packet_len);
     2307        if (packet == NULL) {
    13822308                return;
    13832309        }
    13842310
    1385         fd = swrap_get_pcap_fd(file_name);
     2311        fd = swrap_pcap_get_fd(file_name);
    13862312        if (fd != -1) {
    1387                 if (write(fd, packet, packet_len) != packet_len) {
     2313                if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
    13882314                        free(packet);
    13892315                        return;
     
    13942320}
    13952321
    1396 _PUBLIC_ int swrap_socket(int family, int type, int protocol)
     2322/****************************************************************************
     2323 *   SIGNALFD
     2324 ***************************************************************************/
     2325
     2326#ifdef HAVE_SIGNALFD
     2327static int swrap_signalfd(int fd, const sigset_t *mask, int flags)
     2328{
     2329        int rc;
     2330
     2331        rc = libc_signalfd(fd, mask, flags);
     2332        if (rc != -1) {
     2333                swrap_remove_stale(fd);
     2334        }
     2335
     2336        return rc;
     2337}
     2338
     2339int signalfd(int fd, const sigset_t *mask, int flags)
     2340{
     2341        return swrap_signalfd(fd, mask, flags);
     2342}
     2343#endif
     2344
     2345/****************************************************************************
     2346 *   SOCKET
     2347 ***************************************************************************/
     2348
     2349static int swrap_socket(int family, int type, int protocol)
    13972350{
    13982351        struct socket_info *si;
     2352        struct socket_info_fd *fi;
    13992353        int fd;
    14002354        int real_type = type;
     2355
     2356        /*
     2357         * Remove possible addition flags passed to socket() so
     2358         * do not fail checking the type.
     2359         * See https://lwn.net/Articles/281965/
     2360         */
    14012361#ifdef SOCK_CLOEXEC
    14022362        real_type &= ~SOCK_CLOEXEC;
     
    14062366#endif
    14072367
    1408         if (!socket_wrapper_dir()) {
    1409                 return real_socket(family, type, protocol);
     2368        if (!socket_wrapper_enabled()) {
     2369                return libc_socket(family, type, protocol);
    14102370        }
    14112371
     
    14172377                break;
    14182378        case AF_UNIX:
    1419                 return real_socket(family, type, protocol);
     2379                return libc_socket(family, type, protocol);
    14202380        default:
    14212381                errno = EAFNOSUPPORT;
     
    14512411        }
    14522412
    1453         /* We must call real_socket with type, from the caller, not the version we removed
    1454            SOCK_CLOEXEC and SOCK_NONBLOCK from */
    1455         fd = real_socket(AF_UNIX, type, 0);
    1456 
    1457         if (fd == -1) return -1;
    1458 
    1459         si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
     2413        /*
     2414         * We must call libc_socket with type, from the caller, not the version
     2415         * we removed SOCK_CLOEXEC and SOCK_NONBLOCK from
     2416         */
     2417        fd = libc_socket(AF_UNIX, type, 0);
     2418
     2419        if (fd == -1) {
     2420                return -1;
     2421        }
     2422
     2423        /* Check if we have a stale fd and remove it */
     2424        si = find_socket_info(fd);
     2425        if (si != NULL) {
     2426                swrap_remove_stale(fd);
     2427        }
     2428
     2429        si = (struct socket_info *)malloc(sizeof(struct socket_info));
     2430        memset(si, 0, sizeof(struct socket_info));
     2431        if (si == NULL) {
     2432                errno = ENOMEM;
     2433                return -1;
     2434        }
    14602435
    14612436        si->family = family;
     
    14652440        si->type = real_type;
    14662441        si->protocol = protocol;
    1467         si->fd = fd;
    1468 
     2442
     2443        /*
     2444         * Setup myname so getsockname() can succeed to find out the socket
     2445         * type.
     2446         */
     2447        switch(si->family) {
     2448        case AF_INET: {
     2449                struct sockaddr_in sin = {
     2450                        .sin_family = AF_INET,
     2451                };
     2452
     2453                si->myname.sa_socklen = sizeof(struct sockaddr_in);
     2454                memcpy(&si->myname.sa.in, &sin, si->myname.sa_socklen);
     2455                break;
     2456        }
     2457        case AF_INET6: {
     2458                struct sockaddr_in6 sin6 = {
     2459                        .sin6_family = AF_INET6,
     2460                };
     2461
     2462                si->myname.sa_socklen = sizeof(struct sockaddr_in6);
     2463                memcpy(&si->myname.sa.in6, &sin6, si->myname.sa_socklen);
     2464                break;
     2465        }
     2466        default:
     2467                free(si);
     2468                errno = EINVAL;
     2469                return -1;
     2470        }
     2471
     2472        fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
     2473        if (fi == NULL) {
     2474                free(si);
     2475                errno = ENOMEM;
     2476                return -1;
     2477        }
     2478
     2479        fi->fd = fd;
     2480
     2481        SWRAP_DLIST_ADD(si->fds, fi);
    14692482        SWRAP_DLIST_ADD(sockets, si);
    14702483
    1471         return si->fd;
    1472 }
    1473 
    1474 _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
     2484        SWRAP_LOG(SWRAP_LOG_TRACE,
     2485                  "Created %s socket for protocol %s",
     2486                  si->family == AF_INET ? "IPv4" : "IPv6",
     2487                  si->type == SOCK_DGRAM ? "UDP" : "TCP");
     2488
     2489        return fd;
     2490}
     2491
     2492int socket(int family, int type, int protocol)
     2493{
     2494        return swrap_socket(family, type, protocol);
     2495}
     2496
     2497/****************************************************************************
     2498 *   SOCKETPAIR
     2499 ***************************************************************************/
     2500
     2501static int swrap_socketpair(int family, int type, int protocol, int sv[2])
     2502{
     2503        int rc;
     2504
     2505        rc = libc_socketpair(family, type, protocol, sv);
     2506        if (rc != -1) {
     2507                swrap_remove_stale(sv[0]);
     2508                swrap_remove_stale(sv[1]);
     2509        }
     2510
     2511        return rc;
     2512}
     2513
     2514int socketpair(int family, int type, int protocol, int sv[2])
     2515{
     2516        return swrap_socketpair(family, type, protocol, sv);
     2517}
     2518
     2519/****************************************************************************
     2520 *   SOCKETPAIR
     2521 ***************************************************************************/
     2522
     2523#ifdef HAVE_TIMERFD_CREATE
     2524static int swrap_timerfd_create(int clockid, int flags)
     2525{
     2526        int fd;
     2527
     2528        fd = libc_timerfd_create(clockid, flags);
     2529        if (fd != -1) {
     2530                swrap_remove_stale(fd);
     2531        }
     2532
     2533        return fd;
     2534}
     2535
     2536int timerfd_create(int clockid, int flags)
     2537{
     2538        return swrap_timerfd_create(clockid, flags);
     2539}
     2540#endif
     2541
     2542/****************************************************************************
     2543 *   PIPE
     2544 ***************************************************************************/
     2545
     2546static int swrap_pipe(int pipefd[2])
     2547{
     2548        int rc;
     2549
     2550        rc = libc_pipe(pipefd);
     2551        if (rc != -1) {
     2552                swrap_remove_stale(pipefd[0]);
     2553                swrap_remove_stale(pipefd[1]);
     2554        }
     2555
     2556        return rc;
     2557}
     2558
     2559int pipe(int pipefd[2])
     2560{
     2561        return swrap_pipe(pipefd);
     2562}
     2563
     2564/****************************************************************************
     2565 *   ACCEPT
     2566 ***************************************************************************/
     2567
     2568static int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
    14752569{
    14762570        struct socket_info *parent_si, *child_si;
     2571        struct socket_info_fd *child_fi;
    14772572        int fd;
    1478         struct sockaddr_un un_addr;
    1479         socklen_t un_addrlen = sizeof(un_addr);
    1480         struct sockaddr_un un_my_addr;
    1481         socklen_t un_my_addrlen = sizeof(un_my_addr);
    1482         struct sockaddr *my_addr;
    1483         socklen_t my_addrlen, len;
     2573        struct swrap_address un_addr = {
     2574                .sa_socklen = sizeof(struct sockaddr_un),
     2575        };
     2576        struct swrap_address un_my_addr = {
     2577                .sa_socklen = sizeof(struct sockaddr_un),
     2578        };
     2579        struct swrap_address in_addr = {
     2580                .sa_socklen = sizeof(struct sockaddr_storage),
     2581        };
     2582        struct swrap_address in_my_addr = {
     2583                .sa_socklen = sizeof(struct sockaddr_storage),
     2584        };
    14842585        int ret;
    14852586
    14862587        parent_si = find_socket_info(s);
    14872588        if (!parent_si) {
    1488                 return real_accept(s, addr, addrlen);
    1489         }
    1490 
    1491         /* 
     2589                return libc_accept(s, addr, addrlen);
     2590        }
     2591
     2592        /*
    14922593         * assume out sockaddr have the same size as the in parent
    14932594         * socket family
    14942595         */
    1495         my_addrlen = socket_length(parent_si->family);
    1496         if (my_addrlen <= 0) {
     2596        in_addr.sa_socklen = socket_length(parent_si->family);
     2597        if (in_addr.sa_socklen <= 0) {
    14972598                errno = EINVAL;
    14982599                return -1;
    14992600        }
    15002601
    1501         my_addr = (struct sockaddr *)malloc(my_addrlen);
    1502         if (my_addr == NULL) {
    1503                 return -1;
    1504         }
    1505 
    1506         memset(&un_addr, 0, sizeof(un_addr));
    1507         memset(&un_my_addr, 0, sizeof(un_my_addr));
    1508 
    1509         ret = real_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
     2602        ret = libc_accept(s, &un_addr.sa.s, &un_addr.sa_socklen);
    15102603        if (ret == -1) {
    1511                 free(my_addr);
     2604                if (errno == ENOTSOCK) {
     2605                        /* Remove stale fds */
     2606                        swrap_remove_stale(s);
     2607                }
    15122608                return ret;
    15132609        }
     
    15152611        fd = ret;
    15162612
    1517         len = my_addrlen;
    1518         ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
    1519                                        parent_si->family, my_addr, &len);
     2613        ret = sockaddr_convert_from_un(parent_si,
     2614                                       &un_addr.sa.un,
     2615                                       un_addr.sa_socklen,
     2616                                       parent_si->family,
     2617                                       &in_addr.sa.s,
     2618                                       &in_addr.sa_socklen);
    15202619        if (ret == -1) {
    1521                 free(my_addr);
    15222620                close(fd);
    15232621                return ret;
     
    15252623
    15262624        child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
    1527         memset(child_si, 0, sizeof(*child_si));
    1528 
    1529         child_si->fd = fd;
     2625        memset(child_si, 0, sizeof(struct socket_info));
     2626
     2627        child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
     2628        if (child_fi == NULL) {
     2629                free(child_si);
     2630                close(fd);
     2631                errno = ENOMEM;
     2632                return -1;
     2633        }
     2634
     2635        child_fi->fd = fd;
     2636
     2637        SWRAP_DLIST_ADD(child_si->fds, child_fi);
     2638
    15302639        child_si->family = parent_si->family;
    15312640        child_si->type = parent_si->type;
     
    15352644        child_si->connected = 1;
    15362645
    1537         child_si->peername_len = len;
    1538         child_si->peername = sockaddr_dup(my_addr, len);
     2646        child_si->peername = (struct swrap_address) {
     2647                .sa_socklen = in_addr.sa_socklen,
     2648        };
     2649        memcpy(&child_si->peername.sa.ss, &in_addr.sa.ss, in_addr.sa_socklen);
    15392650
    15402651        if (addr != NULL && addrlen != NULL) {
    1541                 size_t copy_len = MIN(*addrlen, len);
     2652                size_t copy_len = MIN(*addrlen, in_addr.sa_socklen);
    15422653                if (copy_len > 0) {
    1543                         memcpy(addr, my_addr, copy_len);
    1544                 }
    1545                 *addrlen = len;
    1546         }
    1547 
    1548         ret = real_getsockname(fd, (struct sockaddr *)(void *)&un_my_addr,
    1549                                &un_my_addrlen);
     2654                        memcpy(addr, &in_addr.sa.ss, copy_len);
     2655                }
     2656                *addrlen = in_addr.sa_socklen;
     2657        }
     2658
     2659        ret = libc_getsockname(fd,
     2660                               &un_my_addr.sa.s,
     2661                               &un_my_addr.sa_socklen);
    15502662        if (ret == -1) {
     2663                free(child_fi);
    15512664                free(child_si);
    15522665                close(fd);
     
    15542667        }
    15552668
    1556         len = my_addrlen;
    1557         ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
    1558                                        child_si->family, my_addr, &len);
     2669        ret = sockaddr_convert_from_un(child_si,
     2670                                       &un_my_addr.sa.un,
     2671                                       un_my_addr.sa_socklen,
     2672                                       child_si->family,
     2673                                       &in_my_addr.sa.s,
     2674                                       &in_my_addr.sa_socklen);
    15592675        if (ret == -1) {
     2676                free(child_fi);
    15602677                free(child_si);
    1561                 free(my_addr);
    15622678                close(fd);
    15632679                return ret;
    15642680        }
    15652681
    1566         child_si->myname_len = len;
    1567         child_si->myname = sockaddr_dup(my_addr, len);
    1568         free(my_addr);
     2682        SWRAP_LOG(SWRAP_LOG_TRACE,
     2683                  "accept() path=%s, fd=%d",
     2684                  un_my_addr.sa.un.sun_path, s);
     2685
     2686        child_si->myname = (struct swrap_address) {
     2687                .sa_socklen = in_my_addr.sa_socklen,
     2688        };
     2689        memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
    15692690
    15702691        SWRAP_DLIST_ADD(sockets, child_si);
    15712692
    1572         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
    1573         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
    1574         swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
     2693        if (addr != NULL) {
     2694                swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
     2695                swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
     2696                swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);
     2697        }
    15752698
    15762699        return fd;
     2700}
     2701
     2702#ifdef HAVE_ACCEPT_PSOCKLEN_T
     2703int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)
     2704#else
     2705int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
     2706#endif
     2707{
     2708        return swrap_accept(s, addr, (socklen_t *)addrlen);
    15772709}
    15782710
     
    15822714/* using sendto() or connect() on an unbound socket would give the
    15832715   recipient no way to reply, as unlike UDP and TCP, a unix domain
    1584    socket can't auto-assign emphemeral port numbers, so we need to
     2716   socket can't auto-assign ephemeral port numbers, so we need to
    15852717   assign it here.
    15862718   Note: this might change the family from ipv6 to ipv4
    15872719*/
    1588 static int swrap_auto_bind(struct socket_info *si, int family)
    1589 {
    1590         struct sockaddr_un un_addr;
     2720static int swrap_auto_bind(int fd, struct socket_info *si, int family)
     2721{
     2722        struct swrap_address un_addr = {
     2723                .sa_socklen = sizeof(struct sockaddr_un),
     2724        };
    15912725        int i;
    15922726        char type;
     
    16022736        }
    16032737
    1604         un_addr.sun_family = AF_UNIX;
     2738        un_addr.sa.un.sun_family = AF_UNIX;
    16052739
    16062740        switch (family) {
     
    16132747                        break;
    16142748                case SOCK_DGRAM:
    1615                         type = SOCKET_TYPE_CHAR_UDP;
     2749                        type = SOCKET_TYPE_CHAR_UDP;
    16162750                        break;
    16172751                default:
     
    16222756                memset(&in, 0, sizeof(in));
    16232757                in.sin_family = AF_INET;
    1624                 in.sin_addr.s_addr = htonl(127<<24 | 
     2758                in.sin_addr.s_addr = htonl(127<<24 |
    16252759                                           socket_wrapper_default_iface());
    16262760
    1627                 si->myname_len = sizeof(in);
    1628                 si->myname = sockaddr_dup(&in, si->myname_len);
     2761                si->myname = (struct swrap_address) {
     2762                        .sa_socklen = sizeof(in),
     2763                };
     2764                memcpy(&si->myname.sa.in, &in, si->myname.sa_socklen);
    16292765                break;
    16302766        }
     
    16432779                        break;
    16442780                case SOCK_DGRAM:
    1645                         type = SOCKET_TYPE_CHAR_UDP_V6;
     2781                        type = SOCKET_TYPE_CHAR_UDP_V6;
    16462782                        break;
    16472783                default:
     
    16542790                in6.sin6_addr = *swrap_ipv6();
    16552791                in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
    1656                 si->myname_len = sizeof(in6);
    1657                 si->myname = sockaddr_dup(&in6, si->myname_len);
     2792
     2793                si->myname = (struct swrap_address) {
     2794                        .sa_socklen = sizeof(in6),
     2795                };
     2796                memcpy(&si->myname.sa.in6, &in6, si->myname.sa_socklen);
    16582797                break;
    16592798        }
     
    16682807        }
    16692808
    1670         for (i=0;i<1000;i++) {
     2809        for (i = 0; i < SOCKET_MAX_SOCKETS; i++) {
    16712810                port = autobind_start + i;
    1672                 snprintf(un_addr.sun_path, sizeof(un_addr.sun_path),
     2811                snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path),
    16732812                         "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
    16742813                         type, socket_wrapper_default_iface(), port);
    1675                 if (stat(un_addr.sun_path, &st) == 0) continue;
    1676 
    1677                 ret = real_bind(si->fd, (struct sockaddr *)(void *)&un_addr,
    1678                                 sizeof(un_addr));
     2814                if (stat(un_addr.sa.un.sun_path, &st) == 0) continue;
     2815
     2816                ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen);
    16792817                if (ret == -1) return ret;
    16802818
    1681                 si->tmp_path = strdup(un_addr.sun_path);
     2819                si->un_addr = un_addr.sa.un;
     2820
    16822821                si->bound = 1;
    16832822                autobind_start = port + 1;
    16842823                break;
    16852824        }
    1686         if (i == 1000) {
     2825        if (i == SOCKET_MAX_SOCKETS) {
     2826                SWRAP_LOG(SWRAP_LOG_ERROR, "Too many open unix sockets (%u) for "
     2827                                           "interface "SOCKET_FORMAT,
     2828                                           SOCKET_MAX_SOCKETS,
     2829                                           type,
     2830                                           socket_wrapper_default_iface(),
     2831                                           0);
    16872832                errno = ENFILE;
    16882833                return -1;
     
    16902835
    16912836        si->family = family;
    1692         set_port(si->family, port, si->myname);
     2837        set_port(si->family, port, &si->myname);
    16932838
    16942839        return 0;
    16952840}
    16962841
    1697 
    1698 _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
     2842/****************************************************************************
     2843 *   CONNECT
     2844 ***************************************************************************/
     2845
     2846static int swrap_connect(int s, const struct sockaddr *serv_addr,
     2847                         socklen_t addrlen)
    16992848{
    17002849        int ret;
    1701         struct sockaddr_un un_addr;
     2850        struct swrap_address un_addr = {
     2851                .sa_socklen = sizeof(struct sockaddr_un),
     2852        };
    17022853        struct socket_info *si = find_socket_info(s);
    17032854        int bcast = 0;
    17042855
    17052856        if (!si) {
    1706                 return real_connect(s, serv_addr, addrlen);
     2857                return libc_connect(s, serv_addr, addrlen);
    17072858        }
    17082859
    17092860        if (si->bound == 0) {
    1710                 ret = swrap_auto_bind(si, serv_addr->sa_family);
     2861                ret = swrap_auto_bind(s, si, serv_addr->sa_family);
    17112862                if (ret == -1) return -1;
    17122863        }
     
    17182869
    17192870        ret = sockaddr_convert_to_un(si, serv_addr,
    1720                                      addrlen, &un_addr, 0, &bcast);
     2871                                     addrlen, &un_addr.sa.un, 0, &bcast);
    17212872        if (ret == -1) return -1;
    17222873
     
    17302881                ret = 0;
    17312882        } else {
    1732                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
    1733 
    1734                 ret = real_connect(s, (struct sockaddr *)(void *)&un_addr,
    1735                                    sizeof(struct sockaddr_un));
    1736         }
     2883                swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
     2884
     2885                ret = libc_connect(s,
     2886                                   &un_addr.sa.s,
     2887                                   un_addr.sa_socklen);
     2888        }
     2889
     2890        SWRAP_LOG(SWRAP_LOG_TRACE,
     2891                  "connect() path=%s, fd=%d",
     2892                  un_addr.sa.un.sun_path, s);
     2893
    17372894
    17382895        /* to give better errors */
     
    17422899
    17432900        if (ret == 0) {
    1744                 si->peername_len = addrlen;
    1745                 si->peername = sockaddr_dup(serv_addr, addrlen);
     2901                si->peername = (struct swrap_address) {
     2902                        .sa_socklen = addrlen,
     2903                };
     2904
     2905                memcpy(&si->peername.sa.ss, serv_addr, addrlen);
    17462906                si->connected = 1;
    17472907
    1748                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
    1749                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
     2908                /*
     2909                 * When we connect() on a socket than we have to bind the
     2910                 * outgoing connection on the interface we use for the
     2911                 * transport. We already bound it on the right interface
     2912                 * but here we have to update the name so getsockname()
     2913                 * returns correct information.
     2914                 */
     2915                if (si->bindname.sa_socklen > 0) {
     2916                        si->myname = (struct swrap_address) {
     2917                                .sa_socklen = si->bindname.sa_socklen,
     2918                        };
     2919
     2920                        memcpy(&si->myname.sa.ss,
     2921                               &si->bindname.sa.ss,
     2922                               si->bindname.sa_socklen);
     2923
     2924                        /* Cleanup bindname */
     2925                        si->bindname = (struct swrap_address) {
     2926                                .sa_socklen = 0,
     2927                        };
     2928                }
     2929
     2930                swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
     2931                swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
    17502932        } else {
    1751                 swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
     2933                swrap_pcap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0);
    17522934        }
    17532935
     
    17552937}
    17562938
    1757 _PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
     2939int connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen)
     2940{
     2941        return swrap_connect(s, serv_addr, addrlen);
     2942}
     2943
     2944/****************************************************************************
     2945 *   BIND
     2946 ***************************************************************************/
     2947
     2948static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
    17582949{
    17592950        int ret;
    1760         struct sockaddr_un un_addr;
     2951        struct swrap_address un_addr = {
     2952                .sa_socklen = sizeof(struct sockaddr_un),
     2953        };
    17612954        struct socket_info *si = find_socket_info(s);
     2955        int bind_error = 0;
     2956#if 0 /* FIXME */
     2957        bool in_use;
     2958#endif
    17622959
    17632960        if (!si) {
    1764                 return real_bind(s, myaddr, addrlen);
    1765         }
    1766 
    1767         si->myname_len = addrlen;
    1768         si->myname = sockaddr_dup(myaddr, addrlen);
    1769 
    1770         ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
     2961                return libc_bind(s, myaddr, addrlen);
     2962        }
     2963
     2964        switch (si->family) {
     2965        case AF_INET: {
     2966                const struct sockaddr_in *sin;
     2967                if (addrlen < sizeof(struct sockaddr_in)) {
     2968                        bind_error = EINVAL;
     2969                        break;
     2970                }
     2971
     2972                sin = (const struct sockaddr_in *)(const void *)myaddr;
     2973
     2974                if (sin->sin_family != AF_INET) {
     2975                        bind_error = EAFNOSUPPORT;
     2976                }
     2977
     2978                /* special case for AF_UNSPEC */
     2979                if (sin->sin_family == AF_UNSPEC &&
     2980                    (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
     2981                {
     2982                        bind_error = 0;
     2983                }
     2984
     2985                break;
     2986        }
     2987#ifdef HAVE_IPV6
     2988        case AF_INET6: {
     2989                const struct sockaddr_in6 *sin6;
     2990                if (addrlen < sizeof(struct sockaddr_in6)) {
     2991                        bind_error = EINVAL;
     2992                        break;
     2993                }
     2994
     2995                sin6 = (const struct sockaddr_in6 *)(const void *)myaddr;
     2996
     2997                if (sin6->sin6_family != AF_INET6) {
     2998                        bind_error = EAFNOSUPPORT;
     2999                }
     3000
     3001                break;
     3002        }
     3003#endif
     3004        default:
     3005                bind_error = EINVAL;
     3006                break;
     3007        }
     3008
     3009        if (bind_error != 0) {
     3010                errno = bind_error;
     3011                return -1;
     3012        }
     3013
     3014#if 0 /* FIXME */
     3015        in_use = check_addr_port_in_use(myaddr, addrlen);
     3016        if (in_use) {
     3017                errno = EADDRINUSE;
     3018                return -1;
     3019        }
     3020#endif
     3021
     3022        si->myname.sa_socklen = addrlen;
     3023        memcpy(&si->myname.sa.ss, myaddr, addrlen);
     3024
     3025        ret = sockaddr_convert_to_un(si,
     3026                                     myaddr,
     3027                                     addrlen,
     3028                                     &un_addr.sa.un,
     3029                                     1,
     3030                                     &si->bcast);
    17713031        if (ret == -1) return -1;
    17723032
    1773         unlink(un_addr.sun_path);
    1774 
    1775         ret = real_bind(s, (struct sockaddr *)(void *)&un_addr,
    1776                         sizeof(struct sockaddr_un));
     3033        unlink(un_addr.sa.un.sun_path);
     3034
     3035        ret = libc_bind(s, &un_addr.sa.s, un_addr.sa_socklen);
     3036
     3037        SWRAP_LOG(SWRAP_LOG_TRACE,
     3038                  "bind() path=%s, fd=%d",
     3039                  un_addr.sa.un.sun_path, s);
    17773040
    17783041        if (ret == 0) {
     
    17833046}
    17843047
    1785 _PUBLIC_ int swrap_listen(int s, int backlog)
     3048int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
     3049{
     3050        return swrap_bind(s, myaddr, addrlen);
     3051}
     3052
     3053/****************************************************************************
     3054 *   BINDRESVPORT
     3055 ***************************************************************************/
     3056
     3057#ifdef HAVE_BINDRESVPORT
     3058static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
     3059
     3060static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
     3061{
     3062        struct swrap_address myaddr = {
     3063                .sa_socklen = sizeof(struct sockaddr_storage),
     3064        };
     3065        socklen_t salen;
     3066        static uint16_t port;
     3067        uint16_t i;
     3068        int rc = -1;
     3069        int af;
     3070
     3071#define SWRAP_STARTPORT 600
     3072#define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
     3073#define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
     3074
     3075        if (port == 0) {
     3076                port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
     3077        }
     3078
     3079        if (sa == NULL) {
     3080                salen = myaddr.sa_socklen;
     3081                sa = &myaddr.sa.s;
     3082
     3083                rc = swrap_getsockname(sd, &myaddr.sa.s, &salen);
     3084                if (rc < 0) {
     3085                        return -1;
     3086                }
     3087
     3088                af = sa->sa_family;
     3089                memset(&myaddr.sa.ss, 0, salen);
     3090        } else {
     3091                af = sa->sa_family;
     3092        }
     3093
     3094        for (i = 0; i < SWRAP_NPORTS; i++, port++) {
     3095                switch(af) {
     3096                case AF_INET: {
     3097                        struct sockaddr_in *sinp = (struct sockaddr_in *)(void *)sa;
     3098
     3099                        salen = sizeof(struct sockaddr_in);
     3100                        sinp->sin_port = htons(port);
     3101                        break;
     3102                }
     3103                case AF_INET6: {
     3104                        struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)(void *)sa;
     3105
     3106                        salen = sizeof(struct sockaddr_in6);
     3107                        sin6p->sin6_port = htons(port);
     3108                        break;
     3109                }
     3110                default:
     3111                        errno = EAFNOSUPPORT;
     3112                        return -1;
     3113                }
     3114                sa->sa_family = af;
     3115
     3116                if (port > SWRAP_ENDPORT) {
     3117                        port = SWRAP_STARTPORT;
     3118                }
     3119
     3120                rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
     3121                if (rc == 0 || errno != EADDRINUSE) {
     3122                        break;
     3123                }
     3124        }
     3125
     3126        return rc;
     3127}
     3128
     3129int bindresvport(int sockfd, struct sockaddr_in *sinp)
     3130{
     3131        return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);
     3132}
     3133#endif
     3134
     3135/****************************************************************************
     3136 *   LISTEN
     3137 ***************************************************************************/
     3138
     3139static int swrap_listen(int s, int backlog)
    17863140{
    17873141        int ret;
     
    17893143
    17903144        if (!si) {
    1791                 return real_listen(s, backlog);
    1792         }
    1793 
    1794         ret = real_listen(s, backlog);
     3145                return libc_listen(s, backlog);
     3146        }
     3147
     3148        ret = libc_listen(s, backlog);
    17953149
    17963150        return ret;
    17973151}
    17983152
    1799 _PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
     3153int listen(int s, int backlog)
     3154{
     3155        return swrap_listen(s, backlog);
     3156}
     3157
     3158/****************************************************************************
     3159 *   FOPEN
     3160 ***************************************************************************/
     3161
     3162static FILE *swrap_fopen(const char *name, const char *mode)
     3163{
     3164        FILE *fp;
     3165
     3166        fp = libc_fopen(name, mode);
     3167        if (fp != NULL) {
     3168                int fd = fileno(fp);
     3169
     3170                swrap_remove_stale(fd);
     3171        }
     3172
     3173        return fp;
     3174}
     3175
     3176FILE *fopen(const char *name, const char *mode)
     3177{
     3178        return swrap_fopen(name, mode);
     3179}
     3180
     3181/****************************************************************************
     3182 *   OPEN
     3183 ***************************************************************************/
     3184
     3185static int swrap_vopen(const char *pathname, int flags, va_list ap)
     3186{
     3187        int ret;
     3188
     3189        ret = libc_vopen(pathname, flags, ap);
     3190        if (ret != -1) {
     3191                /*
     3192                 * There are methods for closing descriptors (libc-internal code
     3193                 * paths, direct syscalls) which close descriptors in ways that
     3194                 * we can't intercept, so try to recover when we notice that
     3195                 * that's happened
     3196                 */
     3197                swrap_remove_stale(ret);
     3198        }
     3199        return ret;
     3200}
     3201
     3202int open(const char *pathname, int flags, ...)
     3203{
     3204        va_list ap;
     3205        int fd;
     3206
     3207        va_start(ap, flags);
     3208        fd = swrap_vopen(pathname, flags, ap);
     3209        va_end(ap);
     3210
     3211        return fd;
     3212}
     3213
     3214/****************************************************************************
     3215 *   GETPEERNAME
     3216 ***************************************************************************/
     3217
     3218static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
    18003219{
    18013220        struct socket_info *si = find_socket_info(s);
     3221        socklen_t len;
    18023222
    18033223        if (!si) {
    1804                 return real_getpeername(s, name, addrlen);
    1805         }
    1806 
    1807         if (!si->peername)
     3224                return libc_getpeername(s, name, addrlen);
     3225        }
     3226
     3227        if (si->peername.sa_socklen == 0)
    18083228        {
    18093229                errno = ENOTCONN;
     
    18113231        }
    18123232
    1813         memcpy(name, si->peername, si->peername_len);
    1814         *addrlen = si->peername_len;
     3233        len = MIN(*addrlen, si->peername.sa_socklen);
     3234        if (len == 0) {
     3235                return 0;
     3236        }
     3237
     3238        memcpy(name, &si->peername.sa.ss, len);
     3239        *addrlen = si->peername.sa_socklen;
    18153240
    18163241        return 0;
    18173242}
    18183243
    1819 _PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
     3244#ifdef HAVE_ACCEPT_PSOCKLEN_T
     3245int getpeername(int s, struct sockaddr *name, Psocklen_t addrlen)
     3246#else
     3247int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
     3248#endif
     3249{
     3250        return swrap_getpeername(s, name, (socklen_t *)addrlen);
     3251}
     3252
     3253/****************************************************************************
     3254 *   GETSOCKNAME
     3255 ***************************************************************************/
     3256
     3257static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
    18203258{
    18213259        struct socket_info *si = find_socket_info(s);
     3260        socklen_t len;
    18223261
    18233262        if (!si) {
    1824                 return real_getsockname(s, name, addrlen);
    1825         }
    1826 
    1827         memcpy(name, si->myname, si->myname_len);
    1828         *addrlen = si->myname_len;
     3263                return libc_getsockname(s, name, addrlen);
     3264        }
     3265
     3266        len = MIN(*addrlen, si->myname.sa_socklen);
     3267        if (len == 0) {
     3268                return 0;
     3269        }
     3270
     3271        memcpy(name, &si->myname.sa.ss, len);
     3272        *addrlen = si->myname.sa_socklen;
    18293273
    18303274        return 0;
    18313275}
    18323276
    1833 _PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
     3277#ifdef HAVE_ACCEPT_PSOCKLEN_T
     3278int getsockname(int s, struct sockaddr *name, Psocklen_t addrlen)
     3279#else
     3280int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
     3281#endif
     3282{
     3283        return swrap_getsockname(s, name, (socklen_t *)addrlen);
     3284}
     3285
     3286/****************************************************************************
     3287 *   GETSOCKOPT
     3288 ***************************************************************************/
     3289
     3290#ifndef SO_PROTOCOL
     3291# ifdef SO_PROTOTYPE /* The Solaris name */
     3292#  define SO_PROTOCOL SO_PROTOTYPE
     3293# endif /* SO_PROTOTYPE */
     3294#endif /* SO_PROTOCOL */
     3295
     3296static int swrap_getsockopt(int s, int level, int optname,
     3297                            void *optval, socklen_t *optlen)
    18343298{
    18353299        struct socket_info *si = find_socket_info(s);
    18363300
    18373301        if (!si) {
    1838                 return real_getsockopt(s, level, optname, optval, optlen);
     3302                return libc_getsockopt(s,
     3303                                       level,
     3304                                       optname,
     3305                                       optval,
     3306                                       optlen);
    18393307        }
    18403308
    18413309        if (level == SOL_SOCKET) {
    1842                 return real_getsockopt(s, level, optname, optval, optlen);
    1843         }
     3310                switch (optname) {
     3311#ifdef SO_DOMAIN
     3312                case SO_DOMAIN:
     3313                        if (optval == NULL || optlen == NULL ||
     3314                            *optlen < (socklen_t)sizeof(int)) {
     3315                                errno = EINVAL;
     3316                                return -1;
     3317                        }
     3318
     3319                        *optlen = sizeof(int);
     3320                        *(int *)optval = si->family;
     3321                        return 0;
     3322#endif /* SO_DOMAIN */
     3323
     3324#ifdef SO_PROTOCOL
     3325                case SO_PROTOCOL:
     3326                        if (optval == NULL || optlen == NULL ||
     3327                            *optlen < (socklen_t)sizeof(int)) {
     3328                                errno = EINVAL;
     3329                                return -1;
     3330                        }
     3331
     3332                        *optlen = sizeof(int);
     3333                        *(int *)optval = si->protocol;
     3334                        return 0;
     3335#endif /* SO_PROTOCOL */
     3336                case SO_TYPE:
     3337                        if (optval == NULL || optlen == NULL ||
     3338                            *optlen < (socklen_t)sizeof(int)) {
     3339                                errno = EINVAL;
     3340                                return -1;
     3341                        }
     3342
     3343                        *optlen = sizeof(int);
     3344                        *(int *)optval = si->type;
     3345                        return 0;
     3346                default:
     3347                        return libc_getsockopt(s,
     3348                                               level,
     3349                                               optname,
     3350                                               optval,
     3351                                               optlen);
     3352                }
     3353        }
    18443354
    18453355        errno = ENOPROTOOPT;
     
    18473357}
    18483358
    1849 _PUBLIC_ int swrap_setsockopt(int s, int  level,  int  optname,  const  void  *optval, socklen_t optlen)
     3359#ifdef HAVE_ACCEPT_PSOCKLEN_T
     3360int getsockopt(int s, int level, int optname, void *optval, Psocklen_t optlen)
     3361#else
     3362int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
     3363#endif
     3364{
     3365        return swrap_getsockopt(s, level, optname, optval, (socklen_t *)optlen);
     3366}
     3367
     3368/****************************************************************************
     3369 *   SETSOCKOPT
     3370 ***************************************************************************/
     3371
     3372static int swrap_setsockopt(int s, int level, int optname,
     3373                            const void *optval, socklen_t optlen)
    18503374{
    18513375        struct socket_info *si = find_socket_info(s);
    18523376
    18533377        if (!si) {
    1854                 return real_setsockopt(s, level, optname, optval, optlen);
     3378                return libc_setsockopt(s,
     3379                                       level,
     3380                                       optname,
     3381                                       optval,
     3382                                       optlen);
    18553383        }
    18563384
    18573385        if (level == SOL_SOCKET) {
    1858                 return real_setsockopt(s, level, optname, optval, optlen);
     3386                return libc_setsockopt(s,
     3387                                       level,
     3388                                       optname,
     3389                                       optval,
     3390                                       optlen);
    18593391        }
    18603392
    18613393        switch (si->family) {
    18623394        case AF_INET:
     3395                if (level == IPPROTO_IP) {
     3396#ifdef IP_PKTINFO
     3397                        if (optname == IP_PKTINFO) {
     3398                                si->pktinfo = AF_INET;
     3399                        }
     3400#endif /* IP_PKTINFO */
     3401                }
    18633402                return 0;
    18643403#ifdef HAVE_IPV6
    18653404        case AF_INET6:
     3405                if (level == IPPROTO_IPV6) {
     3406#ifdef IPV6_RECVPKTINFO
     3407                        if (optname == IPV6_RECVPKTINFO) {
     3408                                si->pktinfo = AF_INET6;
     3409                        }
     3410#endif /* IPV6_PKTINFO */
     3411                }
    18663412                return 0;
    18673413#endif
     
    18723418}
    18733419
    1874 _PUBLIC_ int swrap_ioctl(int s, int r, void *p)
    1875 {
    1876         int ret;
     3420int setsockopt(int s, int level, int optname,
     3421               const void *optval, socklen_t optlen)
     3422{
     3423        return swrap_setsockopt(s, level, optname, optval, optlen);
     3424}
     3425
     3426/****************************************************************************
     3427 *   IOCTL
     3428 ***************************************************************************/
     3429
     3430static int swrap_vioctl(int s, unsigned long int r, va_list va)
     3431{
    18773432        struct socket_info *si = find_socket_info(s);
     3433        va_list ap;
    18783434        int value;
     3435        int rc;
    18793436
    18803437        if (!si) {
    1881                 return real_ioctl(s, r, p);
    1882         }
    1883 
    1884         ret = real_ioctl(s, r, p);
     3438                return libc_vioctl(s, r, va);
     3439        }
     3440
     3441        va_copy(ap, va);
     3442
     3443        rc = libc_vioctl(s, r, va);
    18853444
    18863445        switch (r) {
    18873446        case FIONREAD:
    1888                 value = *((int *)p);
    1889                 if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
    1890                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
     3447                value = *((int *)va_arg(ap, int *));
     3448
     3449                if (rc == -1 && errno != EAGAIN && errno != ENOBUFS) {
     3450                        swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
    18913451                } else if (value == 0) { /* END OF FILE */
    1892                         swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
    1893                 }
    1894                 break;
    1895         }
    1896 
    1897         return ret;
    1898 }
    1899 
    1900 static ssize_t swrap_sendmsg_before(struct socket_info *si,
     3452                        swrap_pcap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
     3453                }
     3454                break;
     3455        }
     3456
     3457        va_end(ap);
     3458
     3459        return rc;
     3460}
     3461
     3462#ifdef HAVE_IOCTL_INT
     3463int ioctl(int s, int r, ...)
     3464#else
     3465int ioctl(int s, unsigned long int r, ...)
     3466#endif
     3467{
     3468        va_list va;
     3469        int rc;
     3470
     3471        va_start(va, r);
     3472
     3473        rc = swrap_vioctl(s, (unsigned long int) r, va);
     3474
     3475        va_end(va);
     3476
     3477        return rc;
     3478}
     3479
     3480/*****************
     3481 * CMSG
     3482 *****************/
     3483
     3484#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     3485
     3486#ifndef CMSG_ALIGN
     3487# ifdef _ALIGN /* BSD */
     3488#define CMSG_ALIGN _ALIGN
     3489# else
     3490#define CMSG_ALIGN(len) (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
     3491# endif /* _ALIGN */
     3492#endif /* CMSG_ALIGN */
     3493
     3494/**
     3495 * @brief Add a cmsghdr to a msghdr.
     3496 *
     3497 * This is an function to add any type of cmsghdr. It will operate on the
     3498 * msg->msg_control and msg->msg_controllen you pass in by adapting them to
     3499 * the buffer position after the added cmsg element. Hence, this function is
     3500 * intended to be used with an intermediate msghdr and not on the original
     3501 * one handed in by the client.
     3502 *
     3503 * @param[in]  msg      The msghdr to which to add the cmsg.
     3504 *
     3505 * @param[in]  level    The cmsg level to set.
     3506 *
     3507 * @param[in]  type     The cmsg type to set.
     3508 *
     3509 * @param[in]  data     The cmsg data to set.
     3510 *
     3511 * @param[in]  len      the length of the data to set.
     3512 */
     3513static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
     3514                                     int level,
     3515                                     int type,
     3516                                     const void *data,
     3517                                     size_t len)
     3518{
     3519        size_t cmlen = CMSG_LEN(len);
     3520        size_t cmspace = CMSG_SPACE(len);
     3521        uint8_t cmbuf[cmspace];
     3522        void *cast_ptr = (void *)cmbuf;
     3523        struct cmsghdr *cm = (struct cmsghdr *)cast_ptr;
     3524        uint8_t *p;
     3525
     3526        memset(cmbuf, 0, cmspace);
     3527
     3528        if (msg->msg_controllen < cmlen) {
     3529                cmlen = msg->msg_controllen;
     3530                msg->msg_flags |= MSG_CTRUNC;
     3531        }
     3532
     3533        if (msg->msg_controllen < cmspace) {
     3534                cmspace = msg->msg_controllen;
     3535        }
     3536
     3537        /*
     3538         * We copy the full input data into an intermediate cmsghdr first
     3539         * in order to more easily cope with truncation.
     3540         */
     3541        cm->cmsg_len = cmlen;
     3542        cm->cmsg_level = level;
     3543        cm->cmsg_type = type;
     3544        memcpy(CMSG_DATA(cm), data, len);
     3545
     3546        /*
     3547         * We now copy the possibly truncated buffer.
     3548         * We copy cmlen bytes, but consume cmspace bytes,
     3549         * leaving the possible padding uninitialiazed.
     3550         */
     3551        p = (uint8_t *)msg->msg_control;
     3552        memcpy(p, cm, cmlen);
     3553        p += cmspace;
     3554        msg->msg_control = p;
     3555        msg->msg_controllen -= cmspace;
     3556
     3557        return;
     3558}
     3559
     3560static int swrap_msghdr_add_pktinfo(struct socket_info *si,
     3561                                    struct msghdr *msg)
     3562{
     3563        /* Add packet info */
     3564        switch (si->pktinfo) {
     3565#if defined(IP_PKTINFO) && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR))
     3566        case AF_INET: {
     3567                struct sockaddr_in *sin;
     3568#if defined(HAVE_STRUCT_IN_PKTINFO)
     3569                struct in_pktinfo pkt;
     3570#elif defined(IP_RECVDSTADDR)
     3571                struct in_addr pkt;
     3572#endif
     3573
     3574                if (si->bindname.sa_socklen == sizeof(struct sockaddr_in)) {
     3575                        sin = &si->bindname.sa.in;
     3576                } else {
     3577                        if (si->myname.sa_socklen != sizeof(struct sockaddr_in)) {
     3578                                return 0;
     3579                        }
     3580                        sin = &si->myname.sa.in;
     3581                }
     3582
     3583                ZERO_STRUCT(pkt);
     3584
     3585#if defined(HAVE_STRUCT_IN_PKTINFO)
     3586                pkt.ipi_ifindex = socket_wrapper_default_iface();
     3587                pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
     3588#elif defined(IP_RECVDSTADDR)
     3589                pkt = sin->sin_addr;
     3590#endif
     3591
     3592                swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
     3593                                         &pkt, sizeof(pkt));
     3594
     3595                break;
     3596        }
     3597#endif /* IP_PKTINFO */
     3598#if defined(HAVE_IPV6)
     3599        case AF_INET6: {
     3600#if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
     3601                struct sockaddr_in6 *sin6;
     3602                struct in6_pktinfo pkt6;
     3603
     3604                if (si->bindname.sa_socklen == sizeof(struct sockaddr_in6)) {
     3605                        sin6 = &si->bindname.sa.in6;
     3606                } else {
     3607                        if (si->myname.sa_socklen != sizeof(struct sockaddr_in6)) {
     3608                                return 0;
     3609                        }
     3610                        sin6 = &si->myname.sa.in6;
     3611                }
     3612
     3613                ZERO_STRUCT(pkt6);
     3614
     3615                pkt6.ipi6_ifindex = socket_wrapper_default_iface();
     3616                pkt6.ipi6_addr = sin6->sin6_addr;
     3617
     3618                swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
     3619                                        &pkt6, sizeof(pkt6));
     3620#endif /* HAVE_STRUCT_IN6_PKTINFO */
     3621
     3622                break;
     3623        }
     3624#endif /* IPV6_PKTINFO */
     3625        default:
     3626                return -1;
     3627        }
     3628
     3629        return 0;
     3630}
     3631
     3632static int swrap_msghdr_add_socket_info(struct socket_info *si,
     3633                                        struct msghdr *omsg)
     3634{
     3635        int rc = 0;
     3636
     3637        if (si->pktinfo > 0) {
     3638                rc = swrap_msghdr_add_pktinfo(si, omsg);
     3639        }
     3640
     3641        return rc;
     3642}
     3643
     3644static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
     3645                                   uint8_t **cm_data,
     3646                                   size_t *cm_data_space);
     3647static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
     3648                                            uint8_t **cm_data,
     3649                                            size_t *cm_data_space);
     3650
     3651static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
     3652                                        uint8_t **cm_data,
     3653                                        size_t *cm_data_space) {
     3654        struct cmsghdr *cmsg;
     3655        int rc = -1;
     3656
     3657        /* Nothing to do */
     3658        if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
     3659                return 0;
     3660        }
     3661
     3662        for (cmsg = CMSG_FIRSTHDR(msg);
     3663             cmsg != NULL;
     3664             cmsg = CMSG_NXTHDR(msg, cmsg)) {
     3665                switch (cmsg->cmsg_level) {
     3666                case IPPROTO_IP:
     3667                        rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
     3668                                                              cm_data,
     3669                                                              cm_data_space);
     3670                        break;
     3671                default:
     3672                        rc = swrap_sendmsg_copy_cmsg(cmsg,
     3673                                                     cm_data,
     3674                                                     cm_data_space);
     3675                        break;
     3676                }
     3677        }
     3678
     3679        return rc;
     3680}
     3681
     3682static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
     3683                                   uint8_t **cm_data,
     3684                                   size_t *cm_data_space)
     3685{
     3686        size_t cmspace;
     3687        uint8_t *p;
     3688
     3689        cmspace =
     3690                (*cm_data_space) +
     3691                CMSG_SPACE(cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)));
     3692
     3693        p = realloc((*cm_data), cmspace);
     3694        if (p == NULL) {
     3695                return -1;
     3696        }
     3697        (*cm_data) = p;
     3698
     3699        p = (*cm_data) + (*cm_data_space);
     3700        *cm_data_space = cmspace;
     3701
     3702        memcpy(p, cmsg, cmsg->cmsg_len);
     3703
     3704        return 0;
     3705}
     3706
     3707static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
     3708                                            uint8_t **cm_data,
     3709                                            size_t *cm_data_space);
     3710
     3711
     3712static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
     3713                                            uint8_t **cm_data,
     3714                                            size_t *cm_data_space)
     3715{
     3716        int rc = -1;
     3717
     3718        switch(cmsg->cmsg_type) {
     3719#ifdef IP_PKTINFO
     3720        case IP_PKTINFO:
     3721                rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
     3722                                                       cm_data,
     3723                                                       cm_data_space);
     3724                break;
     3725#endif
     3726#ifdef IPV6_PKTINFO
     3727        case IPV6_PKTINFO:
     3728                rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
     3729                                                       cm_data,
     3730                                                       cm_data_space);
     3731                break;
     3732#endif
     3733        default:
     3734                break;
     3735        }
     3736
     3737        return rc;
     3738}
     3739
     3740static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
     3741                                             uint8_t **cm_data,
     3742                                             size_t *cm_data_space)
     3743{
     3744        (void)cmsg; /* unused */
     3745        (void)cm_data; /* unused */
     3746        (void)cm_data_space; /* unused */
     3747
     3748        /*
     3749         * Passing a IP pktinfo to a unix socket might be rejected by the
     3750         * Kernel, at least on FreeBSD. So skip this cmsg.
     3751         */
     3752        return 0;
     3753}
     3754#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
     3755
     3756static ssize_t swrap_sendmsg_before(int fd,
     3757                                    struct socket_info *si,
    19013758                                    struct msghdr *msg,
    19023759                                    struct iovec *tmp_iov,
     
    19203777
    19213778        switch (si->type) {
    1922         case SOCK_STREAM:
     3779        case SOCK_STREAM: {
     3780                unsigned long mtu;
     3781
    19233782                if (!si->connected) {
    19243783                        errno = ENOTCONN;
     
    19303789                }
    19313790
    1932                 /*
    1933                  * cut down to 1500 byte packets for stream sockets,
    1934                  * which makes it easier to format PCAP capture files
    1935                  * (as the caller will simply continue from here)
    1936                  */
    1937 
    1938                 for (i=0; i < msg->msg_iovlen; i++) {
     3791                mtu = socket_wrapper_mtu();
     3792                for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
    19393793                        size_t nlen;
    19403794                        nlen = len + msg->msg_iov[i].iov_len;
    1941                         if (nlen > 1500) {
     3795                        if (nlen > mtu) {
    19423796                                break;
    19433797                        }
     
    19463800                if (msg->msg_iovlen == 0) {
    19473801                        *tmp_iov = msg->msg_iov[0];
    1948                         tmp_iov->iov_len = MIN(tmp_iov->iov_len, 1500);
     3802                        tmp_iov->iov_len = MIN(tmp_iov->iov_len, (size_t)mtu);
    19493803                        msg->msg_iov = tmp_iov;
    19503804                        msg->msg_iovlen = 1;
    19513805                }
    19523806                break;
    1953 
     3807        }
    19543808        case SOCK_DGRAM:
    19553809                if (si->connected) {
     
    19833837
    19843838                if (si->bound == 0) {
    1985                         ret = swrap_auto_bind(si, si->family);
    1986                         if (ret == -1) return -1;
     3839                        ret = swrap_auto_bind(fd, si, si->family);
     3840                        if (ret == -1) {
     3841                                if (errno == ENOTSOCK) {
     3842                                        swrap_remove_stale(fd);
     3843                                        return -ENOTSOCK;
     3844                                } else {
     3845                                        SWRAP_LOG(SWRAP_LOG_ERROR, "swrap_sendmsg_before failed");
     3846                                        return -1;
     3847                                }
     3848                        }
    19873849                }
    19883850
     
    19913853                }
    19923854
    1993                 ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
    1994                                              tmp_un, 0, NULL);
     3855                ret = sockaddr_convert_to_un(si,
     3856                                             &si->peername.sa.s,
     3857                                             si->peername.sa_socklen,
     3858                                             tmp_un,
     3859                                             0,
     3860                                             NULL);
    19953861                if (ret == -1) return -1;
    19963862
    1997                 ret = real_connect(si->fd, (struct sockaddr *)(void *)tmp_un,
     3863                ret = libc_connect(fd,
     3864                                   (struct sockaddr *)(void *)tmp_un,
    19983865                                   sizeof(*tmp_un));
    19993866
     
    20143881        }
    20153882
     3883#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     3884        if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
     3885                uint8_t *cmbuf = NULL;
     3886                size_t cmlen = 0;
     3887
     3888                ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen);
     3889                if (ret < 0) {
     3890                        free(cmbuf);
     3891                        return -1;
     3892                }
     3893
     3894                if (cmlen == 0) {
     3895                        msg->msg_controllen = 0;
     3896                        msg->msg_control = NULL;
     3897                } else if (cmlen < msg->msg_controllen && cmbuf != NULL) {
     3898                        memcpy(msg->msg_control, cmbuf, cmlen);
     3899                        msg->msg_controllen = cmlen;
     3900                }
     3901                free(cmbuf);
     3902        }
     3903#endif
     3904
    20163905        return 0;
    20173906}
    20183907
    2019 static void swrap_sendmsg_after(struct socket_info *si,
     3908static void swrap_sendmsg_after(int fd,
     3909                                struct socket_info *si,
    20203910                                struct msghdr *msg,
    20213911                                const struct sockaddr *to,
     
    20303920
    20313921        /* to give better errors */
    2032         if (ret == -1 && saved_errno == ENOENT) {
    2033                 saved_errno = EHOSTUNREACH;
    2034         }
    2035 
    2036         for (i=0; i < msg->msg_iovlen; i++) {
     3922        if (ret == -1) {
     3923                if (saved_errno == ENOENT) {
     3924                        saved_errno = EHOSTUNREACH;
     3925                } else if (saved_errno == ENOTSOCK) {
     3926                        /* If the fd is not a socket, remove it */
     3927                        swrap_remove_stale(fd);
     3928                }
     3929        }
     3930
     3931        for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
    20373932                avail += msg->msg_iov[i].iov_len;
    20383933        }
     
    20523947        }
    20533948
    2054         for (i=0; i < msg->msg_iovlen; i++) {
    2055                 size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
     3949        for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
     3950                size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
    20563951                memcpy(buf + ofs,
    20573952                       msg->msg_iov[i].iov_base,
     
    20653960        case SOCK_STREAM:
    20663961                if (ret == -1) {
    2067                         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
    2068                         swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
     3962                        swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
     3963                        swrap_pcap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
    20693964                } else {
    2070                         swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
     3965                        swrap_pcap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
    20713966                }
    20723967                break;
     
    20743969        case SOCK_DGRAM:
    20753970                if (si->connected) {
    2076                         to = si->peername;
     3971                        to = &si->peername.sa.s;
    20773972                }
    20783973                if (ret == -1) {
    2079                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
    2080                         swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
     3974                        swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
     3975                        swrap_pcap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
    20813976                } else {
    2082                         swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
     3977                        swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
    20833978                }
    20843979                break;
     
    20893984}
    20903985
    2091 _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
    2092 {
    2093         struct sockaddr_un un_addr;
    2094         socklen_t un_addrlen = sizeof(un_addr);
    2095         int ret;
     3986static int swrap_recvmsg_before(int fd,
     3987                                struct socket_info *si,
     3988                                struct msghdr *msg,
     3989                                struct iovec *tmp_iov)
     3990{
     3991        size_t i, len = 0;
     3992        ssize_t ret;
     3993
     3994        (void)fd; /* unused */
     3995
     3996        switch (si->type) {
     3997        case SOCK_STREAM: {
     3998                unsigned int mtu;
     3999                if (!si->connected) {
     4000                        errno = ENOTCONN;
     4001                        return -1;
     4002                }
     4003
     4004                if (msg->msg_iovlen == 0) {
     4005                        break;
     4006                }
     4007
     4008                mtu = socket_wrapper_mtu();
     4009                for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
     4010                        size_t nlen;
     4011                        nlen = len + msg->msg_iov[i].iov_len;
     4012                        if (nlen > mtu) {
     4013                                break;
     4014                        }
     4015                }
     4016                msg->msg_iovlen = i;
     4017                if (msg->msg_iovlen == 0) {
     4018                        *tmp_iov = msg->msg_iov[0];
     4019                        tmp_iov->iov_len = MIN(tmp_iov->iov_len, (size_t)mtu);
     4020                        msg->msg_iov = tmp_iov;
     4021                        msg->msg_iovlen = 1;
     4022                }
     4023                break;
     4024        }
     4025        case SOCK_DGRAM:
     4026                if (msg->msg_name == NULL) {
     4027                        errno = EINVAL;
     4028                        return -1;
     4029                }
     4030
     4031                if (msg->msg_iovlen == 0) {
     4032                        break;
     4033                }
     4034
     4035                if (si->bound == 0) {
     4036                        ret = swrap_auto_bind(fd, si, si->family);
     4037                        if (ret == -1) {
     4038                                /*
     4039                                 * When attempting to read or write to a
     4040                                 * descriptor, if an underlying autobind fails
     4041                                 * because it's not a socket, stop intercepting
     4042                                 * uses of that descriptor.
     4043                                 */
     4044                                if (errno == ENOTSOCK) {
     4045                                        swrap_remove_stale(fd);
     4046                                        return -ENOTSOCK;
     4047                                } else {
     4048                                        SWRAP_LOG(SWRAP_LOG_ERROR,
     4049                                                  "swrap_recvmsg_before failed");
     4050                                        return -1;
     4051                                }
     4052                        }
     4053                }
     4054                break;
     4055        default:
     4056                errno = EHOSTUNREACH;
     4057                return -1;
     4058        }
     4059
     4060        return 0;
     4061}
     4062
     4063static int swrap_recvmsg_after(int fd,
     4064                               struct socket_info *si,
     4065                               struct msghdr *msg,
     4066                               const struct sockaddr_un *un_addr,
     4067                               socklen_t un_addrlen,
     4068                               ssize_t ret)
     4069{
     4070        int saved_errno = errno;
     4071        size_t i;
     4072        uint8_t *buf = NULL;
     4073        off_t ofs = 0;
     4074        size_t avail = 0;
     4075        size_t remain;
     4076        int rc;
     4077
     4078        /* to give better errors */
     4079        if (ret == -1) {
     4080                if (saved_errno == ENOENT) {
     4081                        saved_errno = EHOSTUNREACH;
     4082                } else if (saved_errno == ENOTSOCK) {
     4083                        /* If the fd is not a socket, remove it */
     4084                        swrap_remove_stale(fd);
     4085                }
     4086        }
     4087
     4088        for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
     4089                avail += msg->msg_iov[i].iov_len;
     4090        }
     4091
     4092        /* Convert the socket address before we leave */
     4093        if (si->type == SOCK_DGRAM && un_addr != NULL) {
     4094                rc = sockaddr_convert_from_un(si,
     4095                                              un_addr,
     4096                                              un_addrlen,
     4097                                              si->family,
     4098                                              msg->msg_name,
     4099                                              &msg->msg_namelen);
     4100                if (rc == -1) {
     4101                        goto done;
     4102                }
     4103        }
     4104
     4105        if (avail == 0) {
     4106                rc = 0;
     4107                goto done;
     4108        }
     4109
     4110        if (ret == -1) {
     4111                remain = MIN(80, avail);
     4112        } else {
     4113                remain = ret;
     4114        }
     4115
     4116        /* we capture it as one single packet */
     4117        buf = (uint8_t *)malloc(remain);
     4118        if (buf == NULL) {
     4119                /* we just not capture the packet */
     4120                errno = saved_errno;
     4121                return -1;
     4122        }
     4123
     4124        for (i = 0; i < (size_t)msg->msg_iovlen; i++) {
     4125                size_t this_time = MIN(remain, (size_t)msg->msg_iov[i].iov_len);
     4126                memcpy(buf + ofs,
     4127                       msg->msg_iov[i].iov_base,
     4128                       this_time);
     4129                ofs += this_time;
     4130                remain -= this_time;
     4131        }
     4132
     4133        switch (si->type) {
     4134        case SOCK_STREAM:
     4135                if (ret == -1 && saved_errno != EAGAIN && saved_errno != ENOBUFS) {
     4136                        swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
     4137                } else if (ret == 0) { /* END OF FILE */
     4138                        swrap_pcap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
     4139                } else if (ret > 0) {
     4140                        swrap_pcap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
     4141                }
     4142                break;
     4143
     4144        case SOCK_DGRAM:
     4145                if (ret == -1) {
     4146                        break;
     4147                }
     4148
     4149                if (un_addr != NULL) {
     4150                        swrap_pcap_dump_packet(si,
     4151                                          msg->msg_name,
     4152                                          SWRAP_RECVFROM,
     4153                                          buf,
     4154                                          ret);
     4155                } else {
     4156                        swrap_pcap_dump_packet(si,
     4157                                          msg->msg_name,
     4158                                          SWRAP_RECV,
     4159                                          buf,
     4160                                          ret);
     4161                }
     4162
     4163                break;
     4164        }
     4165
     4166        rc = 0;
     4167done:
     4168        free(buf);
     4169        errno = saved_errno;
     4170
     4171#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4172        if (rc == 0 &&
     4173            msg->msg_controllen > 0 &&
     4174            msg->msg_control != NULL) {
     4175                rc = swrap_msghdr_add_socket_info(si, msg);
     4176                if (rc < 0) {
     4177                        return -1;
     4178                }
     4179        }
     4180#endif
     4181
     4182        return rc;
     4183}
     4184
     4185/****************************************************************************
     4186 *   RECVFROM
     4187 ***************************************************************************/
     4188
     4189static ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags,
     4190                              struct sockaddr *from, socklen_t *fromlen)
     4191{
     4192        struct swrap_address from_addr = {
     4193                .sa_socklen = sizeof(struct sockaddr_un),
     4194        };
     4195        ssize_t ret;
    20964196        struct socket_info *si = find_socket_info(s);
    2097         struct sockaddr_storage ss;
    2098         socklen_t ss_len = sizeof(ss);
    2099 
    2100         if (!si) {
    2101                 return real_recvfrom(s, buf, len, flags, from, fromlen);
    2102         }
    2103 
    2104         if (!from) {
    2105                 from = (struct sockaddr *)(void *)&ss;
    2106                 fromlen = &ss_len;
    2107         }
    2108 
    2109         if (si->type == SOCK_STREAM) {
    2110                 /* cut down to 1500 byte packets for stream sockets,
    2111                  * which makes it easier to format PCAP capture files
    2112                  * (as the caller will simply continue from here) */
    2113                 len = MIN(len, 1500);
    2114         }
    2115 
    2116         /* irix 6.4 forgets to null terminate the sun_path string :-( */
    2117         memset(&un_addr, 0, sizeof(un_addr));
    2118         ret = real_recvfrom(s, buf, len, flags,
    2119                             (struct sockaddr *)(void *)&un_addr, &un_addrlen);
    2120         if (ret == -1)
    2121                 return ret;
    2122 
    2123         if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
    2124                                      si->family, from, fromlen) == -1) {
    2125                 return -1;
    2126         }
    2127 
    2128         swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);
    2129 
    2130         return ret;
    2131 }
    2132 
    2133 
    2134 _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
    2135 {
     4197        struct swrap_address saddr = {
     4198                .sa_socklen = sizeof(struct sockaddr_storage),
     4199        };
    21364200        struct msghdr msg;
    21374201        struct iovec tmp;
    2138         struct sockaddr_un un_addr;
     4202        int tret;
     4203
     4204        if (!si) {
     4205                return libc_recvfrom(s,
     4206                                     buf,
     4207                                     len,
     4208                                     flags,
     4209                                     from,
     4210                                     fromlen);
     4211        }
     4212
     4213        tmp.iov_base = buf;
     4214        tmp.iov_len = len;
     4215
     4216        ZERO_STRUCT(msg);
     4217        if (from != NULL && fromlen != NULL) {
     4218                msg.msg_name = from;   /* optional address */
     4219                msg.msg_namelen = *fromlen; /* size of address */
     4220        } else {
     4221                msg.msg_name = &saddr.sa.s; /* optional address */
     4222                msg.msg_namelen = saddr.sa_socklen; /* size of address */
     4223        }
     4224        msg.msg_iov = &tmp;            /* scatter/gather array */
     4225        msg.msg_iovlen = 1;            /* # elements in msg_iov */
     4226#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4227        msg.msg_control = NULL;        /* ancillary data, see below */
     4228        msg.msg_controllen = 0;        /* ancillary data buffer len */
     4229        msg.msg_flags = 0;             /* flags on received message */
     4230#endif
     4231
     4232        tret = swrap_recvmsg_before(s, si, &msg, &tmp);
     4233        if (tret < 0) {
     4234                return -1;
     4235        }
     4236
     4237        buf = msg.msg_iov[0].iov_base;
     4238        len = msg.msg_iov[0].iov_len;
     4239
     4240        ret = libc_recvfrom(s,
     4241                            buf,
     4242                            len,
     4243                            flags,
     4244                            &from_addr.sa.s,
     4245                            &from_addr.sa_socklen);
     4246        if (ret == -1) {
     4247                return ret;
     4248        }
     4249
     4250        tret = swrap_recvmsg_after(s,
     4251                                   si,
     4252                                   &msg,
     4253                                   &from_addr.sa.un,
     4254                                   from_addr.sa_socklen,
     4255                                   ret);
     4256        if (tret != 0) {
     4257                return tret;
     4258        }
     4259
     4260        if (from != NULL && fromlen != NULL) {
     4261                *fromlen = msg.msg_namelen;
     4262        }
     4263
     4264        return ret;
     4265}
     4266
     4267#ifdef HAVE_ACCEPT_PSOCKLEN_T
     4268ssize_t recvfrom(int s, void *buf, size_t len, int flags,
     4269                 struct sockaddr *from, Psocklen_t fromlen)
     4270#else
     4271ssize_t recvfrom(int s, void *buf, size_t len, int flags,
     4272                 struct sockaddr *from, socklen_t *fromlen)
     4273#endif
     4274{
     4275        return swrap_recvfrom(s, buf, len, flags, from, (socklen_t *)fromlen);
     4276}
     4277
     4278/****************************************************************************
     4279 *   SENDTO
     4280 ***************************************************************************/
     4281
     4282static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags,
     4283                            const struct sockaddr *to, socklen_t tolen)
     4284{
     4285        struct msghdr msg;
     4286        struct iovec tmp;
     4287        struct swrap_address un_addr = {
     4288                .sa_socklen = sizeof(struct sockaddr_un),
     4289        };
    21394290        const struct sockaddr_un *to_un = NULL;
    21404291        ssize_t ret;
     4292        int rc;
    21414293        struct socket_info *si = find_socket_info(s);
    21424294        int bcast = 0;
    21434295
    21444296        if (!si) {
    2145                 return real_sendto(s, buf, len, flags, to, tolen);
     4297                return libc_sendto(s, buf, len, flags, to, tolen);
    21464298        }
    21474299
     
    21544306        msg.msg_iov = &tmp;            /* scatter/gather array */
    21554307        msg.msg_iovlen = 1;            /* # elements in msg_iov */
    2156 #if 0 /* not available on solaris */
     4308#if HAVE_STRUCT_MSGHDR_MSG_CONTROL
    21574309        msg.msg_control = NULL;        /* ancillary data, see below */
    21584310        msg.msg_controllen = 0;        /* ancillary data buffer len */
     
    21604312#endif
    21614313
    2162         ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
    2163         if (ret == -1) return -1;
     4314        rc = swrap_sendmsg_before(s,
     4315                                  si,
     4316                                  &msg,
     4317                                  &tmp,
     4318                                  &un_addr.sa.un,
     4319                                  &to_un,
     4320                                  &to,
     4321                                  &bcast);
     4322        if (rc < 0) {
     4323                return -1;
     4324        }
    21644325
    21654326        buf = msg.msg_iov[0].iov_base;
     
    21694330                struct stat st;
    21704331                unsigned int iface;
    2171                 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
     4332                unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
    21724333                char type;
    21734334
     
    21754336
    21764337                for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
    2177                         snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
     4338                        snprintf(un_addr.sa.un.sun_path,
     4339                                 sizeof(un_addr.sa.un.sun_path),
     4340                                 "%s/"SOCKET_FORMAT,
    21784341                                 socket_wrapper_dir(), type, iface, prt);
    2179                         if (stat(un_addr.sun_path, &st) != 0) continue;
     4342                        if (stat(un_addr.sa.un.sun_path, &st) != 0) continue;
    21804343
    21814344                        /* ignore the any errors in broadcast sends */
    2182                         real_sendto(s, buf, len, flags,
    2183                                     (struct sockaddr *)(void *)&un_addr,
    2184                                     sizeof(un_addr));
    2185                 }
    2186 
    2187                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
     4345                        libc_sendto(s,
     4346                                    buf,
     4347                                    len,
     4348                                    flags,
     4349                                    &un_addr.sa.s,
     4350                                    un_addr.sa_socklen);
     4351                }
     4352
     4353                swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
    21884354
    21894355                return len;
    21904356        }
    21914357
    2192         ret = real_sendto(s, buf, len, flags, msg.msg_name, msg.msg_namelen);
    2193 
    2194         swrap_sendmsg_after(si, &msg, to, ret);
     4358        ret = libc_sendto(s,
     4359                          buf,
     4360                          len,
     4361                          flags,
     4362                          (struct sockaddr *)msg.msg_name,
     4363                          msg.msg_namelen);
     4364
     4365        swrap_sendmsg_after(s, si, &msg, to, ret);
    21954366
    21964367        return ret;
    21974368}
    21984369
    2199 _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
    2200 {
    2201         int ret;
    2202         struct socket_info *si = find_socket_info(s);
    2203 
    2204         if (!si) {
    2205                 return real_recv(s, buf, len, flags);
    2206         }
    2207 
    2208         if (si->type == SOCK_STREAM) {
    2209                 /* cut down to 1500 byte packets for stream sockets,
    2210                  * which makes it easier to format PCAP capture files
    2211                  * (as the caller will simply continue from here) */
    2212                 len = MIN(len, 1500);
    2213         }
    2214 
    2215         ret = real_recv(s, buf, len, flags);
    2216         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
    2217                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
    2218         } else if (ret == 0) { /* END OF FILE */
    2219                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
    2220         } else if (ret > 0) {
    2221                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
     4370ssize_t sendto(int s, const void *buf, size_t len, int flags,
     4371               const struct sockaddr *to, socklen_t tolen)
     4372{
     4373        return swrap_sendto(s, buf, len, flags, to, tolen);
     4374}
     4375
     4376/****************************************************************************
     4377 *   READV
     4378 ***************************************************************************/
     4379
     4380static ssize_t swrap_recv(int s, void *buf, size_t len, int flags)
     4381{
     4382        struct socket_info *si;
     4383        struct msghdr msg;
     4384        struct swrap_address saddr = {
     4385                .sa_socklen = sizeof(struct sockaddr_storage),
     4386        };
     4387        struct iovec tmp;
     4388        ssize_t ret;
     4389        int tret;
     4390
     4391        si = find_socket_info(s);
     4392        if (si == NULL) {
     4393                return libc_recv(s, buf, len, flags);
     4394        }
     4395
     4396        tmp.iov_base = buf;
     4397        tmp.iov_len = len;
     4398
     4399        ZERO_STRUCT(msg);
     4400        msg.msg_name = &saddr.sa.s;    /* optional address */
     4401        msg.msg_namelen = saddr.sa_socklen; /* size of address */
     4402        msg.msg_iov = &tmp;            /* scatter/gather array */
     4403        msg.msg_iovlen = 1;            /* # elements in msg_iov */
     4404#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4405        msg.msg_control = NULL;        /* ancillary data, see below */
     4406        msg.msg_controllen = 0;        /* ancillary data buffer len */
     4407        msg.msg_flags = 0;             /* flags on received message */
     4408#endif
     4409
     4410        tret = swrap_recvmsg_before(s, si, &msg, &tmp);
     4411        if (tret < 0) {
     4412                return -1;
     4413        }
     4414
     4415        buf = msg.msg_iov[0].iov_base;
     4416        len = msg.msg_iov[0].iov_len;
     4417
     4418        ret = libc_recv(s, buf, len, flags);
     4419
     4420        tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
     4421        if (tret != 0) {
     4422                return tret;
    22224423        }
    22234424
     
    22254426}
    22264427
    2227 _PUBLIC_ ssize_t swrap_read(int s, void *buf, size_t len)
    2228 {
    2229         int ret;
    2230         struct socket_info *si = find_socket_info(s);
    2231 
    2232         if (!si) {
    2233                 return real_read(s, buf, len);
    2234         }
    2235 
    2236         if (si->type == SOCK_STREAM) {
    2237                 /* cut down to 1500 byte packets for stream sockets,
    2238                  * which makes it easier to format PCAP capture files
    2239                  * (as the caller will simply continue from here) */
    2240                 len = MIN(len, 1500);
    2241         }
    2242 
    2243         ret = real_read(s, buf, len);
    2244         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
    2245                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
    2246         } else if (ret == 0) { /* END OF FILE */
    2247                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
    2248         } else if (ret > 0) {
    2249                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
     4428ssize_t recv(int s, void *buf, size_t len, int flags)
     4429{
     4430        return swrap_recv(s, buf, len, flags);
     4431}
     4432
     4433/****************************************************************************
     4434 *   READ
     4435 ***************************************************************************/
     4436
     4437static ssize_t swrap_read(int s, void *buf, size_t len)
     4438{
     4439        struct socket_info *si;
     4440        struct msghdr msg;
     4441        struct iovec tmp;
     4442        struct swrap_address saddr = {
     4443                .sa_socklen = sizeof(struct sockaddr_storage),
     4444        };
     4445        ssize_t ret;
     4446        int tret;
     4447
     4448        si = find_socket_info(s);
     4449        if (si == NULL) {
     4450                return libc_read(s, buf, len);
     4451        }
     4452
     4453        tmp.iov_base = buf;
     4454        tmp.iov_len = len;
     4455
     4456        ZERO_STRUCT(msg);
     4457        msg.msg_name = &saddr.sa.ss;   /* optional address */
     4458        msg.msg_namelen = saddr.sa_socklen; /* size of address */
     4459        msg.msg_iov = &tmp;            /* scatter/gather array */
     4460        msg.msg_iovlen = 1;            /* # elements in msg_iov */
     4461#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4462        msg.msg_control = NULL;        /* ancillary data, see below */
     4463        msg.msg_controllen = 0;        /* ancillary data buffer len */
     4464        msg.msg_flags = 0;             /* flags on received message */
     4465#endif
     4466
     4467        tret = swrap_recvmsg_before(s, si, &msg, &tmp);
     4468        if (tret < 0) {
     4469                if (tret == -ENOTSOCK) {
     4470                        return libc_read(s, buf, len);
     4471                }
     4472                return -1;
     4473        }
     4474
     4475        buf = msg.msg_iov[0].iov_base;
     4476        len = msg.msg_iov[0].iov_len;
     4477
     4478        ret = libc_read(s, buf, len);
     4479
     4480        tret = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
     4481        if (tret != 0) {
     4482                return tret;
    22504483        }
    22514484
     
    22534486}
    22544487
    2255 
    2256 _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
     4488ssize_t read(int s, void *buf, size_t len)
     4489{
     4490        return swrap_read(s, buf, len);
     4491}
     4492
     4493/****************************************************************************
     4494 *   SEND
     4495 ***************************************************************************/
     4496
     4497static ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
    22574498{
    22584499        struct msghdr msg;
     
    22604501        struct sockaddr_un un_addr;
    22614502        ssize_t ret;
     4503        int rc;
    22624504        struct socket_info *si = find_socket_info(s);
    22634505
    22644506        if (!si) {
    2265                 return real_send(s, buf, len, flags);
     4507                return libc_send(s, buf, len, flags);
    22664508        }
    22674509
     
    22744516        msg.msg_iov = &tmp;            /* scatter/gather array */
    22754517        msg.msg_iovlen = 1;            /* # elements in msg_iov */
    2276 #if 0 /* not available on solaris */
     4518#if HAVE_STRUCT_MSGHDR_MSG_CONTROL
    22774519        msg.msg_control = NULL;        /* ancillary data, see below */
    22784520        msg.msg_controllen = 0;        /* ancillary data buffer len */
     
    22804522#endif
    22814523
    2282         ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
    2283         if (ret == -1) return -1;
     4524        rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
     4525        if (rc < 0) {
     4526                return -1;
     4527        }
    22844528
    22854529        buf = msg.msg_iov[0].iov_base;
    22864530        len = msg.msg_iov[0].iov_len;
    22874531
    2288         ret = real_send(s, buf, len, flags);
    2289 
    2290         swrap_sendmsg_after(si, &msg, NULL, ret);
     4532        ret = libc_send(s, buf, len, flags);
     4533
     4534        swrap_sendmsg_after(s, si, &msg, NULL, ret);
    22914535
    22924536        return ret;
    22934537}
    22944538
    2295 _PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
     4539ssize_t send(int s, const void *buf, size_t len, int flags)
     4540{
     4541        return swrap_send(s, buf, len, flags);
     4542}
     4543
     4544/****************************************************************************
     4545 *   RECVMSG
     4546 ***************************************************************************/
     4547
     4548static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
     4549{
     4550        struct swrap_address from_addr = {
     4551                .sa_socklen = sizeof(struct sockaddr_un),
     4552        };
     4553        struct socket_info *si;
     4554        struct msghdr msg;
     4555        struct iovec tmp;
     4556#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4557        size_t msg_ctrllen_filled;
     4558        size_t msg_ctrllen_left;
     4559#endif
     4560
     4561        ssize_t ret;
     4562        int rc;
     4563
     4564        si = find_socket_info(s);
     4565        if (si == NULL) {
     4566                return libc_recvmsg(s, omsg, flags);
     4567        }
     4568
     4569        tmp.iov_base = NULL;
     4570        tmp.iov_len = 0;
     4571
     4572        ZERO_STRUCT(msg);
     4573        msg.msg_name = &from_addr.sa;              /* optional address */
     4574        msg.msg_namelen = from_addr.sa_socklen;    /* size of address */
     4575        msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
     4576        msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
     4577#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4578        msg_ctrllen_filled = 0;
     4579        msg_ctrllen_left = omsg->msg_controllen;
     4580
     4581        msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
     4582        msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
     4583        msg.msg_flags = omsg->msg_flags;           /* flags on received message */
     4584#endif
     4585
     4586        rc = swrap_recvmsg_before(s, si, &msg, &tmp);
     4587        if (rc < 0) {
     4588                return -1;
     4589        }
     4590
     4591        ret = libc_recvmsg(s, &msg, flags);
     4592
     4593#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4594        msg_ctrllen_filled += msg.msg_controllen;
     4595        msg_ctrllen_left -= msg.msg_controllen;
     4596
     4597        if (omsg->msg_control != NULL) {
     4598                uint8_t *p;
     4599
     4600                p = omsg->msg_control;
     4601                p += msg_ctrllen_filled;
     4602
     4603                msg.msg_control = p;
     4604                msg.msg_controllen = msg_ctrllen_left;
     4605        } else {
     4606                msg.msg_control = NULL;
     4607                msg.msg_controllen = 0;
     4608        }
     4609#endif
     4610
     4611        rc = swrap_recvmsg_after(s,
     4612                                 si,
     4613                                 &msg,
     4614                                 &from_addr.sa.un,
     4615                                 from_addr.sa_socklen,
     4616                                 ret);
     4617        if (rc != 0) {
     4618                return rc;
     4619        }
     4620
     4621#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4622        if (omsg->msg_control != NULL) {
     4623                /* msg.msg_controllen = space left */
     4624                msg_ctrllen_left = msg.msg_controllen;
     4625                msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
     4626        }
     4627
     4628        /* Update the original message length */
     4629        omsg->msg_controllen = msg_ctrllen_filled;
     4630        omsg->msg_flags = msg.msg_flags;
     4631#endif
     4632        omsg->msg_iovlen = msg.msg_iovlen;
     4633
     4634        /*
     4635         * From the manpage:
     4636         *
     4637         * The  msg_name  field  points  to a caller-allocated buffer that is
     4638         * used to return the source address if the socket is unconnected.  The
     4639         * caller should set msg_namelen to the size of this buffer before this
     4640         * call; upon return from a successful call, msg_name will contain the
     4641         * length of the returned address.  If the application  does  not  need
     4642         * to know the source address, msg_name can be specified as NULL.
     4643         */
     4644        if (si->type == SOCK_STREAM) {
     4645                omsg->msg_namelen = 0;
     4646        } else if (omsg->msg_name != NULL &&
     4647                   omsg->msg_namelen != 0 &&
     4648                   omsg->msg_namelen >= msg.msg_namelen) {
     4649                memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
     4650                omsg->msg_namelen = msg.msg_namelen;
     4651        }
     4652
     4653        return ret;
     4654}
     4655
     4656ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
     4657{
     4658        return swrap_recvmsg(sockfd, msg, flags);
     4659}
     4660
     4661/****************************************************************************
     4662 *   SENDMSG
     4663 ***************************************************************************/
     4664
     4665static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
    22964666{
    22974667        struct msghdr msg;
     
    23014671        const struct sockaddr *to = NULL;
    23024672        ssize_t ret;
     4673        int rc;
    23034674        struct socket_info *si = find_socket_info(s);
    23044675        int bcast = 0;
    23054676
    23064677        if (!si) {
    2307                 return real_sendmsg(s, omsg, flags);
    2308         }
     4678                return libc_sendmsg(s, omsg, flags);
     4679        }
     4680
     4681        ZERO_STRUCT(un_addr);
    23094682
    23104683        tmp.iov_base = NULL;
    23114684        tmp.iov_len = 0;
    23124685
    2313         msg = *omsg;
    2314 #if 0
    2315         msg.msg_name = omsg->msg_name;             /* optional address */
    2316         msg.msg_namelen = omsg->msg_namelen;       /* size of address */
     4686        ZERO_STRUCT(msg);
     4687
     4688        if (si->connected == 0) {
     4689                msg.msg_name = omsg->msg_name;             /* optional address */
     4690                msg.msg_namelen = omsg->msg_namelen;       /* size of address */
     4691        }
    23174692        msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
    23184693        msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
    2319         /* the following is not available on solaris */
    2320         msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
    2321         msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
     4694#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4695        if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
     4696                /* omsg is a const so use a local buffer for modifications */
     4697                uint8_t cmbuf[omsg->msg_controllen];
     4698
     4699                memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
     4700
     4701                msg.msg_control = cmbuf;       /* ancillary data, see below */
     4702                msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
     4703        }
    23224704        msg.msg_flags = omsg->msg_flags;           /* flags on received message */
    23234705#endif
    23244706
    2325         ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
    2326         if (ret == -1) return -1;
     4707        rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
     4708        if (rc < 0) {
     4709                return -1;
     4710        }
    23274711
    23284712        if (bcast) {
    23294713                struct stat st;
    23304714                unsigned int iface;
    2331                 unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
     4715                unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port);
    23324716                char type;
    23334717                size_t i, len = 0;
     
    23374721                size_t remain;
    23384722
    2339                 for (i=0; i < msg.msg_iovlen; i++) {
     4723                for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
    23404724                        avail += msg.msg_iov[i].iov_len;
    23414725                }
     
    23504734                }
    23514735
    2352                 for (i=0; i < msg.msg_iovlen; i++) {
    2353                         size_t this_time = MIN(remain, msg.msg_iov[i].iov_len);
     4736                for (i = 0; i < (size_t)msg.msg_iovlen; i++) {
     4737                        size_t this_time = MIN(remain, (size_t)msg.msg_iov[i].iov_len);
    23544738                        memcpy(buf + ofs,
    23554739                               msg.msg_iov[i].iov_base,
     
    23704754
    23714755                        /* ignore the any errors in broadcast sends */
    2372                         real_sendmsg(s, &msg, flags);
    2373                 }
    2374 
    2375                 swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
     4756                        libc_sendmsg(s, &msg, flags);
     4757                }
     4758
     4759                swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
    23764760                free(buf);
    23774761
     
    23794763        }
    23804764
    2381         ret = real_sendmsg(s, &msg, flags);
    2382 
    2383         swrap_sendmsg_after(si, &msg, to, ret);
     4765        ret = libc_sendmsg(s, &msg, flags);
     4766
     4767        swrap_sendmsg_after(s, si, &msg, to, ret);
    23844768
    23854769        return ret;
    23864770}
    23874771
    2388 int swrap_readv(int s, const struct iovec *vector, size_t count)
    2389 {
    2390         int ret;
    2391         struct socket_info *si = find_socket_info(s);
    2392         struct iovec v;
    2393 
    2394         if (!si) {
    2395                 return real_readv(s, vector, count);
    2396         }
    2397 
    2398         if (!si->connected) {
    2399                 errno = ENOTCONN;
     4772ssize_t sendmsg(int s, const struct msghdr *omsg, int flags)
     4773{
     4774        return swrap_sendmsg(s, omsg, flags);
     4775}
     4776
     4777/****************************************************************************
     4778 *   READV
     4779 ***************************************************************************/
     4780
     4781static ssize_t swrap_readv(int s, const struct iovec *vector, int count)
     4782{
     4783        struct socket_info *si;
     4784        struct msghdr msg;
     4785        struct iovec tmp;
     4786        struct swrap_address saddr = {
     4787                .sa_socklen = sizeof(struct sockaddr_storage)
     4788        };
     4789        ssize_t ret;
     4790        int rc;
     4791
     4792        si = find_socket_info(s);
     4793        if (si == NULL) {
     4794                return libc_readv(s, vector, count);
     4795        }
     4796
     4797        tmp.iov_base = NULL;
     4798        tmp.iov_len = 0;
     4799
     4800        ZERO_STRUCT(msg);
     4801        msg.msg_name = &saddr.sa.s; /* optional address */
     4802        msg.msg_namelen = saddr.sa_socklen;      /* size of address */
     4803        msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
     4804        msg.msg_iovlen = count;        /* # elements in msg_iov */
     4805#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
     4806        msg.msg_control = NULL;        /* ancillary data, see below */
     4807        msg.msg_controllen = 0;        /* ancillary data buffer len */
     4808        msg.msg_flags = 0;             /* flags on received message */
     4809#endif
     4810
     4811        rc = swrap_recvmsg_before(s, si, &msg, &tmp);
     4812        if (rc < 0) {
     4813                if (rc == -ENOTSOCK) {
     4814                        return libc_readv(s, vector, count);
     4815                }
    24004816                return -1;
    24014817        }
    24024818
    2403         if (si->type == SOCK_STREAM && count > 0) {
    2404                 /* cut down to 1500 byte packets for stream sockets,
    2405                  * which makes it easier to format PCAP capture files
    2406                  * (as the caller will simply continue from here) */
    2407                 size_t i, len = 0;
    2408 
    2409                 for (i=0; i < count; i++) {
    2410                         size_t nlen;
    2411                         nlen = len + vector[i].iov_len;
    2412                         if (nlen > 1500) {
    2413                                 break;
    2414                         }
    2415                 }
    2416                 count = i;
    2417                 if (count == 0) {
    2418                         v = vector[0];
    2419                         v.iov_len = MIN(v.iov_len, 1500);
    2420                         vector = &v;
    2421                         count = 1;
    2422                 }
    2423         }
    2424 
    2425         ret = real_readv(s, vector, count);
    2426         if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
    2427                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
    2428         } else if (ret == 0) { /* END OF FILE */
    2429                 swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
    2430         } else if (ret > 0) {
    2431                 uint8_t *buf;
    2432                 off_t ofs = 0;
    2433                 size_t i;
    2434                 size_t remain = ret;
    2435 
    2436                 /* we capture it as one single packet */
    2437                 buf = (uint8_t *)malloc(ret);
    2438                 if (!buf) {
    2439                         /* we just not capture the packet */
    2440                         errno = 0;
    2441                         return ret;
    2442                 }
    2443 
    2444                 for (i=0; i < count; i++) {
    2445                         size_t this_time = MIN(remain, vector[i].iov_len);
    2446                         memcpy(buf + ofs,
    2447                                vector[i].iov_base,
    2448                                this_time);
    2449                         ofs += this_time;
    2450                         remain -= this_time;
    2451                 }
    2452 
    2453                 swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
    2454                 free(buf);
     4819        ret = libc_readv(s, msg.msg_iov, msg.msg_iovlen);
     4820
     4821        rc = swrap_recvmsg_after(s, si, &msg, NULL, 0, ret);
     4822        if (rc != 0) {
     4823                return rc;
    24554824        }
    24564825
     
    24584827}
    24594828
    2460 int swrap_writev(int s, const struct iovec *vector, size_t count)
     4829ssize_t readv(int s, const struct iovec *vector, int count)
     4830{
     4831        return swrap_readv(s, vector, count);
     4832}
     4833
     4834/****************************************************************************
     4835 *   WRITEV
     4836 ***************************************************************************/
     4837
     4838static ssize_t swrap_writev(int s, const struct iovec *vector, int count)
    24614839{
    24624840        struct msghdr msg;
     
    24644842        struct sockaddr_un un_addr;
    24654843        ssize_t ret;
     4844        int rc;
    24664845        struct socket_info *si = find_socket_info(s);
    24674846
    24684847        if (!si) {
    2469                 return real_writev(s, vector, count);
     4848                return libc_writev(s, vector, count);
    24704849        }
    24714850
     
    24784857        msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
    24794858        msg.msg_iovlen = count;        /* # elements in msg_iov */
    2480 #if 0 /* not available on solaris */
     4859#if HAVE_STRUCT_MSGHDR_MSG_CONTROL
    24814860        msg.msg_control = NULL;        /* ancillary data, see below */
    24824861        msg.msg_controllen = 0;        /* ancillary data buffer len */
     
    24844863#endif
    24854864
    2486         ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
    2487         if (ret == -1) return -1;
    2488 
    2489         ret = real_writev(s, msg.msg_iov, msg.msg_iovlen);
    2490 
    2491         swrap_sendmsg_after(si, &msg, NULL, ret);
     4865        rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
     4866        if (rc < 0) {
     4867                if (rc == -ENOTSOCK) {
     4868                        return libc_readv(s, vector, count);
     4869                }
     4870                return -1;
     4871        }
     4872
     4873        ret = libc_writev(s, msg.msg_iov, msg.msg_iovlen);
     4874
     4875        swrap_sendmsg_after(s, si, &msg, NULL, ret);
    24924876
    24934877        return ret;
    24944878}
    24954879
    2496 _PUBLIC_ int swrap_close(int fd)
     4880ssize_t writev(int s, const struct iovec *vector, int count)
     4881{
     4882        return swrap_writev(s, vector, count);
     4883}
     4884
     4885/****************************
     4886 * CLOSE
     4887 ***************************/
     4888
     4889static int swrap_close(int fd)
    24974890{
    24984891        struct socket_info *si = find_socket_info(fd);
     4892        struct socket_info_fd *fi;
    24994893        int ret;
    25004894
    25014895        if (!si) {
    2502                 return real_close(fd);
     4896                return libc_close(fd);
     4897        }
     4898
     4899        for (fi = si->fds; fi; fi = fi->next) {
     4900                if (fi->fd == fd) {
     4901                        SWRAP_DLIST_REMOVE(si->fds, fi);
     4902                        free(fi);
     4903                        break;
     4904                }
     4905        }
     4906
     4907        if (si->fds) {
     4908                /* there are still references left */
     4909                return libc_close(fd);
    25034910        }
    25044911
    25054912        SWRAP_DLIST_REMOVE(sockets, si);
    25064913
    2507         if (si->myname && si->peername) {
    2508                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
    2509         }
    2510 
    2511         ret = real_close(fd);
    2512 
    2513         if (si->myname && si->peername) {
    2514                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
    2515                 swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
    2516         }
    2517 
    2518         if (si->path) free(si->path);
    2519         if (si->myname) free(si->myname);
    2520         if (si->peername) free(si->peername);
    2521         if (si->tmp_path) {
    2522                 unlink(si->tmp_path);
    2523                 free(si->tmp_path);
     4914        if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
     4915                swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
     4916        }
     4917
     4918        ret = libc_close(fd);
     4919
     4920        if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
     4921                swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0);
     4922                swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0);
     4923        }
     4924
     4925        if (si->un_addr.sun_path[0] != '\0') {
     4926                unlink(si->un_addr.sun_path);
    25244927        }
    25254928        free(si);
     
    25274930        return ret;
    25284931}
     4932
     4933int close(int fd)
     4934{
     4935        return swrap_close(fd);
     4936}
     4937
     4938/****************************
     4939 * DUP
     4940 ***************************/
     4941
     4942static int swrap_dup(int fd)
     4943{
     4944        struct socket_info *si;
     4945        struct socket_info_fd *fi;
     4946
     4947        si = find_socket_info(fd);
     4948
     4949        if (!si) {
     4950                return libc_dup(fd);
     4951        }
     4952
     4953        fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
     4954        if (fi == NULL) {
     4955                errno = ENOMEM;
     4956                return -1;
     4957        }
     4958
     4959        fi->fd = libc_dup(fd);
     4960        if (fi->fd == -1) {
     4961                int saved_errno = errno;
     4962                free(fi);
     4963                errno = saved_errno;
     4964                return -1;
     4965        }
     4966
     4967        /* Make sure we don't have an entry for the fd */
     4968        swrap_remove_stale(fi->fd);
     4969
     4970        SWRAP_DLIST_ADD(si->fds, fi);
     4971        return fi->fd;
     4972}
     4973
     4974int dup(int fd)
     4975{
     4976        return swrap_dup(fd);
     4977}
     4978
     4979/****************************
     4980 * DUP2
     4981 ***************************/
     4982
     4983static int swrap_dup2(int fd, int newfd)
     4984{
     4985        struct socket_info *si;
     4986        struct socket_info_fd *fi;
     4987
     4988        si = find_socket_info(fd);
     4989
     4990        if (!si) {
     4991                return libc_dup2(fd, newfd);
     4992        }
     4993
     4994        if (find_socket_info(newfd)) {
     4995                /* dup2() does an implicit close of newfd, which we
     4996                 * need to emulate */
     4997                swrap_close(newfd);
     4998        }
     4999
     5000        fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
     5001        if (fi == NULL) {
     5002                errno = ENOMEM;
     5003                return -1;
     5004        }
     5005
     5006        fi->fd = libc_dup2(fd, newfd);
     5007        if (fi->fd == -1) {
     5008                int saved_errno = errno;
     5009                free(fi);
     5010                errno = saved_errno;
     5011                return -1;
     5012        }
     5013
     5014        /* Make sure we don't have an entry for the fd */
     5015        swrap_remove_stale(fi->fd);
     5016
     5017        SWRAP_DLIST_ADD(si->fds, fi);
     5018        return fi->fd;
     5019}
     5020
     5021int dup2(int fd, int newfd)
     5022{
     5023        return swrap_dup2(fd, newfd);
     5024}
     5025
     5026/****************************
     5027 * FCNTL
     5028 ***************************/
     5029
     5030static int swrap_vfcntl(int fd, int cmd, va_list va)
     5031{
     5032        struct socket_info_fd *fi;
     5033        struct socket_info *si;
     5034        int rc;
     5035
     5036        si = find_socket_info(fd);
     5037        if (si == NULL) {
     5038                rc = libc_vfcntl(fd, cmd, va);
     5039
     5040                return rc;
     5041        }
     5042
     5043        switch (cmd) {
     5044        case F_DUPFD:
     5045                fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
     5046                if (fi == NULL) {
     5047                        errno = ENOMEM;
     5048                        return -1;
     5049                }
     5050
     5051                fi->fd = libc_vfcntl(fd, cmd, va);
     5052                if (fi->fd == -1) {
     5053                        int saved_errno = errno;
     5054                        free(fi);
     5055                        errno = saved_errno;
     5056                        return -1;
     5057                }
     5058
     5059                /* Make sure we don't have an entry for the fd */
     5060                swrap_remove_stale(fi->fd);
     5061
     5062                SWRAP_DLIST_ADD(si->fds, fi);
     5063
     5064                rc = fi->fd;
     5065                break;
     5066        default:
     5067                rc = libc_vfcntl(fd, cmd, va);
     5068                break;
     5069        }
     5070
     5071        return rc;
     5072}
     5073
     5074int fcntl(int fd, int cmd, ...)
     5075{
     5076        va_list va;
     5077        int rc;
     5078
     5079        va_start(va, cmd);
     5080
     5081        rc = swrap_vfcntl(fd, cmd, va);
     5082
     5083        va_end(va);
     5084
     5085        return rc;
     5086}
     5087
     5088/****************************
     5089 * EVENTFD
     5090 ***************************/
     5091
     5092#ifdef HAVE_EVENTFD
     5093static int swrap_eventfd(int count, int flags)
     5094{
     5095        int fd;
     5096
     5097        fd = libc_eventfd(count, flags);
     5098        if (fd != -1) {
     5099                swrap_remove_stale(fd);
     5100        }
     5101
     5102        return fd;
     5103}
     5104
     5105#ifdef HAVE_EVENTFD_UNSIGNED_INT
     5106int eventfd(unsigned int count, int flags)
     5107#else
     5108int eventfd(int count, int flags)
     5109#endif
     5110{
     5111        return swrap_eventfd(count, flags);
     5112}
     5113#endif
     5114
     5115/****************************
     5116 * DESTRUCTOR
     5117 ***************************/
     5118
     5119/*
     5120 * This function is called when the library is unloaded and makes sure that
     5121 * sockets get closed and the unix file for the socket are unlinked.
     5122 */
     5123void swrap_destructor(void)
     5124{
     5125        struct socket_info *s = sockets;
     5126
     5127        while (s != NULL) {
     5128                struct socket_info_fd *f = s->fds;
     5129                if (f != NULL) {
     5130                        swrap_close(f->fd);
     5131                }
     5132                s = sockets;
     5133        }
     5134
     5135        if (swrap.libc_handle != NULL) {
     5136                dlclose(swrap.libc_handle);
     5137        }
     5138        if (swrap.libsocket_handle) {
     5139                dlclose(swrap.libsocket_handle);
     5140        }
     5141}
  • vendor/current/lib/socket_wrapper/wscript

    r740 r988  
    11#!/usr/bin/env python
    22
    3 import Options
     3import os
    44
    5 def set_options(opt):
    6     gr = opt.option_group('developer options')
    7     gr.add_option('--enable-socket-wrapper',
    8                    help=("Turn on socket wrapper library (default=no)"),
    9                    action="store_true", dest='enable_socket_wrapper', default=False)
     5VERSION="1.1.4"
    106
    117def configure(conf):
    12     if (Options.options.enable_socket_wrapper or Options.options.developer or Options.options.enable_selftest):
    13         conf.DEFINE('SOCKET_WRAPPER', 1)
    14         conf.ADD_GLOBAL_DEPENDENCY('socket_wrapper')
     8    if conf.CHECK_BUNDLED_SYSTEM('socket_wrapper', minversion=VERSION, set_target=False):
     9        conf.DEFINE('USING_SYSTEM_SOCKET_WRAPPER', 1)
     10        libsocket_wrapper_so_path = 'libsocket_wrapper.so'
     11    else:
     12        # check HAVE_GCC_THREAD_LOCAL_STORAGE
     13        conf.CHECK_CODE('''
     14            __thread int tls;
    1515
     16            int main(void) {
     17                return 0;
     18            }
     19            ''',
     20            'HAVE_GCC_THREAD_LOCAL_STORAGE',
     21            addmain=False,
     22            msg='Checking for thread local storage')
     23
     24        # check HAVE_DESTRUCTOR_ATTRIBUTE
     25        conf.CHECK_CODE('''
     26            void test_destructor_attribute(void) __attribute__ ((destructor));
     27
     28            void test_destructor_attribute(void)
     29            {
     30                return;
     31            }
     32
     33            int main(void) {
     34                return 0;
     35            }
     36            ''',
     37            'HAVE_DESTRUCTOR_ATTRIBUTE',
     38            addmain=False,
     39            msg='Checking for library destructor support')
     40
     41        # check HAVE_FUNCTION_ATTRIBUTE_FORMAT
     42        conf.CHECK_CODE('''
     43            void log_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
     44
     45            int main(void) {
     46                return 0;
     47            }
     48            ''',
     49            'HAVE_FUNCTION_ATTRIBUTE_FORMAT',
     50            addmain=False,
     51            msg='Checking for printf format validation support')
     52
     53        conf.CHECK_HEADERS('sys/signalfd.h')
     54        conf.CHECK_HEADERS('sys/eventfd.h')
     55        conf.CHECK_HEADERS('sys/timerfd.h')
     56        conf.CHECK_HEADERS('gnu/lib-names.h')
     57        conf.CHECK_HEADERS('rpc/rpc.h')
     58
     59        conf.CHECK_STRUCTURE_MEMBER('struct msghdr',
     60                                    'msg_control',
     61                                    headers='sys/types.h sys/socket.h',
     62                                    define='HAVE_STRUCT_MSGHDR_MSG_CONTROL')
     63
     64        conf.CHECK_STRUCTURE_MEMBER('struct in_pktinfo',
     65                                    'ipi_addr',
     66                                    headers='sys/types.h sys/socket.h netinet/in.h',
     67                                    define='HAVE_STRUCT_IN_PKTINFO')
     68
     69        conf.CHECK_STRUCTURE_MEMBER('struct in6_pktinfo',
     70                                    'ipi6_addr',
     71                                    headers='sys/types.h sys/socket.h netinet/in.h',
     72                                    define='HAVE_STRUCT_IN6_PKTINFO')
     73
     74        conf.CHECK_FUNCS('getaddrinfo')
     75        conf.CHECK_FUNCS('signalfd eventfd timerfd_create')
     76        conf.CHECK_FUNCS('bindresvport')
     77
     78        conf.CHECK_FUNCS_IN('bind',
     79                            'socket',
     80                            checklibc=True,
     81                            headers='sys/types.h sys/socket.h')
     82
     83        conf.CHECK_C_PROTOTYPE('accept',
     84                               'int accept(int s, struct sockaddr *addr, Psocklen_t addrlen)',
     85                               define='HAVE_ACCEPT_PSOCKLEN_T', headers='sys/types.h sys/socket.h')
     86
     87        conf.CHECK_C_PROTOTYPE('ioctl',
     88                               'int ioctl(int s, int r, ...)',
     89                               define='HAVE_IOCTL_INT', headers='unistd.h sys/ioctl.h')
     90
     91        if conf.CONFIG_SET("HAVE_EVENTFD"):
     92            conf.CHECK_C_PROTOTYPE('eventfd',
     93                                   'int eventfd(unsigned int count, int flags)',
     94                                   define='HAVE_EVENTFD_UNSIGNED_INT', headers='sys/eventfd.h')
     95
     96        # Create full path to socket_wrapper
     97        srcdir = os.path.realpath(conf.srcdir)
     98        libsocket_wrapper_so_path = srcdir + '/bin/default/lib/socket_wrapper/libsocket-wrapper.so'
     99
     100    conf.DEFINE('LIBSOCKET_WRAPPER_SO_PATH', libsocket_wrapper_so_path)
     101    conf.DEFINE('SOCKET_WRAPPER', 1)
     102
     103def build(bld):
     104    if not bld.CONFIG_SET("USING_SYSTEM_SOCKET_WRAPPER"):
     105        # We need to do it this way or the library wont work.
     106        # Using private_library=True will add symbol version which
     107        # breaks preloading!
     108        bld.SAMBA_LIBRARY('socket_wrapper',
     109                          source='socket_wrapper.c',
     110                          deps='dl',
     111                          install=False,
     112                          realname='libsocket-wrapper.so')
Note: See TracChangeset for help on using the changeset viewer.