From e3766b423ee3f6e37bd2896a44b723025edf2715 Mon Sep 17 00:00:00 2001 From: liujinhui-job <17839916631@163.com> Date: Mon, 31 Mar 2025 09:48:27 +0000 Subject: [PATCH 1/2] add accept4 support, and LINUX_SOCK_CLOEXEC/LINUX_SOCK_NONBLOCK support for ff_socket --- adapter/syscall/ff_hook_syscall.c | 58 +++++++++++++++++++++++++++++-- adapter/syscall/ff_socket_ops.c | 3 +- lib/ff_api.h | 1 + lib/ff_api.symlist | 1 + lib/ff_syscall_wrapper.c | 53 +++++++++++++++++++++++++++- 5 files changed, 111 insertions(+), 5 deletions(-) diff --git a/adapter/syscall/ff_hook_syscall.c b/adapter/syscall/ff_hook_syscall.c index ac60b5167..0553d95dd 100644 --- a/adapter/syscall/ff_hook_syscall.c +++ b/adapter/syscall/ff_hook_syscall.c @@ -66,6 +66,7 @@ static __thread struct ff_getsockname_args *getsockname_args = NULL; static __thread struct ff_getpeername_args *getpeername_args = NULL; static __thread struct ff_setsockopt_args *setsockopt_args = NULL; static __thread struct ff_accept_args *accept_args = NULL; +static __thread struct ff_accept4_args *accept4_args = NULL; static __thread struct ff_connect_args *connect_args = NULL; static __thread struct ff_recvfrom_args *recvfrom_args = NULL; static __thread struct ff_recvmsg_args *recvmsg_args = NULL; @@ -680,8 +681,61 @@ ff_hook_accept4(int fd, struct sockaddr *addr, CHECK_FD_OWNERSHIP(accept4, (fd, addr, addrlen, flags)); - errno = ENOSYS; - return -1; + DEFINE_REQ_ARGS_STATIC(accept4); + static __thread struct sockaddr *sh_addr = NULL; + static __thread socklen_t sh_addr_len = 0; + static __thread socklen_t *sh_addrlen = NULL; + + if (addr != NULL) { + if (sh_addr == NULL || sh_addr_len < *addrlen) { + if(sh_addr) { + share_mem_free(sh_addr); + } + + sh_addr_len = *addrlen; + sh_addr = share_mem_alloc(sh_addr_len); + if (sh_addr == NULL) { + RETURN_ERROR_NOFREE(ENOMEM); + } + } + + if (sh_addrlen == NULL) { + sh_addrlen = share_mem_alloc(sizeof(socklen_t)); + if (sh_addrlen == NULL) { + //share_mem_free(sh_addr); // Don't free + RETURN_ERROR_NOFREE(ENOMEM); + } + } + *sh_addrlen = *addrlen; + + args->addr = sh_addr; + args->addrlen = sh_addrlen; + args->flags = flags; + }else { + args->addr = NULL; + args->addrlen = NULL; + } + + args->fd = fd; + + SYSCALL(FF_SO_ACCEPT4, args); + + if (ret > 0) { + ret = convert_fstack_fd(ret); + } + + if (addr) { + if (ret > 0) { + socklen_t cplen = *sh_addrlen > *addrlen ? + *addrlen : *sh_addrlen; + rte_memcpy(addr, sh_addr, cplen); + *addrlen = *sh_addrlen; + } + //share_mem_free(sh_addr); // Don't free + //share_mem_free(sh_addrlen); + } + + RETURN_NOFREE(); } int diff --git a/adapter/syscall/ff_socket_ops.c b/adapter/syscall/ff_socket_ops.c index b2501b4f9..c45ad5667 100644 --- a/adapter/syscall/ff_socket_ops.c +++ b/adapter/syscall/ff_socket_ops.c @@ -186,8 +186,7 @@ ff_sys_accept(struct ff_accept_args *args) static int ff_sys_accept4(struct ff_accept4_args *args) { - errno = ENOSYS; - return -1; + return ff_accept4(args->fd, args->addr, args->addrlen, args->flags); } static int diff --git a/lib/ff_api.h b/lib/ff_api.h index c4853042e..a6138e67f 100644 --- a/lib/ff_api.h +++ b/lib/ff_api.h @@ -88,6 +88,7 @@ int ff_getsockopt(int s, int level, int optname, void *optval, int ff_listen(int s, int backlog); int ff_bind(int s, const struct linux_sockaddr *addr, socklen_t addrlen); int ff_accept(int s, struct linux_sockaddr *addr, socklen_t *addrlen); +int ff_accept4(int s, struct linux_sockaddr *addr, socklen_t *addrlen, int flags); int ff_connect(int s, const struct linux_sockaddr *name, socklen_t namelen); int ff_close(int fd); int ff_shutdown(int s, int how); diff --git a/lib/ff_api.symlist b/lib/ff_api.symlist index f42113d7b..c5aeda3b6 100755 --- a/lib/ff_api.symlist +++ b/lib/ff_api.symlist @@ -21,6 +21,7 @@ ff_fcntl ff_socketpair ff_poll ff_accept +ff_accept4 ff_listen ff_bind ff_connect diff --git a/lib/ff_syscall_wrapper.c b/lib/ff_syscall_wrapper.c index 0c99d2f64..30d9ca017 100644 --- a/lib/ff_syscall_wrapper.c +++ b/lib/ff_syscall_wrapper.c @@ -208,6 +208,11 @@ /* af define end */ +/* Flags for socket, socketpair, accept4 */ + +#define LINUX_SOCK_CLOEXEC LINUX_O_CLOEXEC +#define LINUX_SOCK_NONBLOCK LINUX_O_NONBLOCK + /* msghdr define start */ static /*__thread*/ struct iovec msg_iov_tmp[UIO_MAXIOV]; @@ -655,6 +660,20 @@ linux2freebsd_opt(int level, int optname) } } +static int +linux2freebsd_socket_flags(int flags) +{ + if (flags & LINUX_SOCK_NONBLOCK) { + flags &= ~LINUX_SOCK_NONBLOCK; + flags |= SOCK_NONBLOCK; + } + if (flags & LINUX_SOCK_CLOEXEC) { + flags &= ~LINUX_SOCK_CLOEXEC; + flags |= SOCK_CLOEXEC; + } + return flags; +} + static void linux2freebsd_sockaddr(const struct linux_sockaddr *linux, socklen_t addrlen, struct sockaddr *freebsd) @@ -880,7 +899,7 @@ ff_socket(int domain, int type, int protocol) int rc; struct socket_args sa; sa.domain = domain == LINUX_AF_INET6 ? AF_INET6 : domain; - sa.type = type; + sa.type = linux2freebsd_socket_flags(type); sa.protocol = protocol; if ((rc = sys_socket(curthread, &sa))) goto kern_fail; @@ -1352,6 +1371,38 @@ ff_accept(int s, struct linux_sockaddr * addr, return (-1); } +int +ff_accept4(int s, struct linux_sockaddr * addr, + socklen_t * addrlen, int flags) +{ + int rc; + struct file *fp; + struct sockaddr *pf = NULL; + socklen_t socklen = sizeof(struct sockaddr_storage); + + if ((rc = kern_accept4(curthread, s, &pf, &socklen, linux2freebsd_socket_flags(flags), &fp))) + goto kern_fail; + + rc = curthread->td_retval[0]; + fdrop(fp, curthread); + + if (addr && pf) + freebsd2linux_sockaddr(addr, pf); + + if (addrlen) + *addrlen = pf->sa_len; + + if(pf != NULL) + free(pf, M_SONAME); + return (rc); + +kern_fail: + if(pf != NULL) + free(pf, M_SONAME); + ff_os_errno(rc); + return (-1); +} + int ff_listen(int s, int backlog) { From 753fdb9f3709cd481cc8705f9e3a18fe4604ef49 Mon Sep 17 00:00:00 2001 From: liujinhui-job <17839916631@163.com> Date: Tue, 1 Apr 2025 11:04:26 +0800 Subject: [PATCH 2/2] Update ff_hook_syscall.c --- adapter/syscall/ff_hook_syscall.c | 1 + 1 file changed, 1 insertion(+) diff --git a/adapter/syscall/ff_hook_syscall.c b/adapter/syscall/ff_hook_syscall.c index 0553d95dd..5c2f596d9 100644 --- a/adapter/syscall/ff_hook_syscall.c +++ b/adapter/syscall/ff_hook_syscall.c @@ -714,6 +714,7 @@ ff_hook_accept4(int fd, struct sockaddr *addr, }else { args->addr = NULL; args->addrlen = NULL; + args->flags = flags; } args->fd = fd;