pythonlinuxsocketsnetlink

Python Linux Netlink Recv Buffer


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...


Solution

  • 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.