What additional purpose can ai_protocol use in tooltips when calling the getaddrinfo () method when the ai_socktype parameter is already specified?

getaddrinfo takes struct addrinfo *hintsas a third argument, which can be used to specify criteria for selecting the socket addresses that this function should return.

The documentation indicates what we can establish ai_socktype, as well ai_protocolas to indicate selection criteria. However, I cannot understand why ai_protocolit is required if we already indicate ai_socktype. If one of these two is indicated, then the other seems redundant.

Here is some code that I wrote to experiment with this.

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

void getaddrinfo_demo(const char *node, const char *service,
                      int socktype, int protocol)
{
    struct addrinfo hints, *res, *p; 
    int error;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = socktype;
    hints.ai_protocol = protocol;

    error = getaddrinfo(node, service, &hints, &res);
    if (error) {
        printf("Error %d: %s\n\n", error, gai_strerror(error));
        return;
    }

    for (p = res; p != NULL; p = p->ai_next) {
        struct sockaddr_in *addr = ((struct sockaddr_in *) p->ai_addr);
        char ip[INET_ADDRSTRLEN];
        int port = ntohs(addr->sin_port);

        inet_ntop(AF_INET, &addr->sin_addr, ip, INET_ADDRSTRLEN);
        printf("ip: %s; port: %d; protocol: %d\n", ip, port, p->ai_protocol);
    }
    printf("\n");

    freeaddrinfo(res);
}

int main()
{
    /* Consistent family and socktype works fine. */
    getaddrinfo_demo("localhost", "http", SOCK_STREAM, IPPROTO_TCP);
    getaddrinfo_demo("localhost", "http", SOCK_DGRAM, IPPROTO_UDP);

    /* Inconsistent family and sock type leads to error -7. */
    getaddrinfo_demo("localhost", "http", SOCK_STREAM, IPPROTO_UDP);
    getaddrinfo_demo("localhost", "http", SOCK_DGRAM, IPPROTO_TCP);
}

Here is the result.

$ gcc -std=c99 -D_POSIX_SOURCE -Wall -Wextra -pedantic foo.c && ./a.out 
ip: 127.0.0.1; port: 80; protocol: 6
ip: 127.0.0.1; port: 80; protocol: 6

ip: 127.0.0.1; port: 80; protocol: 17
ip: 127.0.0.1; port: 80; protocol: 17

Error -7: ai_socktype not supported

Error -7: ai_socktype not supported

, ai_socktype = AF_STREAM, ai_protocol = IPPROTO_TCP. ai_protocol = IPPROTO_UDP . ai_protocol hints, - .

, ai_protocol hints? , ai_socktype ai_protocol ?

+4
1

:

getaddrinfo_demo("localhost", "http", SOCK_STREAM, IPPROTO_SCTP);
getaddrinfo_demo("localhost", "imap", SOCK_STREAM, IPPROTO_TCP);
getaddrinfo_demo("localhost", "imap", SOCK_STREAM, IPPROTO_SCTP);
getaddrinfo_demo("localhost", "sbcap", SOCK_STREAM, IPPROTO_SCTP);
getaddrinfo_demo("localhost", "sbcap", SOCK_SEQPACKET, IPPROTO_SCTP);
getaddrinfo_demo("localhost", "sbcap", SOCK_STREAM, IPPROTO_TCP);
getaddrinfo_demo("localhost", "http", SOCK_DGRAM, IPPROTO_UDPLITE);
getaddrinfo_demo("localhost", "syslog-tls", SOCK_DCCP, IPPROTO_DCCP);

:

ip: 127.0.0.1; port: 80; protocol: 132
ip: 127.0.0.1; port: 143; protocol: 6
Error -8: Servname not supported for ai_socktype
ip: 127.0.0.1; port: 29168; protocol: 132
ip: 127.0.0.1; port: 29168; protocol: 132
Error -8: Servname not supported for ai_socktype
Error -8: Servname not supported for ai_socktype
ip: 127.0.0.1; port: 6514; protocol: 33

, TCP , UDP - ( DCCP SOCK_DCCP, UDP-Lite ( , , UDP-Lite RFC , "UDP-Lite , IANA UDP" )).

, API, getaddrinfo(), , , , , . , , . , . FreeBSD,

WIDE Hydrangea IPv6.

FAQ , , 1997 - -1998 ( , , , , ). SCTP 2000 . , SCTP, API - . DCCP, 2005-2006 , API.

+6

Source: https://habr.com/ru/post/1654488/


All Articles