32 #include <sys/select.h> 33 #include <sys/syscall.h> 40 static inline void ensure_init(
void);
43 static int (*libc_socket)(
int domain,
int type,
int protocol) = NULL;
44 static int (*libc_close)(
int sockfd) = NULL;
45 static int (*libc_shutdown)(
int sockfd,
int how) = NULL;
46 static int (*libc_bind)(
int sockfd,
const struct sockaddr *addr,
47 socklen_t addrlen) = NULL;
48 static int (*libc_connect)(
int sockfd,
const struct sockaddr *addr,
49 socklen_t addrlen) = NULL;
50 static int (*libc_listen)(
int sockfd,
int backlog) = NULL;
51 static int (*libc_accept4)(
int sockfd,
struct sockaddr *addr,
52 socklen_t *addrlen,
int flags) = NULL;
53 static int (*libc_accept)(
int sockfd,
struct sockaddr *addr,
54 socklen_t *addrlen) = NULL;
55 static int (*libc_fcntl)(
int sockfd,
int cmd, ...) = NULL;
56 static int (*libc_fcntl64)(
int sockfd,
int cmd, ...) = NULL;
57 static int (*libc_getsockopt)(
int sockfd,
int level,
int optname,
void *optval,
58 socklen_t *optlen) = NULL;
59 static int (*libc_setsockopt)(
int sockfd,
int level,
int optname,
60 const void *optval, socklen_t optlen) = NULL;
61 static int (*libc_getsockname)(
int sockfd,
struct sockaddr *addr,
62 socklen_t *addrlen) = NULL;
63 static int (*libc_getpeername)(
int sockfd,
struct sockaddr *addr,
64 socklen_t *addrlen) = NULL;
65 static ssize_t (*libc_read)(
int fd,
void *buf,
size_t count) = NULL;
66 static ssize_t (*libc_recv)(
int sockfd,
void *buf,
size_t len,
68 static ssize_t (*libc_recvfrom)(
int sockfd,
void *buf,
size_t len,
int flags,
69 struct sockaddr *src_addr, socklen_t *addrlen) = NULL;
70 static ssize_t (*libc_recvmsg)(
int sockfd,
struct msghdr *msg,
int flags)
72 static ssize_t (*libc_readv)(
int sockfd,
const struct iovec *iov,
int iovcnt)
74 static ssize_t (*libc_pread)(
int sockfd,
void *buf,
size_t count, off_t offset)
76 static ssize_t (*libc_write)(
int fd,
const void *buf,
size_t count) = NULL;
77 static ssize_t (*libc_send)(
int sockfd,
const void *buf,
size_t len,
int flags)
79 static ssize_t (*libc_sendto)(
int sockfd,
const void *buf,
size_t len,
80 int flags,
const struct sockaddr *dest_addr, socklen_t addrlen) = NULL;
81 static ssize_t (*libc_sendmsg)(
int sockfd,
const struct msghdr *msg,
int flags)
83 static ssize_t (*libc_writev)(
int sockfd,
const struct iovec *iov,
int iovcnt)
85 static ssize_t (*libc_pwrite)(
int sockfd,
const void *buf,
size_t count,
87 static ssize_t (*libc_sendfile)(
int sockfd,
int in_fd, off_t *offset,
89 static long (*libc_syscall)(
long num, ...) = NULL;
91 int socket(
int domain,
int type,
int protocol)
96 if (domain != AF_INET ||
97 (type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) != SOCK_STREAM) {
98 return libc_socket(domain, type, protocol);
101 return tas_socket(domain, type, protocol);
104 int close(
int sockfd)
108 if ((ret = tas_close(sockfd)) == -1 && errno == EBADF) {
109 return libc_close(sockfd);
114 int shutdown(
int sockfd,
int how)
118 if ((ret = tas_shutdown(sockfd, how)) == -1 && errno == EBADF) {
119 return libc_shutdown(sockfd, how);
124 int bind(
int sockfd,
const struct sockaddr *addr, socklen_t addrlen)
128 if ((ret = tas_bind(sockfd, addr, addrlen)) == -1 && errno == EBADF) {
129 return libc_bind(sockfd, addr, addrlen);
134 int connect(
int sockfd,
const struct sockaddr *addr, socklen_t addrlen)
138 if ((ret = tas_connect(sockfd, addr, addrlen)) == -1 && errno == EBADF) {
139 return libc_connect(sockfd, addr, addrlen);
144 int listen(
int sockfd,
int backlog)
148 if ((ret = tas_listen(sockfd, backlog)) == -1 && errno == EBADF) {
149 return libc_listen(sockfd, backlog);
154 int accept4(
int sockfd,
struct sockaddr *addr, socklen_t *addrlen,
159 if ((ret = tas_accept4(sockfd, addr, addrlen, flags)) == -1 &&
162 return libc_accept4(sockfd, addr, addrlen, flags);
167 int accept(
int sockfd,
struct sockaddr *addr, socklen_t *addrlen)
171 if ((ret =
tas_accept(sockfd, addr, addrlen)) == -1 && errno == EBADF) {
172 return libc_accept(sockfd, addr, addrlen);
177 static int vfcntl(
int sockfd,
int cmd, va_list val,
int is_64)
195 if ((ret = tas_fcntl(sockfd, cmd)) == -1 && errno == EBADF) {
197 ret = libc_fcntl64(sockfd, cmd);
199 ret = libc_fcntl(sockfd, cmd);
206 case F_DUPFD_CLOEXEC:
217 arg_i = va_arg(val,
int);
218 if ((ret = tas_fcntl(sockfd, cmd, arg_i)) == -1 && errno == EBADF) {
220 ret = libc_fcntl64(sockfd, cmd, arg_i);
222 ret = libc_fcntl(sockfd, cmd, arg_i);
240 #ifdef F_GET_FILE_RW_HINT 241 case F_GET_FILE_RW_HINT:
242 case F_SET_FILE_RW_HINT:
244 arg_p = va_arg(val,
void *);
245 if ((ret = tas_fcntl(sockfd, cmd, arg_p)) == -1 && errno == EBADF) {
247 ret = libc_fcntl64(sockfd, cmd, arg_p);
249 ret = libc_fcntl(sockfd, cmd, arg_p);
255 fprintf(stderr,
"tas fcntl wrapper: unsupported cmd (%u)\n", cmd);
265 int fcntl(
int sockfd,
int cmd, ...)
272 ret = vfcntl(sockfd, cmd, val, 0);
278 int fcntl64(
int sockfd,
int cmd, ...)
285 ret = vfcntl(sockfd, cmd, val, 1);
291 int getsockopt(
int sockfd,
int level,
int optname,
void *optval,
296 if ((ret = tas_getsockopt(sockfd, level, optname, optval, optlen)) == -1 &&
299 return libc_getsockopt(sockfd, level, optname, optval, optlen);
304 int setsockopt(
int sockfd,
int level,
int optname,
const void *optval,
309 if ((ret = tas_setsockopt(sockfd, level, optname, optval, optlen)) == -1 &&
312 return libc_setsockopt(sockfd, level, optname, optval, optlen);
317 int getsockname(
int sockfd,
struct sockaddr *addr, socklen_t *addrlen)
321 if ((ret = tas_getsockname(sockfd, addr, addrlen)) == -1 && errno == EBADF) {
322 return libc_getsockname(sockfd, addr, addrlen);
327 int getpeername(
int sockfd,
struct sockaddr *addr, socklen_t *addrlen)
331 if ((ret = tas_getpeername(sockfd, addr, addrlen)) == -1 && errno == EBADF) {
332 return libc_getpeername(sockfd, addr, addrlen);
337 ssize_t read(
int sockfd,
void *buf,
size_t count)
341 if ((ret = tas_read(sockfd, buf, count)) == -1 && errno == EBADF) {
342 return libc_read(sockfd, buf, count);
347 ssize_t recv(
int sockfd,
void *buf,
size_t len,
int flags)
351 if ((ret = tas_recv(sockfd, buf, len, flags)) == -1 && errno == EBADF) {
352 return libc_recv(sockfd, buf, len, flags);
357 ssize_t recvfrom(
int sockfd,
void *buf,
size_t len,
int flags,
358 struct sockaddr *src_addr, socklen_t *addrlen)
362 if ((ret = tas_recvfrom(sockfd, buf, len, flags, src_addr, addrlen)) == -1 &&
365 return libc_recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
370 ssize_t recvmsg(
int sockfd,
struct msghdr *msg,
int flags)
374 if ((ret = tas_recvmsg(sockfd, msg, flags)) == -1 && errno == EBADF) {
375 return libc_recvmsg(sockfd, msg, flags);
380 ssize_t readv(
int sockfd,
const struct iovec *iov,
int iovcnt)
384 if ((ret = tas_readv(sockfd, iov, iovcnt)) == -1 && errno == EBADF) {
385 return libc_readv(sockfd, iov, iovcnt);
390 ssize_t pread(
int sockfd,
void *buf,
size_t count, off_t offset)
394 if ((ret = tas_pread(sockfd, buf, count, offset)) == -1 && errno == EBADF) {
395 return libc_pread(sockfd, buf, count, offset);
400 ssize_t write(
int sockfd,
const void *buf,
size_t count)
404 if ((ret = tas_write(sockfd, buf, count)) == -1 && errno == EBADF) {
405 return libc_write(sockfd, buf, count);
410 ssize_t send(
int sockfd,
const void *buf,
size_t len,
int flags)
414 if ((ret = tas_send(sockfd, buf, len, flags)) == -1 && errno == EBADF) {
415 return libc_send(sockfd, buf, len, flags);
420 ssize_t sendto(
int sockfd,
const void *buf,
size_t len,
int flags,
421 const struct sockaddr *dest_addr, socklen_t addrlen)
425 if ((ret = tas_sendto(sockfd, buf, len, flags, dest_addr, addrlen)) == -1 &&
428 return libc_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
433 ssize_t sendmsg(
int sockfd,
const struct msghdr *msg,
int flags)
437 if ((ret = tas_sendmsg(sockfd, msg, flags)) == -1 && errno == EBADF) {
438 return libc_sendmsg(sockfd, msg, flags);
443 ssize_t writev(
int sockfd,
const struct iovec *iov,
int iovcnt)
447 if ((ret = tas_writev(sockfd, iov, iovcnt)) == -1 && errno == EBADF) {
448 return libc_writev(sockfd, iov, iovcnt);
453 ssize_t pwrite(
int sockfd,
const void *buf,
size_t count, off_t offset)
457 if ((ret = tas_pwrite(sockfd, buf, count, offset)) == -1 && errno == EBADF) {
458 return libc_pwrite(sockfd, buf, count, offset);
463 ssize_t sendfile(
int sockfd,
int in_fd, off_t *offset,
size_t len)
467 if ((ret = tas_sendfile(sockfd, in_fd, offset, len)) == -1 && errno == EBADF) {
468 return libc_sendfile(sockfd, in_fd, offset, len);
473 int select(
int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
477 return tas_select(nfds, readfds, writefds, exceptfds, timeout);
480 int pselect(
int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
481 const struct timespec *
timeout,
const sigset_t *sigmask)
484 return tas_pselect(nfds, readfds, writefds, exceptfds, timeout, sigmask);
487 int epoll_create(
int size)
490 return tas_epoll_create(size);
493 int epoll_create1(
int flags)
496 return tas_epoll_create1(flags);
499 int epoll_ctl(
int epfd,
int op,
int fd,
struct epoll_event *event)
502 return tas_epoll_ctl(epfd, op, fd, event);
505 int epoll_wait(
int epfd,
struct epoll_event *events,
int maxevents,
509 return tas_epoll_wait(epfd, events, maxevents, timeout);
512 int epoll_pwait(
int epfd,
struct epoll_event *events,
int maxevents,
513 int timeout,
const sigset_t *sigmask)
516 return tas_epoll_pwait(epfd, events, maxevents, timeout, sigmask);
519 int poll(
struct pollfd *fds, nfds_t nfds,
int timeout)
522 return tas_poll(fds, nfds, timeout);
525 int ppoll(
struct pollfd *fds, nfds_t nfds,
const struct timespec *tmo_p,
526 const sigset_t *sigmask)
529 return tas_ppoll(fds, nfds, tmo_p, sigmask);
534 return tas_dup(oldfd);
537 int dup2(
int oldfd,
int newfd)
539 return tas_dup2(oldfd, newfd);
542 int dup3(
int oldfd,
int newfd,
int flags)
544 return tas_dup3(oldfd, newfd, flags);
552 long syscall(
long number, ...)
556 long arg1, arg2, arg3, arg4, arg5, arg6;
561 va_start(val, number);
562 arg1 = va_arg(val,
long);
563 arg2 = va_arg(val,
long);
564 arg3 = va_arg(val,
long);
565 arg4 = va_arg(val,
long);
566 arg5 = va_arg(val,
long);
567 arg6 = va_arg(val,
long);
572 return socket((
int) arg1, (
int) arg2, (
int) arg3);
574 return close((
int) arg1);
576 return shutdown((
int) arg1, (
int) arg2);
578 return bind((
int) arg1, (
const struct sockaddr *) (uintptr_t) arg2,
581 return connect((
int) arg1, (
const struct sockaddr *) (uintptr_t) arg2,
584 return listen((
int) arg1, (
int) arg2);
586 return accept4((
int) arg1, (
struct sockaddr *) (uintptr_t) arg2,
587 (socklen_t *) (uintptr_t) arg3, (
int) arg4);
589 return accept((
int) arg1, (
struct sockaddr *) (uintptr_t) arg2,
590 (socklen_t *) (uintptr_t) arg3);
592 va_start(val, number);
593 (void) va_arg(val,
long);
594 (void) va_arg(val,
long);
595 ret = vfcntl((
int) arg1, (
int) arg2, val, 0);
600 va_start(val, number);
601 (void) va_arg(val,
long);
602 (void) va_arg(val,
long);
603 ret = vfcntl((
int) arg1, (
int) arg2, val, 1);
608 return getsockopt((
int) arg1, (
int) arg2, (
int) arg3,
609 (
void *) (uintptr_t) arg4, (socklen_t *) (uintptr_t) arg5);
611 return setsockopt((
int) arg1, (
int) arg2, (
int) arg3,
612 (
const void *) (uintptr_t) arg4, (socklen_t) arg5);
613 case SYS_getsockname:
614 return getsockname((
int) arg1, (
struct sockaddr *) (uintptr_t) arg2,
615 (socklen_t *) (uintptr_t) arg3);
616 case SYS_getpeername:
617 return getpeername((
int) arg1, (
struct sockaddr *) (uintptr_t) arg2,
618 (socklen_t *) (uintptr_t) arg3);
621 return read((
int) arg1, (
void *) (uintptr_t) arg2, (
size_t) arg3);
624 return recv((
int) arg1, (
void *) (uintptr_t) arg2, (
size_t) arg3,
628 return recvfrom((
int) arg1, (
void *) (uintptr_t) arg2, (
size_t) arg3,
629 (
int) arg4, (
struct sockaddr *) (uintptr_t) arg5,
630 (socklen_t *) (uintptr_t) arg6);
632 return recvmsg((
int) arg1, (
struct msghdr *) (uintptr_t) arg2,
635 return readv((
int) arg1, (
struct iovec *) (uintptr_t) arg2,
638 return pread((
int) arg1, (
void *) (uintptr_t) arg2, (
size_t) arg3,
642 return write((
int) arg1, (
const void *) (uintptr_t) arg2, (
size_t) arg3);
645 return send((
int) arg1, (
const void *) (uintptr_t) arg2, (
size_t) arg3,
649 return sendto((
int) arg1,(
const void *) (uintptr_t) arg2, (
size_t) arg3,
650 (
int) arg4, (
const struct sockaddr *) (uintptr_t) arg5,
653 return sendmsg((
int) arg1, (
const struct msghdr *) (uintptr_t) arg2,
656 return writev((
int) arg1, (
const struct iovec *) (uintptr_t) arg2,
659 return pwrite((
int) arg1, (
const void *) (uintptr_t) arg2, (
size_t) arg3,
662 return sendfile((
int) arg1, (
int) arg2, (off_t *) (uintptr_t) arg3,
666 return select((
int) arg1, (fd_set *) (uintptr_t) arg2,
667 (fd_set *) (uintptr_t) arg3, (fd_set *) (uintptr_t) arg4,
668 (
struct timeval *) (uintptr_t) arg5);
670 fprintf(stderr,
"tas syscall(): warning our pselect6 does not update " 672 return pselect((
int) arg1, (fd_set *) (uintptr_t) arg2,
673 (fd_set *) (uintptr_t) arg3, (fd_set *) (uintptr_t) arg4,
674 (
struct timespec *) (uintptr_t) arg5,
675 (
const sigset_t *) (uintptr_t) arg6);
676 case SYS_epoll_create:
677 return epoll_create((
int) arg1);
678 case SYS_epoll_create1:
679 return epoll_create1((
int) arg1);
681 return epoll_ctl((
int) arg1, (
int) arg2, (
int) arg3,
682 (
struct epoll_event *) (uintptr_t) arg4);
684 return epoll_wait((
int) arg1, (
struct epoll_event *) (uintptr_t) arg2,
685 (
int) arg3, (
int) arg4);
686 case SYS_epoll_pwait:
687 return epoll_pwait((
int) arg1, (
struct epoll_event *) (uintptr_t) arg2,
688 (
int) arg3, (
int) arg4, (
const sigset_t *) (uintptr_t) arg5);
690 return poll((
struct pollfd *) (uintptr_t) arg1, (nfds_t) arg2,
693 return ppoll((
struct pollfd *) (uintptr_t) arg1, (nfds_t) arg2,
694 (
const struct timespec *) (uintptr_t) arg3,
695 (
const sigset_t *) (uintptr_t) arg4);
698 return dup((
int) arg1);
700 return dup2((
int) arg1, (
int) arg2);
702 return dup3((
int) arg1, (
int) arg2, (
int) arg3);
705 return libc_syscall(number, arg1, arg2, arg3, arg4, arg5, arg6);
711 static void *bind_symbol(
const char *sym)
714 if ((ptr = dlsym(RTLD_NEXT, sym)) == NULL) {
715 fprintf(stderr,
"flextcp socket interpose: dlsym failed (%s)\n", sym);
721 static void init(
void)
723 libc_socket = bind_symbol(
"socket");
724 libc_close = bind_symbol(
"close");
725 libc_shutdown = bind_symbol(
"shutdown");
726 libc_bind = bind_symbol(
"bind");
727 libc_connect = bind_symbol(
"connect");
728 libc_listen = bind_symbol(
"listen");
729 libc_accept4 = bind_symbol(
"accept4");
730 libc_accept = bind_symbol(
"accept");
731 libc_fcntl = bind_symbol(
"fcntl");
733 libc_fcntl64 = dlsym(RTLD_NEXT,
"fcntl64");
734 if (libc_fcntl64 == NULL)
735 libc_fcntl64 = libc_fcntl;
737 libc_getsockopt = bind_symbol(
"getsockopt");
738 libc_setsockopt = bind_symbol(
"setsockopt");
739 libc_getsockname = bind_symbol(
"getsockname");
740 libc_getpeername = bind_symbol(
"getpeername");
741 libc_read = bind_symbol(
"read");
742 libc_recv = bind_symbol(
"recv");
743 libc_recvfrom = bind_symbol(
"recvfrom");
744 libc_recvmsg = bind_symbol(
"recvmsg");
745 libc_readv = bind_symbol(
"readv");
746 libc_pread = bind_symbol(
"pread");
747 libc_write = bind_symbol(
"write");
748 libc_send = bind_symbol(
"send");
749 libc_sendto = bind_symbol(
"sendto");
750 libc_sendmsg = bind_symbol(
"sendmsg");
751 libc_writev = bind_symbol(
"writev");
752 libc_pwrite = bind_symbol(
"pwrite");
753 libc_sendfile = bind_symbol(
"sendfile");
754 libc_syscall = bind_symbol(
"syscall");
756 if (tas_init() != 0) {
761 static inline void ensure_init(
void)
763 static volatile uint32_t init_cnt = 0;
764 static volatile uint8_t init_done = 0;
765 static __thread uint8_t in_init = 0;
767 if (init_done == 0) {
774 if (__sync_fetch_and_add(&init_cnt, 1) == 0) {
781 while (init_done == 0) {
int tas_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)