[PATCH 2/3] network: recvmsg and sendmsg standard compliance (BZ#16919)
Szabolcs Nagy
szabolcs.nagy@arm.com
Fri Apr 22 10:25:00 GMT 2016
On 22/04/16 09:04, Michael Kerrisk (man-pages) wrote:
> On 21 April 2016 at 16:01, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
>> it is not clear from the standard how the
>> msg_control buffer may be allocated (since
>> only CMSG_* macros can access it), on linux
>> the kernel makes a copy so it does not care
>> about alignment in user-space, but the struct
>> alignment is still visible in the c and c++ abi.
>>
>> msg_control usage should be probably documented
>> in the linux man-page: glibc sunrpc sometimes
>> uses plain char[], nscd uses a union with struct
>> cmsghdr, i think neither of them makes a
>>
>> CMSG_FIRSTHDR (&msg)->cmsg_len
>>
>> access strictly iso c confrom, but the later at
>> least uses correct alignment.
>>
>> maybe a posix issue should be filed to the
>> austin group.
>
> Below are the current snippets of code shown in the cmsg(3) man page.
> Could you please tell me more exactly what you think needs fixing?
>
thanks, this is what i was looking for.
(i missed cmsg(3), only looked at recvmsg(2) and sendmsg(2).)
this means some code in glibc and iproute2 should be fixed
to use such a union. (what a nasty interface.)
> [[
> EXAMPLE
> This code looks for the IP_TTL option in a received ancillary
> buffer:
>
> struct msghdr msgh;
> struct cmsghdr *cmsg;
> int *ttlptr;
> int received_ttl;
>
> /* Receive auxiliary data in msgh */
>
> for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
> cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
> if (cmsg->cmsg_level == IPPROTO_IP
> && cmsg->cmsg_type == IP_TTL) {
> ttlptr = (int *) CMSG_DATA(cmsg);
> received_ttl = *ttlptr;
> break;
> }
> }
>
> if (cmsg == NULL) {
> /* Error: IP_TTL not enabled or small buffer or I/O error */
> }
>
> The code below passes an array of file descriptors over a UNIX
> domain socket using SCM_RIGHTS:
>
> struct msghdr msg = {0};
> struct cmsghdr *cmsg;
> int myfds[NUM_FD]; /* Contains the file descriptors to pass */
> int *fdptr;
> union { /* Ancillary data buffer, wrapped in a union
> in order to ensure it is suitably aligned */
> char buf[CMSG_SPACE(sizeof myfds)];
> struct cmsghdr align;
> } u;
>
> msg.msg_control = u.buf;
> msg.msg_controllen = sizeof u.buf;
> cmsg = CMSG_FIRSTHDR(&msg);
> cmsg->cmsg_level = SOL_SOCKET;
> cmsg->cmsg_type = SCM_RIGHTS;
> cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
> fdptr = (int *) CMSG_DATA(cmsg); /* Initialize the payload */
> memcpy(fdptr, myfds, NUM_FD * sizeof(int));
> ]]
>
> Cheers,
>
> Michael
>
More information about the Libc-alpha
mailing list