开发者

IPPROTO_IP vs IPPROTO_TCP/IPPROTO_UDP

I'm having some trouble finding documentation on what the distinction between these settings for the third argument to socket is. I know about TCP and UDP and their differences and also that IP is one layer up (down?) on the stack... My UDP code seems to work the same whether I set it to IPPROTO_IP 开发者_开发知识库or IPPROTO_UDP.


Documentation for socket() on Linux is split between various manpages including ip(7) that specifies that you have to use 0 or IPPROTO_UDP for UDP and 0 or IPPROTO_TCP for TCP. When you use 0, which happens to be the value of IPPROTO_IP, UDP is used for SOCK_DGRAM and TCP is used for SOCK_STREAM.

In my opinion the clean way to create a UDP or a TCP IPv4 socket object is as follows:

int sock_udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
int sock_tcp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

The reason is that it is generally better to be explicit than implicit. In this specific case using 0 or worse IPPROTO_IP for the third argument doesn't gain you anything.

Also imagine using a protocol that can do both streams and datagrams like sctp. By always specifying both socktype and protocol you are safe from any ambiguity.


From the socket(2) Linux manual page, from man-pages 5.08:

Normally only a single protocol exists to support a particular socket type within a given protocol family, in which case protocol can be specified as 0. However, it is possible that many protocols may exist, in which case a particular protocol must be specified in this manner.

IPPROTO_IP is just the usual placeholder constant from the IPPROTO_* family with the value 0 in the socket API since its early days.

Of course in the interest of forward compatibility, in case more socket types are added for the protocol family in the future, which could break 0 with UDP/TCP or change its behaviour, it would be best to look up the specific protocol value for the protocol you want and use it, rather than using 0 or IPPROTO_IP.

Note that the IPPROTO_* header values serve multiple purposes in different contexts: in addition to being used as parameter values to identify protocols here in the socket API and internally in its implementation code, they are also used as the values of the IP protocol field in the IP packets themselves. These IP protocol values, or protocol numbers in IANA terminology, themselves have an additional purpose, identifying different extension header types in IPv6. This is why 0 is also IPPROTO_HOPOPTS, the identifier for the IPv6 Hop-by-Hop Option extension header.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜