Есть ли способ обработки вывода getaddrinfo () с помощью одного цикла и сокета IPv6? - PullRequest
1 голос
/ 20 марта 2011

Я хотел бы иметь возможность циклически проходить по списку, который является результатом функции getaddrinfo(), и вызывать connect(), используя каждый элемент этого списка, пока connect() не будет успешным.К сожалению, даже если я укажу флаги AI_ALL | AI_V4MAPPED и семейство AF_INET6, результаты будут неоднозначными.Первая часть списка содержит sockaddr_in6 структуры, а вторая часть sockaddr_in структуры, поэтому я не могу использовать их с AF_INET6 сокетом.

Я знаю, что могу создать два сокета.Я хотел бы знать, возможно ли это сделать только с помощью сокета AF_INET6.

Вот операционная система:

> uname -a
> Linux debian 2.6.32-5-amd64 #1 SMP Wed Jan 12 03:40:32 UTC 2011 x86_64 GNU/Linux

1 Ответ

1 голос
/ 20 марта 2011

Вам не нужно беспокоиться, если вы создаете сокет AF_INET или AF_INET6.Просто передайте данные из вызова getaddrinfo () в вызов socket ().

например

/* returns -1 on error, or a connected socket descriptor*/
int opensock(const char *hostname, const char *service)
{
    struct addrinfo hint, *host, *res = NULL;
    int tcp_sd = -1, error;

    memset(&hint, '\0', sizeof(hint));
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_family = PF_UNSPEC;
    error = getaddrinfo(hostname, service, &hint, &res);
    if(error){
        syslog(LOG_DEBUG,"getaddrinfo failed. Cant find host %s: %m",hostname);
        return tcp_sd;
    }
    for (host = res; host; host = host->ai_next) {
        tcp_sd = socket(host->ai_family, host->ai_socktype, host->ai_protocol);
        if (tcp_sd < 0) {
            continue;
        }

        if (connect(tcp_sd, host->ai_addr, host->ai_addrlen) < 0) {
            close(tcp_sd);
            tcp_sd = -1;
            continue;
        }

        break;      /* okay we got one */
    }

    freeaddrinfo(res);

    return tcp_sd;
}
...