I’m a little confused about the difference between the definitions of protocols on Linux when using socket(). I am attempting to listen for connections over TCP using socket(PF_INET, SOCK_STREAM, proto), where proto is (in my mind) disputed, or at least seems odd.
From <netinet/in.h>:
...
IPPROTO_IP = 0, /* Dummy protocol for TCP. */
...
IPPROTO_TCP = 6, /* Transmission Control Protocol. */
...
Agreed with by /etc/protocols:
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # hop-by-hop options for ipv6
...
tcp 6 TCP # transmission control protocol
...
I learned from an online tutorial, and also from the man page tcp(7) that you initialise a TCP socket using
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
which works absolutely fine, and certainly is a TCP socket. One thing about using the above arguments to initialise a socket is that the code
struct timeval timeout = {1, 0};
setsockopt(tcp_socket, 0, SO_RCVTIMEO, &timeout, sizeof(timeout); // 1s timeout
// Exactly the same for SO_SNDTIMEO here
works absolutely fine, but not after replacing all protocol arguments (including in socket()) with IPPROTO_TCP, as opposed to IPPROTO_IP which they have, as above.
So after experimenting with the difference, I’ve needed to ask a few searching questions:
- Why, when I replace all protocol arguments with
IPPROTO_TCP, do I get error 92 (“Protocol not available”) when setting timeouts, when protocol 0 is apparently just a ‘dummy’ TCP? - Why does
socket()require the information of whether it should be a stream, datagram or raw socket when that information is (always?) implicitly known from the protocol, and vice versa? (i.e. TCP is a stream protocol, UDP is a datagram protocol, …) - What could be meant by “dummy TCP”?
- What is
hopopt, and why does it have the same protocol number as ‘ip’?
Many thanks.
Giving 0 as protocol to
socketjust means that you want to use the default protocol for the family/socktype pair. In this case that is TCP, and thus you get the same result as withIPPROTO_TCP.Your error is in the setsockopt call. The correct one would be
the 0 there is not for protocol, but for option level.
IPPROTO_TCPis another option level, but you can’t combine that withSO_RCVTIMEO. It can only be used together withSOL_SOCKET.The ones you use with
IPPROTO_TCPare the ones listed in tcp(7), e.g.TCP_NODELAY.