NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: aligning control message ancillary data

   Date: Wed, 18 Jun 2008 01:42:10 +0200
   From: Martin Husemann <>

   FWIW, all three programs work on NetBSD/i386 -current too, none of them
   works on NetBSD/sparc64 -current. The whole CMSG interface is a mess and
   a very good example how to not design an API.

Indeed.  But it would be nice if at least the correct intent were

   For an example how to get all the alignement and length fields right
   look at mm_send_fd() in crypto/dist/ssh/monitor_fdpass.c in the NetBSD
   source tree.

I looked at that file in the netbsd-4 branch, and was reassured to see
the idiom I used in nb-test.c:

   struct msghdr msg;
   char tmp[CMSG_SPACE(sizeof(int))];
   struct cmsghdr *cmsg;
   /* ... */
   msg.msg_control = (caddr_t)tmp;
   msg.msg_controllen = CMSG_LEN(sizeof(int));
   cmsg = CMSG_FIRSTHDR(&msg);
   cmsg->cmsg_len = CMSG_LEN(sizeof(int));

But then I checked -current, and it changed dramatically!  Now it uses
nearly the union that stunnel uses, but looks rather clumsier:

   struct msghdr msg;
   union {
        struct cmsghdr hdr;
        char buf[1024]; /* Here stunnel uses CMSG_SPACE. */
   } cmsgbuf;
   struct cmsghdr *cmsg;
   /* ... */
   if (sizeof(cmsgbuf.buf) < CMSG_SPACE(sizeof(int))) {
        error("%s: %zu < %zu, recompile", __func__,
                sizeof(cmsgbuf.buf), CMSG_SPACE(sizeof(int)));
        return -1;
   /* ... */
   msg.msg_control = &cmsgbuf.buf;
   msg.msg_controllen = CMSG_SPACE(sizeof(int));
   cmsg = CMSG_FIRSTHDR(&msg);
   cmsg->cmsg_len = CMSG_LEN(sizeof(int));

The magic constant 1024 scares me, and the conditional looks
ridiculous, and now msg.msg_controllen disagrees with cmsg->cmsg_len.
In OpenBSD's source tree, there is a subtly different idiom; in fact,
the last four changes to it have been to change the idiom.  So...which
one is right?

Home | Main Index | Thread Index | Old Index