diff --git a/src/irc.c b/src/irc.c --- a/src/irc.c +++ b/src/irc.c @@ -34,33 +34,41 @@ "KICK", NULL }; -FILE *irc_connect (char *server, unsigned int port) +FILE *irc_connect (char *server, char *port) { - struct hostent *he; - char *ip; - struct sockaddr_in ca; - int csocket; + struct addrinfo hints; + struct addrinfo *result, *rp; + + int csocket = -1; FILE *stream; - he = gethostbyname (server); - if (he == NULL) { - perror ("GETHOSTBYNAME"); + memset (&hints, 0, sizeof (struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = 0; + hints.ai_protocol = IPPROTO_TCP; + + if (getaddrinfo (server, port, &hints, &result) != 0) { + perror ("getaddrinfo"); return NULL; } - if ((ip = inet_ntoa (*((struct in_addr *)he->h_addr_list[0]))) == NULL) { - perror ("INET_NTOA"); - return NULL; - } else - printf ("IP: %s\n", ip); + for (rp = result; rp != NULL; rp = rp->ai_next) { + if ((csocket = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1) + continue; - ca.sin_family = AF_INET; - ca.sin_addr.s_addr = inet_addr (ip); - ca.sin_port = htons (port); + if (connect (csocket, rp->ai_addr, rp->ai_addrlen) != -1) { + fprintf (stderr, "Connected via %s\n", (rp->ai_family == AF_INET6) ? "IPv6" : "IPv4"); + break; + } + close (csocket); + } - csocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (connect (csocket, (struct sockaddr *)&ca, (socklen_t) sizeof (ca)) == -1) { - perror ("CONNECT"); + if (result != NULL) + freeaddrinfo (result); + + if (csocket < 0) { + perror ("Cannot connect"); return NULL; }