# HG changeset patch # User Markus Bröker # Date 1289632444 -3600 # Node ID 500a5ea7fcb85ef6a9dbfca7c57c332c90eb3727 # Parent ca4e10daa1c9fc09c9357ce3463b96368ce4f80b IPv6 Support for mcbot We initialize the socket functions with AF_UNSPEC and let the library fill in the proper values. Connects to IPv4 or IPv6. committer: Markus Bröker diff --git a/debian/changelog b/debian/changelog --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -mcbot (0.99-4) unstable; urgency=low +mcbot (0.99-5) unstable; urgency=low * Initial Release * the location of mcbot.cgi is stored in the db @@ -36,5 +36,6 @@ * user and hostname handling improved * useless feof handling removed * spelling error fixed + * ipv6 support added - -- Markus Bröker Fri, 22 Oct 2010 19:18:00 +0200 + -- Markus Bröker Sat, 13 Nov 2010 08:13:37 +0100 diff --git a/include/config.h b/include/config.h --- a/include/config.h +++ b/include/config.h @@ -11,7 +11,7 @@ char *nick; char *pass; char *server; - int port; + char *port; char *topic; char *channel; }; diff --git a/include/irc.h b/include/irc.h --- a/include/irc.h +++ b/include/irc.h @@ -24,7 +24,7 @@ typedef struct Message MSG; -FILE *irc_connect (char *, unsigned int); +FILE *irc_connect (char *, char *); int irc_login (FILE *, char *, char *, char *); char *irc_parsemessage (const char *, MSG *); #endif diff --git a/src/config.c b/src/config.c --- a/src/config.c +++ b/src/config.c @@ -46,7 +46,7 @@ * We can easily provide default values ... */ uc->nick = uc->pass = uc->server = uc->channel = uc->topic = NULL; - uc->port = 6667; + uc->port = "6667"; while (!feof (f)) { if (fgets (buffer, sizeof (buffer), f) == NULL) @@ -91,7 +91,7 @@ free (line[map]); break; case PORT: - uc->port = atoi (line[map]); + uc->port = compat_strdup (line[map]); free (line[map]); break; case CHANNEL: 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; }