Opened 12 years ago
Closed 12 years ago
#9678 closed bug (fixed)
Cannot send and receive through the same socket
Reported by: | markh | Owned by: | phoudoin |
---|---|---|---|
Priority: | normal | Milestone: | R1 |
Component: | Network & Internet/IPv4 | Version: | R1/alpha4.1 |
Keywords: | Cc: | phoudoin | |
Blocked By: | Blocking: | ||
Platform: | All |
Description
When trying to receive data from a socket I have previously sent data through, I get a connection refused error. A workaround is to use a second socket to send the data. I attached two files:
- socket_test_send_recv_1_socket.c: Uses only one socket and fails.
- socket_test_send_recv_2_sockets.c: Uses two sockets and works.
The first construction is used by Postgresql to check if it can start the statistics collector and this now fails on Haiku.
Attachments (2)
Change History (10)
by , 12 years ago
Attachment: | socket_test_send_recv_1_socket.c added |
---|
by , 12 years ago
Attachment: | socket_test_send_recv_2_sockets.c added |
---|
comment:1 by , 12 years ago
comment:2 by , 12 years ago
Cc: | added |
---|
comment:3 by , 12 years ago
Just test it: when skipping connect() and using sendto() instead, send and receive through the same socket does works as expected.
Which means that connect() is the culprid here. Well, not the syscall, but the UdpEndpointManager::ConnectEndpoint() one, I fear.
comment:4 by , 12 years ago
looking at udp_endpoints KDL command, it seems that the local (ephemeral) port bound at bind() step is replaced by the implicit bind done at UdpEndpointManager::ConnectEndpoint()'s end, with a new ephemeral local port. The peer address/port pair being the first bound one, the data sent is refused as no local address match anymore.
Will see next how to fix that - without breaking everything else ;-)
comment:5 by , 12 years ago
Owner: | changed from | to
---|---|
Status: | new → in-progress |
comment:6 by , 12 years ago
If I'm not mistaken, problem is here: http://cgit.haiku-os.org/haiku/tree/src/add-ons/kernel/network/protocols/udp/udp.cpp#n371
When the local address is not empty, bound port is not kept, overwritten by routeToDestination's interface address port, which is 0 for obvious reason, leading to a new ephemeral port being bound to endpoint.
comment:7 by , 12 years ago
Thanks for working on this, phoudoin! You may want to add the test to our set of networking test applications -- that we should one day transform into proper unit tests.
Thanks Mark for the ticket.
Meanwhile, could you try in the one socket scenario to skip the connect() step and use sendto(pgStatSock, &test_byte, 1, 0, & pgStatAddr, alen) instead of calling plain send()?
Oh, BTW, closesocket() was needed under BeOS only. You can use close() now, and it's better to remove this old BeOS-specific from PostgresSQL port.