Socket sendmsg() porting question

Ed Schouten ed at nuxi.nl
Thu Aug 4 07:15:06 UTC 2016


2016-08-03 19:18 GMT+02:00 Lundberg, Johannes <johannes at brilliantservice.co.jp>:
> Even if I set cmsg_level and cmsg_type it won't let me send it. The problem
> is having a zero length attachment on freebsd....
> I can't send -1 as fd because that errors to invalid file descriptor.

Well, it makes sense. If you're attaching a message to a sendmsg()
call, it should have contents that make sense. Also, msg_controllen
should correspond with the actual space consumed by the message. Not a
single byte more. Change the logic to one of the following two.

Solution 1: Simply set msg_controllen to zero entirely, so there is no
message attached when sending.

struct cmsghdr *cmsg = CMSG_FIRSTHDR(&message);
if (fd >= 0) {
message.msg_controllen = CMSG_SPACE(sizeof(fd));
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
} else {
message.msg_controllen = 0;
}

Solution 2: Send a SCM_RIGHTS message that contains no file descriptors.

struct cmsghdr *cmsg = CMSG_FIRSTHDR(&message);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
if (fd >= 0) {
message.msg_controllen = CMSG_SPACE(sizeof(fd));
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
} else {
message.msg_controllen = CMSG_SPACE(0);
cmsg->cmsg_len = CMSG_LEN(0);
}

Also worth mentioning:

char control[CMSG_SPACE(sizeof(int))];

That line is incorrect. The reason for this is that it may not be
sufficiently aligned. You have to make sure that the control message
buffer is aligned to at least 'struct cmsghdr', as CMSG_FIRSTHDR()
will do nothing more than return the buffer directly. Change that line
to one of the following two:

#include <stdalign.h>
alignas(struct cmsghdr) char control[CMSG_SPACE(sizeof(int))];

Or:

union {
 struct cmsghdr a;
 char b[CMSG_SPACE(sizeof(int))];
} control;

Best regards,
-- 
Ed Schouten <ed at nuxi.nl>
Nuxi, 's-Hertogenbosch, the Netherlands
KvK-nr.: 62051717


More information about the freebsd-current mailing list