Here is an updated version of the kernel part for sendmmsg.
mbuhl
Index: sys/kern/syscalls.master
===================================================================
RCS file: /mount/openbsd/cvs/src/sys/kern/syscalls.master,v
retrieving revision 1.230
diff -u -p -r1.230 syscalls.master
--- sys/kern/syscalls.master 2 Sep 2022 13:18:06 -0000 1.230
+++ sys/kern/syscalls.master 2 Sep 2022 20:34:15 -0000
@@ -247,7 +247,9 @@
116 STD NOLOCK { int sys_recvmmsg(int s, struct mmsghdr *mmsg, \
unsigned int vlen, unsigned int flags, \
struct timespec *timeout); }
-117 UNIMPL sendmmsg
+117 STD NOLOCK { int sys_sendmmsg(int s, \
+ struct mmsghdr *mmsg, unsigned int vlen, \
+ unsigned int flags); }
118 STD { int sys_getsockopt(int s, int level, int name, \
void *val, socklen_t *avalsize); }
119 STD { int sys_thrkill(pid_t tid, int signum, void *tcb); }
Index: sys/kern/uipc_syscalls.c
===================================================================
RCS file: /mount/openbsd/cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.202
diff -u -p -r1.202 uipc_syscalls.c
--- sys/kern/uipc_syscalls.c 2 Sep 2022 13:18:06 -0000 1.202
+++ sys/kern/uipc_syscalls.c 2 Sep 2022 23:26:08 -0000
@@ -606,6 +606,92 @@ done:
}
int
+sys_sendmmsg(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_sendmmsg_args /* {
+ syscallarg(int) s;
+ syscallarg(struct mmsghdr *) mmsg;
+ syscallarg(unsigned int) vlen;
+ syscallarg(unsigned int) flags;
+ } */ *uap = v;
+ struct mmsghdr mmsg, *mmsgp;
+ struct iovec aiov[UIO_SMALLIOV], *iov = aiov, *uiov;
+ size_t iovlen = UIO_SMALLIOV;
+ register_t retsnd;
+ unsigned int vlen, dgrams;
+ int error = 0;
+
+ /* Arbitrarily capped at 1024 datagrams. */
+ vlen = SCARG(uap, vlen);
+ if (vlen > 1024)
+ vlen = 1024;
+
+ mmsgp = SCARG(uap, mmsg);
+ for (dgrams = 0; dgrams < vlen; dgrams++) {
+ error = copyin(&mmsgp[dgrams], &mmsg, sizeof(mmsg));
+ if (error)
+ break;
+
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_STRUCT))
+ ktrmmsghdr(p, &mmsg);
+#endif
+
+ if (mmsg.msg_hdr.msg_iovlen > IOV_MAX) {
+ error = EMSGSIZE;
+ break;
+ }
+
+ if (mmsg.msg_hdr.msg_iovlen > iovlen) {
+ if (iov != aiov)
+ free(iov, M_IOV, iovlen *
+ sizeof(struct iovec));
+
+ iovlen = mmsg.msg_hdr.msg_iovlen;
+ iov = mallocarray(iovlen, sizeof(struct iovec),
+ M_IOV, M_WAITOK);
+ }
+
+ if (mmsg.msg_hdr.msg_iovlen > 0) {
+ error = copyin(mmsg.msg_hdr.msg_iov, iov,
+ mmsg.msg_hdr.msg_iovlen * sizeof(struct iovec));
+ if (error)
+ break;
+ }
+
+#ifdef KTRACE
+ if (mmsg.msg_hdr.msg_iovlen && KTRPOINT(p, KTR_STRUCT))
+ ktriovec(p, iov, mmsg.msg_hdr.msg_iovlen);
+#endif
+
+ uiov = mmsg.msg_hdr.msg_iov;
+ mmsg.msg_hdr.msg_iov = iov;
+ mmsg.msg_hdr.msg_flags = 0;
+
+ error = sendit(p, SCARG(uap, s), &mmsg.msg_hdr,
+ SCARG(uap, flags), &retsnd);
+ if (error)
+ break;
+
+ mmsg.msg_hdr.msg_iov = uiov;
+ mmsg.msg_len = retsnd;
+
+ error = copyout(&mmsg, &mmsgp[dgrams], sizeof(mmsg));
+ if (error)
+ break;
+ }
+
+ if (iov != aiov)
+ free(iov, M_IOV, sizeof(struct iovec) * iovlen);
+
+ *retval = dgrams;
+
+ if (dgrams)
+ return 0;
+ return error;
+}
+
+int
sendit(struct proc *p, int s, struct msghdr *mp, int flags, register_t
*retsize)
{
struct file *fp;
Index: sys/sys/socket.h
===================================================================
RCS file: /mount/openbsd/cvs/src/sys/sys/socket.h,v
retrieving revision 1.103
diff -u -p -r1.103 socket.h
--- sys/sys/socket.h 2 Sep 2022 13:18:07 -0000 1.103
+++ sys/sys/socket.h 2 Sep 2022 22:31:09 -0000
@@ -579,6 +579,7 @@ ssize_t send(int, const void *, size_t,
ssize_t sendto(int, const void *,
size_t, int, const struct sockaddr *, socklen_t);
ssize_t sendmsg(int, const struct msghdr *, int);
+int sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int);
int setsockopt(int, int, int, const void *, socklen_t);
int shutdown(int, int);
int sockatmark(int);