IPPROTO_IP vs IPPROTO_TCP/IPPROTO_UDP

前端 未结 2 1283
眼角桃花
眼角桃花 2020-12-24 08:19

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

相关标签:
2条回答
  • 2020-12-24 08:44

    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 IPv6 Hop-by-Hop Option extension header identifier.

    0 讨论(0)
  • 2020-12-24 08:47

    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.

    0 讨论(0)
提交回复
热议问题