IPv6 Support for mcbot
authorMarkus Bröker <mbroeker@largo.dyndns.tv>
Sat, 13 Nov 2010 08:14:04 +0100
changeset 58 500a5ea7fcb8
parent 57 ca4e10daa1c9
child 59 e8f15b159e19
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 <mbroeker@largo.homelinux.org>
debian/changelog
include/config.h
include/irc.h
src/config.c
src/irc.c
--- 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 <mbroeker@largo.homelinux.org>  Fri, 22 Oct 2010 19:18:00 +0200
+ -- Markus Bröker <mbroeker@largo.homelinux.org>  Sat, 13 Nov 2010 08:13:37 +0100
--- 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;
 };
--- 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
--- 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:
--- 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;
     }