X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sources%2Fsockconn.c;h=543abe679109579160be079a889832e6af377e82;hp=c1624743d8d0054224a39f00211359bb5559b36d;hb=c19330d1e61698f1758d5bf9d340955e1d4d876b;hpb=88d8a251947f948094d35de596feaf49e975f91b diff --git a/sources/sockconn.c b/sources/sockconn.c index c162474..543abe6 100644 --- a/sources/sockconn.c +++ b/sources/sockconn.c @@ -28,38 +28,76 @@ * ****************************************************************/ #include +#include #include #include +#include +#include +#include #include +#include int sockconn(char *host, char *serv, int prot, int type) { - struct addrinfo hint, *addr; + struct addrinfo hint, *addr, *save; int res; - int sock - /* initialize hint */ - memset(&hint, 0, sizeof(hint)); - hint.ai_family = PF_UNSPEC; - hint.ai_protocol = prot; - hint.ai_socktype = type; - res = getaddrinfo(host, serv, &hint, &addr); - if (res != 0) { - printf("sockconn cannot resolve host %s, service %s, - protocol %d: %s\n", host, serv, prot, gai_strerror(res)); - errno = 0; + int sock; + int err; + char buffer[INET6_ADDRSTRLEN]; + struct sockaddr_in *ip4; + struct sockaddr_in6 *ip6; + /* initialize hint structure */ + memset(&hint, 0, sizeof(struct addrinfo)); + hint.ai_family = PF_UNSPEC; /* generic address (IPv4 or IPv6) */ + hint.ai_protocol = prot; /* protocol */ + hint.ai_socktype = type; /* socket type */ + res = getaddrinfo(host, serv, &hint, &addr); /* calling getaddrinfo */ + if (res != 0) { /* on error exit */ + printf("sockconn cannot resolve host %s, service %s, ", host, serv); + printf("protocol %d: %s\n", prot, gai_strerror(res)); + errno = 0; /* clear errno */ return -1; } - sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); - if (sock < 0) { - perror("sockconn cannot create socket\n"); - return sock; + /* loop on possible addresses */ + save = addr; + while (addr != NULL) { + if (addr->ai_family == PF_INET) { + ip4 = (struct sockaddr_in *) addr->ai_addr; + printf("Indirizzo %s\n", inet_ntop(ip4->sin_family, &ip4->sin_addr, + buffer, sizeof(buffer))); + } else { + ip6 = (struct sockaddr_in6 *) addr->ai_addr; + printf("Indirizzo %s\n", inet_ntop(ip6->sin6_family, + &ip6->sin6_addr, + buffer, sizeof(buffer))); + } + /* get a socket */ + sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if (sock < 0) { + if (addr->ai_next != NULL) { + addr=addr->ai_next; + continue; + } else { + printf("sockconn cannot create socket\n"); + return sock; + } + } + /* connect the socket */ + res = connect(sock, addr->ai_addr, addr->ai_addrlen); + if (res < 0) { + if (addr->ai_next != NULL) { + close(sock); + addr=addr->ai_next; + continue; + } else { + err = errno; + close(sock); + errno = err; + printf("sockconn cannot connect socket\n"); + return res; + } + } else break; } - res = connect(sock, addr->ai_addr, addr->ai_addrlen); - if (res < 0) { - perror("sockconn cannot connect socket\n"); - return res; - } - freeaddrinfo(addr); + freeaddrinfo(save); /* done, release memory */ return sock; } -