2

When I create a try to socket.recv() from a NETLINK_ROUTE socket if I don't recv ALL the data available, it seems the data not recv'd is lost.

For example:

>>> import socket
>>> sock = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, socket.NETLINK_ROUTE)
>>> sock.bind((0,0))
>>> sock.send('\24\0\0\0\22\0\1\3\23\0364O\0\0\0\0\21\0\0\0') # struct nlmsghdr
20
>>> sock.recv(10000)
'\xe4\x03\x00\x00 ... ' (+3000 more bytes)

If I sock.recv(100), it will return 100 bytes but the +2900 other bytes are gone. Doing another sock.recv() will return the next nlmsghdr (if a multi part message) or block waiting for data.

I can sock.recv(X, socket.MSG_PEEK) to read X bytes without data being lost; but when doing that the read data isn't pop'd out of the recv buffer of course.

I thought any data not read would remain in the buffer until read. What am I doing wrong? I'd rather not just 'guess' at how much data might be available...

2 Answers 2

3

That's how datagrams (SOCK_DGRAM sockets) work -- message boundaries are kept and when you don't read the whole packet the rest is discarded (SOCK_STREAM sockets, i.e. TCP provide byte stream services where you can read as many bytes as you want at once, the rest will be kept in the socket buffer).

Netlink provides a datagram service, you can use SOCK_DGRAM or SOCK_RAW sockets with it.

What is the issue? AFAIK netlink has an upper limit for message size, you should just use that to receive messages.

Sign up to request clarification or add additional context in comments.

3 Comments

I just didn't expect it to work that way. I was planning on just reading a single netlink msg at a time from the socket buffer. If this is expected behavior (there isn't a flag to alter it) I'll just create and read from my own buffer.
As far as I know you can't change this behavior. If you really need to know the exact size of the message before you read it you can peek onto the nlmsghdr and you'll see the length of the packet.
That was my plan. The problem is there can be multiple msgs in a single datagram. Reading the nlmsg_len of the first packet doesn't include the size of any other msgs in the same datagram.
0

Read (and process) all datagrams in a loop, until none is received within a time interval. A non-blocking socket and select.select can be used with a timeout to accomplish this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.