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

Reply via email to