From 4a3247534d4c741e9408eeb6dc98a1cab86cd174 Mon Sep 17 00:00:00 2001 From: mbuhl Date: Fri, 9 Sep 2022 13:52:59 +0000 Subject: [PATCH] Add libc wrappers for the new sendmmsg and recvmmsg system calls. Feedback tb@, miod@, jca@ OK jca@ --- lib/libc/Symbols.list | 4 ++ lib/libc/hidden/sys/socket.h | 4 +- lib/libc/shlib_version | 2 +- lib/libc/sys/Makefile.inc | 6 +- lib/libc/sys/recv.2 | 117 +++++++++++++++++++++++++++-------- lib/libc/sys/send.2 | 36 ++++++++--- lib/libc/sys/w_recvmmsg.c | 32 ++++++++++ lib/libc/sys/w_sendmmsg.c | 31 ++++++++++ lib/librthread/shlib_version | 2 +- 9 files changed, 193 insertions(+), 41 deletions(-) create mode 100644 lib/libc/sys/w_recvmmsg.c create mode 100644 lib/libc/sys/w_sendmmsg.c diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list index a9549c18e29..3096857ca39 100644 --- a/lib/libc/Symbols.list +++ b/lib/libc/Symbols.list @@ -175,6 +175,7 @@ _thread_sys_readlinkat _thread_sys_readv _thread_sys_reboot _thread_sys_recvfrom +_thread_sys_recvmmsg _thread_sys_recvmsg _thread_sys_rename _thread_sys_renameat @@ -184,6 +185,7 @@ _thread_sys_sched_yield _thread_sys_select _thread_sys_semget _thread_sys_semop +_thread_sys_sendmmsg _thread_sys_sendmsg _thread_sys_sendsyslog _thread_sys_sendto @@ -372,6 +374,7 @@ readlinkat readv reboot recvfrom +recvmmsg recvmsg rename renameat @@ -383,6 +386,7 @@ select semctl semget semop +sendmmsg sendmsg sendsyslog sendto diff --git a/lib/libc/hidden/sys/socket.h b/lib/libc/hidden/sys/socket.h index 2d8b3e4f120..1f45d4f4a3f 100644 --- a/lib/libc/hidden/sys/socket.h +++ b/lib/libc/hidden/sys/socket.h @@ -1,4 +1,4 @@ -/* $OpenBSD: socket.h,v 1.4 2016/05/07 19:05:22 guenther Exp $ */ +/* $OpenBSD: socket.h,v 1.5 2022/09/09 13:52:59 mbuhl Exp $ */ /* * Copyright (c) 2015 Philip Guenther * @@ -32,8 +32,10 @@ PROTO_NORMAL(getsockopt); PROTO_NORMAL(listen); PROTO_NORMAL(recv); PROTO_CANCEL(recvfrom); +PROTO_CANCEL(recvmmsg); PROTO_CANCEL(recvmsg); PROTO_NORMAL(send); +PROTO_CANCEL(sendmmsg); PROTO_CANCEL(sendmsg); PROTO_CANCEL(sendto); PROTO_NORMAL(setrtable); diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 5fb0770494f..03589a3f97f 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ major=96 -minor=1 +minor=2 # note: If changes were made to include/thread_private.h or if system calls # were added/changed then librthread/shlib_version must also be updated. diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index b9cae5f77af..50c4af6156b 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.163 2022/07/17 03:04:27 deraadt Exp $ +# $OpenBSD: Makefile.inc,v 1.164 2022/09/09 13:52:59 mbuhl Exp $ # $NetBSD: Makefile.inc,v 1.35 1995/10/16 23:49:07 jtc Exp $ # @(#)Makefile.inc 8.1 (Berkeley) 6/17/93 @@ -34,8 +34,8 @@ CANCEL= accept accept4 \ nanosleep \ open openat \ poll ppoll pread preadv pselect pwrite pwritev \ - read readv recvfrom recvmsg \ - select sendmsg sendto \ + read readv recvfrom recvmmsg recvmsg \ + select sendmmsg sendmsg sendto \ wait4 write writev SRCS+= ${CANCEL:%=w_%.c} diff --git a/lib/libc/sys/recv.2 b/lib/libc/sys/recv.2 index 9d327e9723e..2e548707d69 100644 --- a/lib/libc/sys/recv.2 +++ b/lib/libc/sys/recv.2 @@ -1,4 +1,4 @@ -.\" $OpenBSD: recv.2,v 1.48 2021/11/21 23:44:55 jan Exp $ +.\" $OpenBSD: recv.2,v 1.49 2022/09/09 13:52:59 mbuhl Exp $ .\" $NetBSD: recv.2,v 1.6 1995/02/27 12:36:08 cgd Exp $ .\" .\" Copyright (c) 1983, 1990, 1991, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)recv.2 8.3 (Berkeley) 2/21/94 .\" -.Dd $Mdocdate: November 21 2021 $ +.Dd $Mdocdate: September 9 2022 $ .Dt RECV 2 .Os .Sh NAME @@ -46,15 +46,35 @@ .Fn recvfrom "int s" "void *buf" "size_t len" "int flags" "struct sockaddr *from" "socklen_t *fromlen" .Ft ssize_t .Fn recvmsg "int s" "struct msghdr *msg" "int flags" +.Ft int +.Fn recvmmsg "int s" "struct mmsghdr *mmsg" "unsigned int vlen" "int flags" "struct timespec *timeout" .Sh DESCRIPTION -.Fn recvfrom +.Fn recv , +.Fn recvfrom , +.Fn recvmsg , and -.Fn recvmsg +.Fn recvmmsg are used to receive messages from a socket, -.Fa s , -and may be used to receive +.Fa s . +.Fn recv +is normally used only on a +.Em connected +socket (see +.Xr connect 2 ). +.Fn recvfrom , +.Fn recvmsg , +and +.Fn recvmmsg +may be used to receive data on a socket whether or not it is connection-oriented. .Pp +.Fn recv +is identical to +.Fn recvfrom +with a null +.Fa from +parameter. +.Pp If .Fa from is non-null and the socket is not connection-oriented, @@ -66,25 +86,6 @@ the buffer associated with and modified on return to indicate the actual size of the address stored there. .Pp -The -.Fn recv -call is normally used only on a -.Em connected -socket (see -.Xr connect 2 ) -and is identical to -.Fn recvfrom -with a null -.Fa from -parameter. -.Pp -On successful completion, all three routines return the number of -message bytes read. -If a message is too long to fit in the supplied -buffer, excess bytes may be discarded depending on the type of socket -the message is received from (see -.Xr socket 2 ) . -.Pp If no messages are available at the socket, the receive call waits for a message to arrive, unless the socket is nonblocking (see @@ -158,6 +159,8 @@ The .Dv MSG_CMSG_CLOEXEC requests that any file descriptors received as ancillary data with .Fn recvmsg +and +.Fn recvmmsg (see below) have their close-on-exec flag set. .Pp @@ -249,13 +252,67 @@ Indicates that the packet was received as broadcast. .It Dv MSG_MCAST Indicates that the packet was received as multicast. .El +.Pp +The +.Fn recvmmsg +call uses an array of the +.Fa mmsghdr +structure of length +.Fa vlen +to group multiple +.Fa msghdr +structures into a single system call. +.Fa vlen +is capped at maximum +.Dv 1024 +messages that are received in a single call. +The +.Fa flags +field allows setting +.Dv MSG_WAITFORONE +to wait for one +.Fa msghdr , +and set +.Dv MSG_DONTWAIT +for all subsequent messages. +A provided +.Fa timeout +limits the time spent in the function but it does not limit the +time spent in lower parts of the kernel. +.Pp +The +.Fa mmsghdr +structure has the following form, as defined in +.In sys/socket.h : +.Bd -literal +struct mmsghdr { + struct msghdr msg_hdr; + unsigned int msg_len; +}; +.Ed +.Pp +Here +.Fa msg_len +indicated the number of bytes received for each +.Fa msg_hdr +member. .Sh RETURN VALUES -These calls return the number of bytes received, or \-1 if an error occurred. -.Sh ERRORS +The .Fn recv , .Fn recvfrom , and .Fn recvmsg +calls return the number of bytes received, or \-1 if an error occurred. +The +.Fn recvmmsg +call returns the number of messages received, or \-1 +if an error occurred before the first message has been received. +.Sh ERRORS +.Fn recv , +.Fn recvfrom , +.Fn recvmsg , +and +.Fn recvmmsg fail if: .Bl -tag -width "[EHOSTUNREACH]" .It Bq Er EBADF @@ -310,6 +367,8 @@ was larger than .Pp And .Fn recvmsg +and +.Fn recvmmsg may return one of the following errors: .Bl -tag -width Er .It Bq Er EINVAL @@ -364,6 +423,10 @@ The .Fn recv function call appeared in .Bx 4.1c . +The +.Fn recvmmsg +syscall first appeared in Linux 2.6.33 and was added to +.Ox 7.2 . .Sh CAVEATS Calling .Fn recvmsg diff --git a/lib/libc/sys/send.2 b/lib/libc/sys/send.2 index e3e1077d390..960df1d1670 100644 --- a/lib/libc/sys/send.2 +++ b/lib/libc/sys/send.2 @@ -1,4 +1,4 @@ -.\" $OpenBSD: send.2,v 1.34 2019/01/11 06:10:13 jsg Exp $ +.\" $OpenBSD: send.2,v 1.35 2022/09/09 13:52:59 mbuhl Exp $ .\" $NetBSD: send.2,v 1.6 1996/01/15 01:17:18 thorpej Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 @@ -30,13 +30,14 @@ .\" .\" @(#)send.2 8.2 (Berkeley) 2/21/94 .\" -.Dd $Mdocdate: January 11 2019 $ +.Dd $Mdocdate: September 9 2022 $ .Dt SEND 2 .Os .Sh NAME .Nm send , .Nm sendto , -.Nm sendmsg +.Nm sendmsg , +.Nm sendmmsg .Nd send a message from a socket .Sh SYNOPSIS .In sys/socket.h @@ -46,19 +47,23 @@ .Fn sendto "int s" "const void *msg" "size_t len" "int flags" "const struct sockaddr *to" "socklen_t tolen" .Ft ssize_t .Fn sendmsg "int s" "const struct msghdr *msg" "int flags" +.Ft int +.Fn sendmmsg "int s" "const struct mmsghdr *mmsg" "unsigned int vlen" "int flags" .Sh DESCRIPTION .Fn send , .Fn sendto , +.Fn sendmsg , and -.Fn sendmsg +.Fn sendmmsg are used to transmit a message to another socket. .Fn send may be used only when the socket is in a .Em connected state, while -.Fn sendto +.Fn sendto , +.Fn sendmsg , and -.Fn sendmsg +.Fn sendmmsg may be used at any time. .Pp The address of the target is given by @@ -127,10 +132,21 @@ See .Xr recv 2 for a description of the .Fa msghdr -structure. +and +.Fa mmsghdr +structures. .Sh RETURN VALUES -The call returns the number of characters sent, or \-1 +The +.Fn send , +.Fn sendto , +and +.Fn sendmsg +calls return the number of characters sent, or \-1 if an error occurred. +The +.Fn sendmmsg +call returns the number of messages sent, or \-1 +if an error occurred before the first message has been sent. .Sh ERRORS .Fn send , .Fn sendto , @@ -267,3 +283,7 @@ The .Fn send function call appeared in .Bx 4.1c . +The +.Fn sendmmsg +syscall first appeared in Linux 3.0 and was added to +.Ox 7.2 . diff --git a/lib/libc/sys/w_recvmmsg.c b/lib/libc/sys/w_recvmmsg.c new file mode 100644 index 00000000000..e274c04dc16 --- /dev/null +++ b/lib/libc/sys/w_recvmmsg.c @@ -0,0 +1,32 @@ +/* $OpenBSD: w_recvmmsg.c,v 1.1 2022/09/09 13:52:59 mbuhl Exp $ */ +/* + * Copyright (c) 2022 Moritz Buhl + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include "cancel.h" + +int +recvmmsg(int fd, struct mmsghdr *mmsg, unsigned int vlen, int flags, + struct timespec *ts) +{ + int ret; + + ENTER_CANCEL_POINT(1); + ret = HIDDEN(recvmmsg)(fd, mmsg, vlen, flags, ts); + LEAVE_CANCEL_POINT(ret == -1); + return (ret); +} +DEF_CANCEL(recvmmsg); diff --git a/lib/libc/sys/w_sendmmsg.c b/lib/libc/sys/w_sendmmsg.c new file mode 100644 index 00000000000..132ba2c7f7f --- /dev/null +++ b/lib/libc/sys/w_sendmmsg.c @@ -0,0 +1,31 @@ +/* $OpenBSD: w_sendmmsg.c,v 1.1 2022/09/09 13:53:00 mbuhl Exp $ */ +/* + * Copyright (c) 2022 Moritz Buhl + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include "cancel.h" + +int +sendmmsg(int s, struct mmsghdr *mmsg, unsigned int vlen, int flags) +{ + int ret; + + ENTER_CANCEL_POINT(1); + ret = HIDDEN(sendmmsg)(s, mmsg, vlen, flags); + LEAVE_CANCEL_POINT(ret <= 0); + return (ret); +} +DEF_CANCEL(sendmmsg); diff --git a/lib/librthread/shlib_version b/lib/librthread/shlib_version index 72168dfd16a..34aa186fe47 100644 --- a/lib/librthread/shlib_version +++ b/lib/librthread/shlib_version @@ -1,2 +1,2 @@ major=26 -minor=1 +minor=2 -- 2.20.1