From owner-freebsd-hackers@freebsd.org Fri Jul 31 23:59:06 2015 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C816D9B06CD for ; Fri, 31 Jul 2015 23:59:06 +0000 (UTC) (envelope-from saper@saper.info) Received: from m.saper.info (m.saper.info [IPv6:2a01:4f8:a0:7383::]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "m.saper.info", Issuer "Marcin Cieslak 2011" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4706F354 for ; Fri, 31 Jul 2015 23:59:05 +0000 (UTC) (envelope-from saper@saper.info) Received: from m.saper.info (saper@m.saper.info [IPv6:2a01:4f8:a0:7383::]) by m.saper.info (8.14.9/8.14.9) with ESMTP id t6VNx1OX057627 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 31 Jul 2015 23:59:01 GMT (envelope-from saper@saper.info) Received: from localhost (saper@localhost) by m.saper.info (8.14.9/8.14.9/Submit) with ESMTP id t6VNx0Of057563; Fri, 31 Jul 2015 23:59:01 GMT (envelope-from saper@saper.info) X-Authentication-Warning: m.saper.info: saper owned process doing -bs Date: Fri, 31 Jul 2015 23:59:00 +0000 From: Marcin Cieslak To: Patrick Mooney cc: freebsd-hackers@freebsd.org Subject: Re: Interpretation of POSIX.1-2008 for recvmsg In-Reply-To: Message-ID: References: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Jul 2015 23:59:06 -0000 On Fri, 31 Jul 2015, Patrick Mooney wrote: > Greetings, > I have been researching differences in recvmsg() behavior across platforms > (namely Illumos and Linux) with respect to MSG_PEEK and 0-length buffers. > Certain Linux software I am attempting to run under Illumos makes a recvmsg() > call with a 0-length iovec and flags set to MSG_PEEK in order to interrogate > the size of a queued dgram. On native Linux, recvmsg() returns the size of the > queued dgram (with the MSG_TRUNC flag set). On both Illumos and FreeBSD, a > size of 0 is returned (with MSG_TRUNC set as well). In reading the POSIX spec > (http://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html), it is > not clear that returning 0 in this case is correct behavior. > > Here is a small test program I wrote up to display the differences in behavior: > https://us-east.manta.joyent.com/patrick.mooney/public/recvmsg/peektest.c > > The output on Linux: > peek len: 20 errno: 0 flags: 20 > recv len: 20 errno: 0 flags: 0 > ... versus BSD and Illumos: > peek len: 0 errno: 2 flags: 12 > recv len: 20 errno: 2 flags: 0 errno does not has to be reset to 0 to indicate success. You should check return value < 0 before using errno. I set errno to 0 before invoking recvmsg() and it stays 0 (that means it is just not modified). Also setting MSG_TRUNC in the input flags is not specified by POSIX (use just MSG_PEEK). MSG_TRUNC is the output flag. What you are expecting is the non-standard Linux behaviour with this flag set as input: MSG_TRUNC (since Linux 2.2) For raw (AF_PACKET), Internet datagram (since Linux 2.4.27/2.6.8), netlink (since Linux 2.6.22) and UNIX datagram (since Linux 3.4) sockets: return the real length of the packet or datagram, even when it was longer than the passed buffer. Not implemented for UNIX domain (unix(7)) sockets. Be aware that recvmsg(x, y, MSG_PEEK) *also* reads data - so Solaris and BSD consitently return what was saved into the buffer. In short - to check how large the message is, supply the buffer that is large enough (or try MSG_PEEK until it is large enough). Here are the result of my modified peektest.c[1]: peek buflen: 0x02 peek len: 0x02 errno: 0 flags: 0x12 peek read: [AB ] read buflen: 0x20 recv len: 0x20 errno: 0 flags: 0x00 recv read: [ABCD] On Linux: Using port 18399 peek buflen: 0x02 peek len: 0x02 errno: 0 flags: 0x20 peek read: [AB ] read buflen: 0x20 recv len: 0x20 errno: 0 flags: 0x00 recv read: [ABCD] MSG_TRUNC in the input flags is not POSIX. //Marcin