(This information may be Linux specific)
As I recall, control messages are associated with normal data. Thus,
you need to read a byte of normal data in order to get a control
message. You cannot set msg_iovlen to 0 and expect to get only control
messages.
The converse is not true. You can set controllen to 0 and any control
messages will be discarded (and MSG_CTRUNC will let you know that this
occurred.)
MSG_TRUNC will occur on a datagram based socket when a partial
datagram was read. The rest of the datagram is lost.
> If my understanding is correct, doing read() and recvmsg() on the same
> socket to receive normal data and ancillary messages can cause you to
> lose data.
This is correct. If you wish to mix read() and recvmsg() you must
somehow know when to expect control messages so that you can use
recvmsg to catch them. (This is how Chrome's renderer communication
works. Due to a detail of Chrome's design, read() is significantly
faster so it used by default and the IPC protocol is framed such that
recvmsg is only used when needed.)
> type Conn interface {
> Recvmsg(b []byte, ancil []byte) (n int, nancil int, msgflags int,
> err os.Error)
> }
That seems reasonable to me, but rsc often has good ideas that I don't think of.
AGL
On Oct 7, 2:31 pm, Adam Langley <a...@golang.org> wrote:
> On Thu, Oct 7, 2010 at 7:55 AM, Albert Strasheim <full...@gmail.com> wrote:
> > I need to test what happens when msg_iov is null and there is normal
> > data on the socket, or if msg_control is null and there is ancillary
> > messages on the socket. My guess is that you will get a msghdr back
> > with the MSG_TRUNC or MSG_CTRUNC flag set and the data will be
> > discarded.
>
> (This information may be Linux specific)
>
> As I recall, control messages are associated with normal data. Thus,
> you need to read a byte of normal data in order to get a control
> message. You cannot set msg_iovlen to 0 and expect to get only control
> messages.
> The converse is not true. You can set controllen to 0 and any control
> messages will be discarded (and MSG_CTRUNC will let you know that this
> occurred.)
>
> MSG_TRUNC will occur on a datagram based socket when a partial
> datagram was read. The rest of the datagram is lost.
Thanks. I also found some notes here (for future reference):
http://www.lst.de/~okir/blackhats/node121.html
> > If my understanding is correct, doing read() and recvmsg() on the same
> > socket to receive normal data and ancillary messages can cause you to
> > lose data.
>
> This is correct. If you wish to mix read() and recvmsg() you must
> somehow know when to expect control messages so that you can use
> recvmsg to catch them. (This is how Chrome's renderer communication
> works. Due to a detail of Chrome's design, read() is significantly
> faster so it used by default and the IPC protocol is framed such that
> recvmsg is only used when needed.)
>
> > type Conn interface {
> > Recvmsg(b []byte, ancil []byte) (n int, nancil int, msgflags int,
> > err os.Error)
> > }
>
> That seems reasonable to me, but rsc often has good ideas that I don't think of.
I have started work on changing fd.go to get a feel of what has to
happen.
Patch for Recvmsg looks something like this: http://pastebin.com/btyfWZMq
Some of the code can probably move from there into syscall, so that
syscall doesn't have to export anyToSockaddr. I also need to add a
SetLen function for Iov and a SetControllen function for Msghdr to
deal with the different data types on 386/amd64.
If Russ could give us his thoughts, I can start by making the
necessary changes to this CL:
http://codereview.appspot.com/2331044/
to get syscall ready, and then do the remaining work and testing in
net.
Regards
Albert