Merge branch 'dev' into dev

This commit is contained in:
johnjiang 2025-04-23 14:55:53 +08:00 committed by GitHub
commit 01e6d334e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 112 additions and 5 deletions

View File

@ -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,62 @@ 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->flags = flags;
}
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

View File

@ -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

View File

@ -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);

View File

@ -21,6 +21,7 @@ ff_fcntl
ff_socketpair
ff_poll
ff_accept
ff_accept4
ff_listen
ff_bind
ff_connect

View File

@ -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 @@ kern_fail:
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)
{