Hi Christian,
I've to admit that we never considered about supporting this (rather exotic) feature.
On Tue, Jun 19, 2018 at 03:52:16PM +0200, Johannes Kliemann wrote:
Yet this doesn't seem to be the case (at least with lwip). I implemented a test [1] that creates a connection from the test http client and subsequently calls recv(sock, buf, 1, MSG_PEEK) which always should yield 'G' into the buffer (the first character of the GET request). Yet the output looks as follows:
[init -> test-http_clnt] got IP address 10.0.2.15 [init -> test-http_clnt] Create new socket ... [init -> test-http_clnt] Connect to server ... [init -> test-http_clnt] Send request... [init -> test-libc_msg_peek] peek: G [init -> test-libc_msg_peek] peek: E [init -> test-libc_msg_peek] peek: T [init -> test-libc_msg_peek] peek: [init -> test-libc_msg_peek] peek: /
(this is just an extract but you get the point)
The problem is that this doesn't only account to the recv call but also any further read call will miss the first "peeked" bytes which completely defeats the purpose of MSG_PEEK.
According to the lwip_legacy port MSG_PEEK should be supported since 2007 and I'm not sure why it should stay broken such a long time.
2007-06-30 Frédéric Bernon
- sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions.
As far as I can see I have used it correctly so I'm not sure why it isn't working. You can view the code at [1] and run the test with run/libc_msg_peek.
The reason for this behavior can be found in the libc_lwip library, which (as my statement above hints) does not translate the 'flags' parameter, which seems to be incompatibly defined in lwip and libc:
grep -rn define.*MSG_PEEK $(./tool/ports/current lwip_legacy)/include $(./tool/ports/current libc)/include .../contrib/lwip_legacy-7f5610426ed8c4c64903136122d9ba58836cdc89/include/lwip_legacy/lwip/sockets.h:157:#define MSG_PEEK 0x01 /* Peeks at an incoming message */ .../contrib/libc-5a5de5baab6e3ce23f24012a7604abf070fa990c/include/libc/sys/socket.h:450:#define MSG_PEEK 0x2 /* peek at incoming message */
Oh, I only grepped inside lwip so I didn't find the conflict with libc.
The current migration to VFS-based socket operations does not include any support for recv flags too. Is this feature essential for your use case?
While the MSG_PEEK isn't absolutely necessary to me some other flags are. We're trying to build a TCP/IP unwrapper/wrapper and transmit OSI layer 5 with a Terminal session in between. Yet the asynchronous semantics of the Terminal session and the synchronous ones of the socket API aren't exactly easy to combine. Currently I use MSG_DONTWAIT to prevent blocking in read operations and polling to check if data is available (I wasn't able to stop select if necessary and recv with MSG_PEEK obviously wasn't working).
So having at least MSG_DONTWAIT would be quite helpful. But I think the general problem is the API. Having a native asynchronous TCP or IP session with a native TCP/IP stack would be the best case but I assume this won't happen soon. But also an asynchronous (or at least more compatible) approach using libc would already be useful (and potentially resolve the need for any recv flags ;) ).
So currently I need some flags but I would happily switch to a generally better approach if there is one.
Regards, Johannes