2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * 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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
21 * All rights reserved.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
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.
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.
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
53 Socket wrapper library. Passes all socket communication over
54 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
66 #include <vcl/vcom_socket_wrapper.h>
78 /* Macros for accessing mutexes */
79 #define SWRAP_LOCK(m) do { \
80 pthread_mutex_lock(&(m ## _mutex)); \
83 #define SWRAP_UNLOCK(m) do { \
84 pthread_mutex_unlock(&(m ## _mutex)); \
87 /* Add new global locks here please */
88 #define SWRAP_LOCK_ALL \
89 SWRAP_LOCK(libc_symbol_binding); \
91 #define SWRAP_UNLOCK_ALL \
92 SWRAP_UNLOCK(libc_symbol_binding); \
96 /* The mutex for accessing the global libc.symbols */
97 static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
99 /* Function prototypes */
102 #define SWRAP_LOG(...)
104 static unsigned int swrap_log_lvl = SWRAP_LOG_WARN;
107 swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
108 const char *format, ...)
109 PRINTF_ATTRIBUTE (3, 4);
110 #define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
113 swrap_log (enum swrap_dbglvl_e dbglvl,
114 const char *func, const char *format, ...)
119 va_start (va, format);
120 vsnprintf (buffer, sizeof (buffer), format, va);
123 if (dbglvl <= swrap_log_lvl)
127 case SWRAP_LOG_ERROR:
129 "SWRAP_ERROR(%d) - %s: %s\n",
130 (int) getpid (), func, buffer);
134 "SWRAP_WARN(%d) - %s: %s\n",
135 (int) getpid (), func, buffer);
137 case SWRAP_LOG_DEBUG:
139 "SWRAP_DEBUG(%d) - %s: %s\n",
140 (int) getpid (), func, buffer);
142 case SWRAP_LOG_TRACE:
144 "SWRAP_TRACE(%d) - %s: %s\n",
145 (int) getpid (), func, buffer);
153 /*********************************************************
154 * SWRAP LOADING LIBC FUNCTIONS
155 *********************************************************/
157 typedef int (*__libc_accept4) (int sockfd,
158 struct sockaddr * addr,
159 socklen_t * addrlen, int flags);
160 typedef int (*__libc_accept) (int sockfd,
161 struct sockaddr * addr, socklen_t * addrlen);
162 typedef int (*__libc_bind) (int sockfd,
163 const struct sockaddr * addr, socklen_t addrlen);
164 typedef int (*__libc_close) (int fd);
165 typedef int (*__libc_connect) (int sockfd,
166 const struct sockaddr * addr,
170 /* TBD: dup and dup2 to be implemented later */
171 typedef int (*__libc_dup) (int fd);
172 typedef int (*__libc_dup2) (int oldfd, int newfd);
175 typedef int (*__libc_fcntl) (int fd, int cmd, ...);
176 typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
178 typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
181 typedef int (*__libc_eventfd) (int count, int flags);
183 typedef int (*__libc_getpeername) (int sockfd,
184 struct sockaddr * addr,
185 socklen_t * addrlen);
186 typedef int (*__libc_getsockname) (int sockfd,
187 struct sockaddr * addr,
188 socklen_t * addrlen);
189 typedef int (*__libc_getsockopt) (int sockfd,
192 void *optval, socklen_t * optlen);
193 typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
194 typedef int (*__libc_listen) (int sockfd, int backlog);
195 typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
197 typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
198 #endif /* HAVE_OPEN64 */
199 typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
200 typedef int (*__libc_pipe) (int pipefd[2]);
201 typedef int (*__libc_read) (int fd, void *buf, size_t count);
202 typedef ssize_t (*__libc_readv) (int fd, const struct iovec * iov,
204 typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
205 typedef int (*__libc_recvfrom) (int sockfd,
209 struct sockaddr * src_addr,
210 socklen_t * addrlen);
211 typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr * msg,
213 typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
215 typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
217 typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
218 int flags, const struct sockaddr * dst_addr,
220 typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
221 const void *optval, socklen_t optlen);
223 typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
225 typedef int (*__libc_socket) (int domain, int type, int protocol);
226 typedef int (*__libc_socketpair) (int domain, int type, int protocol,
228 #ifdef HAVE_TIMERFD_CREATE
229 typedef int (*__libc_timerfd_create) (int clockid, int flags);
231 typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
232 typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
235 typedef int (*__libc_shutdown) (int fd, int how);
237 typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
238 fd_set * __restrict __writefds,
239 fd_set * __restrict __exceptfds,
240 struct timeval * __restrict __timeout);
243 typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
244 fd_set * __restrict __writefds,
245 fd_set * __restrict __exceptfds,
246 const struct timespec * __restrict __timeout,
247 const __sigset_t * __restrict __sigmask);
250 typedef int (*__libc_epoll_create) (int __size);
252 typedef int (*__libc_epoll_create1) (int __flags);
254 typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
255 struct epoll_event * __event);
257 typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
258 int __maxevents, int __timeout);
260 typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
261 int __maxevents, int __timeout,
262 const __sigset_t * __ss);
264 typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
268 typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
269 const struct timespec * __timeout,
270 const __sigset_t * __ss);
274 #define SWRAP_SYMBOL_ENTRY(i) \
280 struct swrap_libc_symbols
282 SWRAP_SYMBOL_ENTRY (accept4);
283 SWRAP_SYMBOL_ENTRY (accept);
284 SWRAP_SYMBOL_ENTRY (bind);
285 SWRAP_SYMBOL_ENTRY (close);
286 SWRAP_SYMBOL_ENTRY (connect);
288 /* TBD: dup and dup2 to be implemented later */
289 SWRAP_SYMBOL_ENTRY (dup);
290 SWRAP_SYMBOL_ENTRY (dup2);
292 SWRAP_SYMBOL_ENTRY (fcntl);
293 SWRAP_SYMBOL_ENTRY (fopen);
295 SWRAP_SYMBOL_ENTRY (fopen64);
298 SWRAP_SYMBOL_ENTRY (eventfd);
300 SWRAP_SYMBOL_ENTRY (getpeername);
301 SWRAP_SYMBOL_ENTRY (getsockname);
302 SWRAP_SYMBOL_ENTRY (getsockopt);
303 SWRAP_SYMBOL_ENTRY (ioctl);
304 SWRAP_SYMBOL_ENTRY (listen);
305 SWRAP_SYMBOL_ENTRY (open);
307 SWRAP_SYMBOL_ENTRY (open64);
309 SWRAP_SYMBOL_ENTRY (openat);
310 SWRAP_SYMBOL_ENTRY (pipe);
311 SWRAP_SYMBOL_ENTRY (read);
312 SWRAP_SYMBOL_ENTRY (readv);
313 SWRAP_SYMBOL_ENTRY (recv);
314 SWRAP_SYMBOL_ENTRY (recvfrom);
315 SWRAP_SYMBOL_ENTRY (recvmsg);
316 SWRAP_SYMBOL_ENTRY (send);
317 SWRAP_SYMBOL_ENTRY (sendmsg);
318 SWRAP_SYMBOL_ENTRY (sendto);
319 SWRAP_SYMBOL_ENTRY (setsockopt);
321 SWRAP_SYMBOL_ENTRY (signalfd);
323 SWRAP_SYMBOL_ENTRY (socket);
324 SWRAP_SYMBOL_ENTRY (socketpair);
325 #ifdef HAVE_TIMERFD_CREATE
326 SWRAP_SYMBOL_ENTRY (timerfd_create);
328 SWRAP_SYMBOL_ENTRY (write);
329 SWRAP_SYMBOL_ENTRY (writev);
331 SWRAP_SYMBOL_ENTRY (shutdown);
332 SWRAP_SYMBOL_ENTRY (select);
334 SWRAP_SYMBOL_ENTRY (pselect);
336 SWRAP_SYMBOL_ENTRY (epoll_create);
337 SWRAP_SYMBOL_ENTRY (epoll_create1);
338 SWRAP_SYMBOL_ENTRY (epoll_ctl);
339 SWRAP_SYMBOL_ENTRY (epoll_wait);
340 SWRAP_SYMBOL_ENTRY (epoll_pwait);
341 SWRAP_SYMBOL_ENTRY (poll);
343 SWRAP_SYMBOL_ENTRY (ppoll);
353 struct swrap_libc_symbols symbols;
357 static struct swrap swrap;
359 #define LIBC_NAME "libc.so"
368 swrap_str_lib (enum swrap_lib lib)
376 /* Compiler would warn us about unhandled enum value if we get here */
382 swrap_load_lib_handle (enum swrap_lib lib)
384 int flags = RTLD_LAZY;
389 flags |= RTLD_DEEPBIND;
395 handle = swrap.libc.handle;
399 handle = dlopen (LIBC_SO, flags);
401 swrap.libc.handle = handle;
406 for (i = 10; i >= 0; i--)
408 char soname[256] = { 0 };
410 snprintf (soname, sizeof (soname), "libc.so.%d", i);
411 handle = dlopen (soname, flags);
418 swrap.libc.handle = handle;
425 SWRAP_LOG (SWRAP_LOG_ERROR,
426 "Failed to dlopen library: %s\n", dlerror ());
434 _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
439 handle = swrap_load_lib_handle (lib);
441 func = dlsym (handle, fn_name);
444 SWRAP_LOG (SWRAP_LOG_ERROR,
445 "Failed to find %s: %s\n", fn_name, dlerror ());
449 SWRAP_LOG (SWRAP_LOG_TRACE,
450 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
455 #define swrap_bind_symbol_libc(sym_name) \
456 SWRAP_LOCK(libc_symbol_binding); \
457 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
458 swrap.libc.symbols._libc_##sym_name.obj = \
459 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
461 SWRAP_UNLOCK(libc_symbol_binding)
466 * Functions especially from libc need to be loaded individually, you can't load
467 * all at once or gdb will segfault at startup. The same applies to valgrind and
468 * has probably something todo with with the linker.
469 * So we need load each function at the point it is called the first time.
472 libc_accept4 (int sockfd,
473 struct sockaddr *addr, socklen_t * addrlen, int flags)
475 swrap_bind_symbol_libc (accept4);
477 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
481 libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
483 swrap_bind_symbol_libc (accept);
485 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
489 libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
491 swrap_bind_symbol_libc (bind);
493 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
499 swrap_bind_symbol_libc (close);
501 return swrap.libc.symbols._libc_close.f (fd);
505 libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
507 swrap_bind_symbol_libc (connect);
509 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
513 /* TBD: dup and dup2 to be implemented later */
517 swrap_bind_symbol_libc (dup);
519 return swrap.libc.symbols._libc_dup.f (fd);
523 libc_dup2 (int oldfd, int newfd)
525 swrap_bind_symbol_libc (dup2);
527 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
533 libc_eventfd (int count, int flags)
535 swrap_bind_symbol_libc (eventfd);
537 return swrap.libc.symbols._libc_eventfd.f (count, flags);
541 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
542 libc_vfcntl (int fd, int cmd, va_list ap)
548 swrap_bind_symbol_libc (fcntl);
550 for (i = 0; i < 4; i++)
552 args[i] = va_arg (ap, long int);
555 rc = swrap.libc.symbols._libc_fcntl.f (fd,
557 args[0], args[1], args[2], args[3]);
562 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
563 libc_vioctl (int fd, int cmd, va_list ap)
569 swrap_bind_symbol_libc (ioctl);
571 for (i = 0; i < 4; i++)
573 args[i] = va_arg (ap, long int);
576 rc = swrap.libc.symbols._libc_ioctl.f (fd,
578 args[0], args[1], args[2], args[3]);
584 libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
586 swrap_bind_symbol_libc (getpeername);
588 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
592 libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
594 swrap_bind_symbol_libc (getsockname);
596 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
600 libc_getsockopt (int sockfd,
601 int level, int optname, void *optval, socklen_t * optlen)
603 swrap_bind_symbol_libc (getsockopt);
605 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
607 optname, optval, optlen);
611 libc_listen (int sockfd, int backlog)
613 swrap_bind_symbol_libc (listen);
615 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
619 libc_read (int fd, void *buf, size_t count)
621 swrap_bind_symbol_libc (read);
623 return swrap.libc.symbols._libc_read.f (fd, buf, count);
627 libc_readv (int fd, const struct iovec * iov, int iovcnt)
629 swrap_bind_symbol_libc (readv);
631 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
635 libc_recv (int sockfd, void *buf, size_t len, int flags)
637 swrap_bind_symbol_libc (recv);
639 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
643 libc_recvfrom (int sockfd,
646 int flags, struct sockaddr *src_addr, socklen_t * addrlen)
648 swrap_bind_symbol_libc (recvfrom);
650 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
652 len, flags, src_addr, addrlen);
656 libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
658 swrap_bind_symbol_libc (recvmsg);
660 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
664 libc_send (int sockfd, const void *buf, size_t len, int flags)
666 swrap_bind_symbol_libc (send);
668 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
672 libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
674 swrap_bind_symbol_libc (sendmsg);
676 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
680 libc_sendto (int sockfd,
683 int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
685 swrap_bind_symbol_libc (sendto);
687 return swrap.libc.symbols._libc_sendto.f (sockfd,
689 len, flags, dst_addr, addrlen);
693 libc_setsockopt (int sockfd,
694 int level, int optname, const void *optval, socklen_t optlen)
696 swrap_bind_symbol_libc (setsockopt);
698 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
700 optname, optval, optlen);
704 libc_socket (int domain, int type, int protocol)
706 swrap_bind_symbol_libc (socket);
708 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
712 libc_socketpair (int domain, int type, int protocol, int sv[2])
714 swrap_bind_symbol_libc (socketpair);
716 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
720 libc_write (int fd, const void *buf, size_t count)
722 swrap_bind_symbol_libc (write);
724 return swrap.libc.symbols._libc_write.f (fd, buf, count);
728 libc_writev (int fd, const struct iovec * iov, int iovcnt)
730 swrap_bind_symbol_libc (writev);
732 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
736 libc_shutdown (int fd, int how)
738 swrap_bind_symbol_libc (shutdown);
740 return swrap.libc.symbols._libc_shutdown.f (fd, how);
744 libc_select (int __nfds, fd_set * __restrict __readfds,
745 fd_set * __restrict __writefds,
746 fd_set * __restrict __exceptfds,
747 struct timeval *__restrict __timeout)
749 swrap_bind_symbol_libc (select);
751 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
753 __exceptfds, __timeout);
758 libc_pselect (int __nfds, fd_set * __restrict __readfds,
759 fd_set * __restrict __writefds,
760 fd_set * __restrict __exceptfds,
761 const struct timespec *__restrict __timeout,
762 const __sigset_t * __restrict __sigmask)
764 swrap_bind_symbol_libc (pselect);
766 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
769 __timeout, __sigmask);
774 libc_epoll_create (int __size)
776 swrap_bind_symbol_libc (epoll_create);
778 return swrap.libc.symbols._libc_epoll_create.f (__size);
782 libc_epoll_create1 (int __flags)
784 swrap_bind_symbol_libc (epoll_create1);
786 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
790 libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
792 swrap_bind_symbol_libc (epoll_ctl);
794 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
798 libc_epoll_wait (int __epfd, struct epoll_event *__events,
799 int __maxevents, int __timeout)
801 swrap_bind_symbol_libc (epoll_wait);
803 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
804 __maxevents, __timeout);
808 libc_epoll_pwait (int __epfd, struct epoll_event *__events,
809 int __maxevents, int __timeout, const __sigset_t * __ss)
811 swrap_bind_symbol_libc (epoll_pwait);
813 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
814 __maxevents, __timeout,
819 libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
821 swrap_bind_symbol_libc (poll);
823 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
828 libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
829 const struct timespec *__timeout, const __sigset_t * __ss)
831 swrap_bind_symbol_libc (ppoll);
833 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
838 swrap_thread_prepare (void)
844 swrap_thread_parent (void)
850 swrap_thread_child (void)
855 /****************************
857 ***************************/
859 swrap_constructor (void)
862 * If we hold a lock and the application forks, then the child
863 * is not able to unlock the mutex and we are in a deadlock.
864 * This should prevent such deadlocks.
866 pthread_atfork (&swrap_thread_prepare,
867 &swrap_thread_parent, &swrap_thread_child);
870 /****************************
872 ***************************/
875 * This function is called when the library is unloaded and makes sure that
876 * sockets get closed and the unix file for the socket are unlinked.
879 swrap_destructor (void)
881 if (swrap.libc.handle != NULL)
883 dlclose (swrap.libc.handle);
885 if (swrap.libc.socket_handle)
887 dlclose (swrap.libc.socket_handle);
892 * fd.io coding-style-patch-verification: ON
895 * eval: (c-set-style "gnu")