blob: 7ae2a2266419ee497fb409480a065f24b02810f8 [file] [log] [blame]
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07001/*
Florin Corasc5df8c72019-04-08 07:42:30 -07002 * Copyright (c) 2016-2019 Cisco and/or its affiliates.
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -07003 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17 * Copyright (c) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
18 * Copyright (C) 2006-2014 Stefan Metzmacher <metze@samba.org>
19 * Copyright (C) 2013-2014 Andreas Schneider <asn@samba.org>
20 *
21 * All rights reserved.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 *
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 *
34 * 3. Neither the name of the author nor the names of its contributors
35 * may be used to endorse or promote products derived from this software
36 * without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 *
50 */
51
52/*
53 Socket wrapper library. Passes all socket communication over
54 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
55 is set.
56*/
57
Florin Coras36847942023-02-02 12:56:16 -080058#ifdef HAVE_GNU_SOURCE
59#define _GNU_SOURCE
60#endif
61
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070062#include <signal.h>
63#include <dlfcn.h>
64
65#include <stdio.h>
66#include <stdarg.h>
67#include <unistd.h>
68#include <pthread.h>
69
BenoƮt Ganne6531cf52022-09-30 17:13:33 +020070#include <vppinfra/clib.h>
71
Dave Wallace2a865272018-02-07 21:00:42 -050072#include <vcl/ldp_socket_wrapper.h>
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070073
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -070074enum swrap_dbglvl_e
75{
76 SWRAP_LOG_ERROR = 0,
77 SWRAP_LOG_WARN,
78 SWRAP_LOG_DEBUG,
79 SWRAP_LOG_TRACE
80};
81
82
83/* Macros for accessing mutexes */
84#define SWRAP_LOCK(m) do { \
85 pthread_mutex_lock(&(m ## _mutex)); \
86} while(0)
87
88#define SWRAP_UNLOCK(m) do { \
89 pthread_mutex_unlock(&(m ## _mutex)); \
90} while(0)
91
92/* Add new global locks here please */
93#define SWRAP_LOCK_ALL \
94 SWRAP_LOCK(libc_symbol_binding); \
95
96#define SWRAP_UNLOCK_ALL \
97 SWRAP_UNLOCK(libc_symbol_binding); \
98
99
100
101/* The mutex for accessing the global libc.symbols */
102static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
103
104/* Function prototypes */
105
106#ifdef NDEBUG
107#define SWRAP_LOG(...)
108#else
Dave Wallace60f54822017-10-24 20:47:45 -0400109static unsigned int swrap_log_lvl = SWRAP_LOG_WARN;
110
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700111static void
112swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
113 const char *format, ...)
114PRINTF_ATTRIBUTE (3, 4);
115#define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
116
117 static void
118 swrap_log (enum swrap_dbglvl_e dbglvl,
119 const char *func, const char *format, ...)
120{
121 char buffer[1024];
122 va_list va;
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700123
124 va_start (va, format);
125 vsnprintf (buffer, sizeof (buffer), format, va);
126 va_end (va);
127
Dave Wallace60f54822017-10-24 20:47:45 -0400128 if (dbglvl <= swrap_log_lvl)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700129 {
130 switch (dbglvl)
131 {
132 case SWRAP_LOG_ERROR:
133 fprintf (stderr,
134 "SWRAP_ERROR(%d) - %s: %s\n",
135 (int) getpid (), func, buffer);
136 break;
137 case SWRAP_LOG_WARN:
138 fprintf (stderr,
139 "SWRAP_WARN(%d) - %s: %s\n",
140 (int) getpid (), func, buffer);
141 break;
142 case SWRAP_LOG_DEBUG:
143 fprintf (stderr,
144 "SWRAP_DEBUG(%d) - %s: %s\n",
145 (int) getpid (), func, buffer);
146 break;
147 case SWRAP_LOG_TRACE:
148 fprintf (stderr,
149 "SWRAP_TRACE(%d) - %s: %s\n",
150 (int) getpid (), func, buffer);
151 break;
152 }
153 }
154}
155#endif
156
157
158/*********************************************************
159 * SWRAP LOADING LIBC FUNCTIONS
160 *********************************************************/
161
Florin Coras36847942023-02-02 12:56:16 -0800162typedef int (*__libc_accept4) (int sockfd, __SOCKADDR_ARG addr,
163 socklen_t *addrlen, int flags);
164typedef int (*__libc_accept) (int sockfd, __SOCKADDR_ARG addr,
165 socklen_t *addrlen);
166typedef int (*__libc_bind) (int sockfd, __CONST_SOCKADDR_ARG addr,
167 socklen_t addrlen);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700168typedef int (*__libc_close) (int fd);
Florin Coras36847942023-02-02 12:56:16 -0800169typedef int (*__libc_connect) (int sockfd, __CONST_SOCKADDR_ARG addr,
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700170 socklen_t addrlen);
171
172#if 0
173/* TBD: dup and dup2 to be implemented later */
174typedef int (*__libc_dup) (int fd);
175typedef int (*__libc_dup2) (int oldfd, int newfd);
176#endif
177
178typedef int (*__libc_fcntl) (int fd, int cmd, ...);
Carl Smithe16707b2019-11-13 14:37:39 +1300179#ifdef HAVE_FCNTL64
180typedef int (*__libc_fcntl64) (int fd, int cmd, ...);
181#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700182typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
183#ifdef HAVE_FOPEN64
184typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
185#endif
186#ifdef HAVE_EVENTFD
187typedef int (*__libc_eventfd) (int count, int flags);
188#endif
Florin Coras36847942023-02-02 12:56:16 -0800189typedef int (*__libc_getpeername) (int sockfd, __SOCKADDR_ARG addr,
190 socklen_t *addrlen);
191typedef int (*__libc_getsockname) (int sockfd, __SOCKADDR_ARG addr,
192 socklen_t *addrlen);
193typedef int (*__libc_getsockopt) (int sockfd, int level, int optname,
194 void *optval, socklen_t *optlen);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700195typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
196typedef int (*__libc_listen) (int sockfd, int backlog);
197typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
198#ifdef HAVE_OPEN64
199typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
200#endif /* HAVE_OPEN64 */
201typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
202typedef int (*__libc_pipe) (int pipefd[2]);
203typedef int (*__libc_read) (int fd, void *buf, size_t count);
Florin Coras36847942023-02-02 12:56:16 -0800204typedef ssize_t (*__libc_readv) (int fd, const struct iovec *iov, int iovcnt);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700205typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
Florin Coras36847942023-02-02 12:56:16 -0800206typedef int (*__libc_recvfrom) (int sockfd, void *buf, size_t len, int flags,
207 __SOCKADDR_ARG src_addr, socklen_t *addrlen);
208typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr *msg,
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700209 int flags);
Florin Coras36847942023-02-02 12:56:16 -0800210#ifdef _GNU_SOURCE
211typedef int (*__libc_recvmmsg) (int fd, struct mmsghdr *vmessages,
212 unsigned int vlen, int flags,
213 struct timespec *tmo);
214#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700215typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
216 int flags);
Dave Wallace227867f2017-11-13 21:21:53 -0500217typedef ssize_t (*__libc_sendfile) (int out_fd, int in_fd, off_t * offset,
218 size_t len);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700219typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
220 int flags);
Florin Coras36847942023-02-02 12:56:16 -0800221#ifdef _GNU_SOURCE
222typedef int (*__libc_sendmmsg) (int __fd, struct mmsghdr *__vmessages,
223 unsigned int __vlen, int __flags);
224#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700225typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
Florin Coras36847942023-02-02 12:56:16 -0800226 int flags, __CONST_SOCKADDR_ARG dst_addr,
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700227 socklen_t addrlen);
228typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
229 const void *optval, socklen_t optlen);
230#ifdef HAVE_SIGNALFD
231typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
232#endif
233typedef int (*__libc_socket) (int domain, int type, int protocol);
234typedef int (*__libc_socketpair) (int domain, int type, int protocol,
235 int sv[2]);
236#ifdef HAVE_TIMERFD_CREATE
237typedef int (*__libc_timerfd_create) (int clockid, int flags);
238#endif
239typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
240typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
241 int iovcnt);
242
243typedef int (*__libc_shutdown) (int fd, int how);
244
245typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
246 fd_set * __restrict __writefds,
247 fd_set * __restrict __exceptfds,
248 struct timeval * __restrict __timeout);
249
250#ifdef __USE_XOPEN2K
251typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
252 fd_set * __restrict __writefds,
253 fd_set * __restrict __exceptfds,
254 const struct timespec * __restrict __timeout,
255 const __sigset_t * __restrict __sigmask);
256#endif
257
258typedef int (*__libc_epoll_create) (int __size);
259
260typedef int (*__libc_epoll_create1) (int __flags);
261
262typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
263 struct epoll_event * __event);
264
265typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
266 int __maxevents, int __timeout);
267
268typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
269 int __maxevents, int __timeout,
270 const __sigset_t * __ss);
271
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700272typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
273 int __timeout);
274
Florin Coras36847942023-02-02 12:56:16 -0800275#ifdef _GNU_SOURCE
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700276typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
277 const struct timespec * __timeout,
278 const __sigset_t * __ss);
279#endif
280
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700281
282#define SWRAP_SYMBOL_ENTRY(i) \
283 union { \
284 __libc_##i f; \
285 void *obj; \
286 } _libc_##i
287
288struct swrap_libc_symbols
289{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700290 SWRAP_SYMBOL_ENTRY (accept4);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700291 SWRAP_SYMBOL_ENTRY (accept);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700292 SWRAP_SYMBOL_ENTRY (bind);
293 SWRAP_SYMBOL_ENTRY (close);
294 SWRAP_SYMBOL_ENTRY (connect);
295#if 0
296 /* TBD: dup and dup2 to be implemented later */
297 SWRAP_SYMBOL_ENTRY (dup);
298 SWRAP_SYMBOL_ENTRY (dup2);
299#endif
300 SWRAP_SYMBOL_ENTRY (fcntl);
Carl Smithe16707b2019-11-13 14:37:39 +1300301#ifdef HAVE_FCNTL64
302 SWRAP_SYMBOL_ENTRY (fcntl64);
303#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700304 SWRAP_SYMBOL_ENTRY (fopen);
305#ifdef HAVE_FOPEN64
306 SWRAP_SYMBOL_ENTRY (fopen64);
307#endif
308#ifdef HAVE_EVENTFD
309 SWRAP_SYMBOL_ENTRY (eventfd);
310#endif
311 SWRAP_SYMBOL_ENTRY (getpeername);
312 SWRAP_SYMBOL_ENTRY (getsockname);
313 SWRAP_SYMBOL_ENTRY (getsockopt);
314 SWRAP_SYMBOL_ENTRY (ioctl);
315 SWRAP_SYMBOL_ENTRY (listen);
316 SWRAP_SYMBOL_ENTRY (open);
317#ifdef HAVE_OPEN64
318 SWRAP_SYMBOL_ENTRY (open64);
319#endif
320 SWRAP_SYMBOL_ENTRY (openat);
321 SWRAP_SYMBOL_ENTRY (pipe);
322 SWRAP_SYMBOL_ENTRY (read);
323 SWRAP_SYMBOL_ENTRY (readv);
324 SWRAP_SYMBOL_ENTRY (recv);
325 SWRAP_SYMBOL_ENTRY (recvfrom);
326 SWRAP_SYMBOL_ENTRY (recvmsg);
Florin Coras36847942023-02-02 12:56:16 -0800327#ifdef _GNU_SOURCE
328 SWRAP_SYMBOL_ENTRY (recvmmsg);
329#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700330 SWRAP_SYMBOL_ENTRY (send);
Dave Wallace227867f2017-11-13 21:21:53 -0500331 SWRAP_SYMBOL_ENTRY (sendfile);
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700332 SWRAP_SYMBOL_ENTRY (sendmsg);
Florin Coras36847942023-02-02 12:56:16 -0800333#ifdef _GNU_SOURCE
334 SWRAP_SYMBOL_ENTRY (sendmmsg);
335#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700336 SWRAP_SYMBOL_ENTRY (sendto);
337 SWRAP_SYMBOL_ENTRY (setsockopt);
338#ifdef HAVE_SIGNALFD
339 SWRAP_SYMBOL_ENTRY (signalfd);
340#endif
341 SWRAP_SYMBOL_ENTRY (socket);
342 SWRAP_SYMBOL_ENTRY (socketpair);
343#ifdef HAVE_TIMERFD_CREATE
344 SWRAP_SYMBOL_ENTRY (timerfd_create);
345#endif
346 SWRAP_SYMBOL_ENTRY (write);
347 SWRAP_SYMBOL_ENTRY (writev);
348
349 SWRAP_SYMBOL_ENTRY (shutdown);
350 SWRAP_SYMBOL_ENTRY (select);
351#ifdef __USE_XOPEN2K
352 SWRAP_SYMBOL_ENTRY (pselect);
353#endif
354 SWRAP_SYMBOL_ENTRY (epoll_create);
355 SWRAP_SYMBOL_ENTRY (epoll_create1);
356 SWRAP_SYMBOL_ENTRY (epoll_ctl);
357 SWRAP_SYMBOL_ENTRY (epoll_wait);
358 SWRAP_SYMBOL_ENTRY (epoll_pwait);
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700359 SWRAP_SYMBOL_ENTRY (poll);
Florin Coras36847942023-02-02 12:56:16 -0800360#ifdef _GNU_SOURCE
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700361 SWRAP_SYMBOL_ENTRY (ppoll);
362#endif
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700363};
364
365struct swrap
366{
367 struct
368 {
369 void *handle;
370 void *socket_handle;
371 struct swrap_libc_symbols symbols;
372 } libc;
373};
374
375static struct swrap swrap;
376
377#define LIBC_NAME "libc.so"
378
379enum swrap_lib
380{
381 SWRAP_LIBC,
382};
383
384#ifndef NDEBUG
385static const char *
386swrap_str_lib (enum swrap_lib lib)
387{
388 switch (lib)
389 {
390 case SWRAP_LIBC:
391 return "libc";
392 }
393
394 /* Compiler would warn us about unhandled enum value if we get here */
395 return "unknown";
396}
397#endif
398
399static void *
400swrap_load_lib_handle (enum swrap_lib lib)
401{
402 int flags = RTLD_LAZY;
403 void *handle = NULL;
404 int i;
405
BenoƮt Ganne9fb6d402019-04-15 15:28:21 +0200406#if defined(RTLD_DEEPBIND) && !defined(CLIB_SANITIZE_ADDR)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700407 flags |= RTLD_DEEPBIND;
408#endif
409
410 switch (lib)
411 {
412 case SWRAP_LIBC:
413 handle = swrap.libc.handle;
414#ifdef LIBC_SO
415 if (handle == NULL)
416 {
417 handle = dlopen (LIBC_SO, flags);
418
419 swrap.libc.handle = handle;
420 }
421#endif
422 if (handle == NULL)
423 {
424 for (i = 10; i >= 0; i--)
425 {
426 char soname[256] = { 0 };
427
428 snprintf (soname, sizeof (soname), "libc.so.%d", i);
429 handle = dlopen (soname, flags);
430 if (handle != NULL)
431 {
432 break;
433 }
434 }
435
436 swrap.libc.handle = handle;
437 }
438 break;
439 }
440
441 if (handle == NULL)
442 {
443 SWRAP_LOG (SWRAP_LOG_ERROR,
444 "Failed to dlopen library: %s\n", dlerror ());
445 exit (-1);
446 }
447
448 return handle;
449}
450
451static void *
452_swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
453{
454 void *handle;
455 void *func;
456
457 handle = swrap_load_lib_handle (lib);
458
459 func = dlsym (handle, fn_name);
460 if (func == NULL)
461 {
462 SWRAP_LOG (SWRAP_LOG_ERROR,
463 "Failed to find %s: %s\n", fn_name, dlerror ());
464 exit (-1);
465 }
466
467 SWRAP_LOG (SWRAP_LOG_TRACE,
468 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
469
470 return func;
471}
472
473#define swrap_bind_symbol_libc(sym_name) \
474 SWRAP_LOCK(libc_symbol_binding); \
475 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
476 swrap.libc.symbols._libc_##sym_name.obj = \
477 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
478 } \
479 SWRAP_UNLOCK(libc_symbol_binding)
480
481/*
482 * IMPORTANT
483 *
484 * Functions especially from libc need to be loaded individually, you can't load
485 * all at once or gdb will segfault at startup. The same applies to valgrind and
486 * has probably something todo with with the linker.
487 * So we need load each function at the point it is called the first time.
488 */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700489int
Florin Coras36847942023-02-02 12:56:16 -0800490libc_accept4 (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen, int flags)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700491{
492 swrap_bind_symbol_libc (accept4);
493
494 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
495}
496
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700497int
Florin Coras36847942023-02-02 12:56:16 -0800498libc_accept (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700499{
500 swrap_bind_symbol_libc (accept);
501
502 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
503}
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700504
505int
Florin Coras36847942023-02-02 12:56:16 -0800506libc_bind (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700507{
508 swrap_bind_symbol_libc (bind);
509
510 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
511}
512
513int
514libc_close (int fd)
515{
516 swrap_bind_symbol_libc (close);
517
518 return swrap.libc.symbols._libc_close.f (fd);
519}
520
521int
Florin Coras36847942023-02-02 12:56:16 -0800522libc_connect (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700523{
524 swrap_bind_symbol_libc (connect);
525
526 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
527}
528
529#if 0
530/* TBD: dup and dup2 to be implemented later */
531int
532libc_dup (int fd)
533{
534 swrap_bind_symbol_libc (dup);
535
536 return swrap.libc.symbols._libc_dup.f (fd);
537}
538
539int
540libc_dup2 (int oldfd, int newfd)
541{
542 swrap_bind_symbol_libc (dup2);
543
544 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
545}
546#endif
547
548#ifdef HAVE_EVENTFD
549int
550libc_eventfd (int count, int flags)
551{
552 swrap_bind_symbol_libc (eventfd);
553
554 return swrap.libc.symbols._libc_eventfd.f (count, flags);
555}
556#endif
557
BenoƮt Ganne9fb6d402019-04-15 15:28:21 +0200558int
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700559libc_vfcntl (int fd, int cmd, va_list ap)
560{
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700561 swrap_bind_symbol_libc (fcntl);
Florin Coras0ab36f52020-05-26 19:45:45 +0000562 return swrap.libc.symbols._libc_fcntl.f (fd, cmd, va_arg (ap, long int));
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700563}
564
Carl Smithe16707b2019-11-13 14:37:39 +1300565#ifdef HAVE_FCNTL64
BenoƮt Ganne9fb6d402019-04-15 15:28:21 +0200566int
Carl Smithe16707b2019-11-13 14:37:39 +1300567libc_vfcntl64 (int fd, int cmd, va_list ap)
568{
Carl Smithe16707b2019-11-13 14:37:39 +1300569 swrap_bind_symbol_libc (fcntl64);
Florin Coras0ab36f52020-05-26 19:45:45 +0000570 return swrap.libc.symbols._libc_fcntl64.f (fd, cmd, va_arg (ap, long int));
Carl Smithe16707b2019-11-13 14:37:39 +1300571}
572#endif
573
BenoƮt Ganne9fb6d402019-04-15 15:28:21 +0200574int
Stevenb59f2272017-10-12 17:10:33 -0700575libc_vioctl (int fd, int cmd, va_list ap)
576{
577 long int args[4];
578 int rc;
579 int i;
580
581 swrap_bind_symbol_libc (ioctl);
582
583 for (i = 0; i < 4; i++)
584 {
585 args[i] = va_arg (ap, long int);
586 }
587
588 rc = swrap.libc.symbols._libc_ioctl.f (fd,
589 cmd,
590 args[0], args[1], args[2], args[3]);
591
592 return rc;
593}
594
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700595int
Florin Coras36847942023-02-02 12:56:16 -0800596libc_getpeername (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700597{
598 swrap_bind_symbol_libc (getpeername);
599
600 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
601}
602
603int
Florin Coras36847942023-02-02 12:56:16 -0800604libc_getsockname (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700605{
606 swrap_bind_symbol_libc (getsockname);
607
608 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
609}
610
611int
612libc_getsockopt (int sockfd,
613 int level, int optname, void *optval, socklen_t * optlen)
614{
615 swrap_bind_symbol_libc (getsockopt);
616
617 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
618 level,
619 optname, optval, optlen);
620}
621
622int
623libc_listen (int sockfd, int backlog)
624{
625 swrap_bind_symbol_libc (listen);
626
627 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
628}
629
Dave Wallace227867f2017-11-13 21:21:53 -0500630/* TBD: libc_read() should return ssize_t not an int */
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700631int
632libc_read (int fd, void *buf, size_t count)
633{
634 swrap_bind_symbol_libc (read);
635
636 return swrap.libc.symbols._libc_read.f (fd, buf, count);
637}
638
639ssize_t
640libc_readv (int fd, const struct iovec * iov, int iovcnt)
641{
642 swrap_bind_symbol_libc (readv);
643
644 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
645}
646
647int
648libc_recv (int sockfd, void *buf, size_t len, int flags)
649{
650 swrap_bind_symbol_libc (recv);
651
652 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
653}
654
655int
Florin Coras36847942023-02-02 12:56:16 -0800656libc_recvfrom (int sockfd, void *buf, size_t len, int flags,
657 __SOCKADDR_ARG src_addr, socklen_t *addrlen)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700658{
659 swrap_bind_symbol_libc (recvfrom);
660
661 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
662 buf,
663 len, flags, src_addr, addrlen);
664}
665
666int
667libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
668{
669 swrap_bind_symbol_libc (recvmsg);
670
671 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
672}
673
Florin Coras36847942023-02-02 12:56:16 -0800674#ifdef _GNU_SOURCE
675int
676libc_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
677 struct timespec *tmo)
678{
679 swrap_bind_symbol_libc (recvmmsg);
680
681 return swrap.libc.symbols._libc_recvmmsg.f (fd, vmessages, vlen, flags, tmo);
682}
683#endif
684
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700685int
686libc_send (int sockfd, const void *buf, size_t len, int flags)
687{
688 swrap_bind_symbol_libc (send);
689
690 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
691}
692
Dave Wallace227867f2017-11-13 21:21:53 -0500693ssize_t
694libc_sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
695{
696 swrap_bind_symbol_libc (sendfile);
697
698 return swrap.libc.symbols._libc_sendfile.f (out_fd, in_fd, offset, len);
699}
700
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700701int
702libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
703{
704 swrap_bind_symbol_libc (sendmsg);
705
706 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
707}
708
Florin Coras36847942023-02-02 12:56:16 -0800709#ifdef _GNU_SOURCE
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700710int
Florin Coras36847942023-02-02 12:56:16 -0800711libc_sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
712{
713 swrap_bind_symbol_libc (sendmmsg);
714
715 return swrap.libc.symbols._libc_sendmmsg.f (fd, vmessages, vlen, flags);
716}
717#endif
718
719int
720libc_sendto (int sockfd, const void *buf, size_t len, int flags,
721 __CONST_SOCKADDR_ARG dst_addr, socklen_t addrlen)
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700722{
723 swrap_bind_symbol_libc (sendto);
724
725 return swrap.libc.symbols._libc_sendto.f (sockfd,
726 buf,
727 len, flags, dst_addr, addrlen);
728}
729
730int
731libc_setsockopt (int sockfd,
732 int level, int optname, const void *optval, socklen_t optlen)
733{
734 swrap_bind_symbol_libc (setsockopt);
735
736 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
737 level,
738 optname, optval, optlen);
739}
740
741int
742libc_socket (int domain, int type, int protocol)
743{
744 swrap_bind_symbol_libc (socket);
745
746 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
747}
748
749int
750libc_socketpair (int domain, int type, int protocol, int sv[2])
751{
752 swrap_bind_symbol_libc (socketpair);
753
754 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
755}
756
757ssize_t
758libc_write (int fd, const void *buf, size_t count)
759{
760 swrap_bind_symbol_libc (write);
761
762 return swrap.libc.symbols._libc_write.f (fd, buf, count);
763}
764
765ssize_t
766libc_writev (int fd, const struct iovec * iov, int iovcnt)
767{
768 swrap_bind_symbol_libc (writev);
769
770 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
771}
772
773int
774libc_shutdown (int fd, int how)
775{
776 swrap_bind_symbol_libc (shutdown);
777
778 return swrap.libc.symbols._libc_shutdown.f (fd, how);
779}
780
781int
782libc_select (int __nfds, fd_set * __restrict __readfds,
783 fd_set * __restrict __writefds,
784 fd_set * __restrict __exceptfds,
785 struct timeval *__restrict __timeout)
786{
787 swrap_bind_symbol_libc (select);
788
789 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
790 __writefds,
791 __exceptfds, __timeout);
792}
793
794#ifdef __USE_XOPEN2K
795int
796libc_pselect (int __nfds, fd_set * __restrict __readfds,
797 fd_set * __restrict __writefds,
798 fd_set * __restrict __exceptfds,
799 const struct timespec *__restrict __timeout,
800 const __sigset_t * __restrict __sigmask)
801{
802 swrap_bind_symbol_libc (pselect);
803
804 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
805 __writefds,
806 __exceptfds,
807 __timeout, __sigmask);
808}
809#endif
810
811int
812libc_epoll_create (int __size)
813{
814 swrap_bind_symbol_libc (epoll_create);
815
816 return swrap.libc.symbols._libc_epoll_create.f (__size);
817}
818
819int
820libc_epoll_create1 (int __flags)
821{
822 swrap_bind_symbol_libc (epoll_create1);
823
824 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
825}
826
827int
828libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
829{
830 swrap_bind_symbol_libc (epoll_ctl);
831
832 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
833}
834
835int
836libc_epoll_wait (int __epfd, struct epoll_event *__events,
837 int __maxevents, int __timeout)
838{
839 swrap_bind_symbol_libc (epoll_wait);
840
841 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
842 __maxevents, __timeout);
843}
844
845int
846libc_epoll_pwait (int __epfd, struct epoll_event *__events,
847 int __maxevents, int __timeout, const __sigset_t * __ss)
848{
849 swrap_bind_symbol_libc (epoll_pwait);
850
851 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
852 __maxevents, __timeout,
853 __ss);
854}
855
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700856int
857libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
858{
859 swrap_bind_symbol_libc (poll);
860
861 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
862}
863
Florin Coras36847942023-02-02 12:56:16 -0800864#ifdef _GNU_SOURCE
shrinivasan ganapathy1d359632017-10-15 15:46:09 -0700865int
866libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
867 const struct timespec *__timeout, const __sigset_t * __ss)
868{
869 swrap_bind_symbol_libc (ppoll);
870
871 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
872}
873#endif
874
Keith Burns (alagalah)b327c2b2017-10-09 08:52:59 -0700875static void
876swrap_thread_prepare (void)
877{
878 SWRAP_LOCK_ALL;
879}
880
881static void
882swrap_thread_parent (void)
883{
884 SWRAP_UNLOCK_ALL;
885}
886
887static void
888swrap_thread_child (void)
889{
890 SWRAP_UNLOCK_ALL;
891}
892
893/****************************
894 * CONSTRUCTOR
895 ***************************/
896void
897swrap_constructor (void)
898{
899 /*
900 * If we hold a lock and the application forks, then the child
901 * is not able to unlock the mutex and we are in a deadlock.
902 * This should prevent such deadlocks.
903 */
904 pthread_atfork (&swrap_thread_prepare,
905 &swrap_thread_parent, &swrap_thread_child);
906}
907
908/****************************
909 * DESTRUCTOR
910 ***************************/
911
912/*
913 * This function is called when the library is unloaded and makes sure that
914 * sockets get closed and the unix file for the socket are unlinked.
915 */
916void
917swrap_destructor (void)
918{
919 if (swrap.libc.handle != NULL)
920 {
921 dlclose (swrap.libc.handle);
922 }
923 if (swrap.libc.socket_handle)
924 {
925 dlclose (swrap.libc.socket_handle);
926 }
927}
928
929/*
930 * fd.io coding-style-patch-verification: ON
931 *
932 * Local Variables:
933 * eval: (c-set-style "gnu")
934 * End:
935 */