implemented ipv6 support
authorpk910 <philipp@zoelle1.de>
Sat, 10 Dec 2011 12:31:48 +0000 (13:31 +0100)
committerpk910 <philipp@zoelle1.de>
Sat, 10 Dec 2011 12:40:10 +0000 (13:40 +0100)
src/ClientSocket.c

index 898b05fb2a9dc3a0ac27f0597f62e0cb85f39493..7ddaa3e46be9c620693efe469833e87fdbbce804 100644 (file)
@@ -53,7 +53,6 @@ struct ClientSocket* create_socket(char *host, int port, char *pass, char *nick,
     }
     client->host = strdup(host);
     client->port = port;
-    printf("Connect: %s:%d\n", client->host, client->port);
     client->pass = (pass == NULL ? NULL : strdup(pass));
     client->nick = strdup(nick);
     client->ident = strdup(ident);
@@ -76,108 +75,77 @@ struct ClientSocket* create_socket(char *host, int port, char *pass, char *nick,
     return client;
 }
 
-#ifdef WIN32
-
 int connect_socket(struct ClientSocket *client) {
     if((client->flags & SOCKET_FLAG_CONNECTED)) return 1;
-    struct hostent *host;
-    struct sockaddr_in addr;
     int sock;
-    addr.sin_addr.s_addr = inet_addr(client->host);
-    if (addr.sin_addr.s_addr == INADDR_NONE) {
-        host = gethostbyname(client->host);
-        if(!host) {
-            return SOCKET_ERROR;
-        }
-        memcpy(&(addr.sin_addr), host->h_addr_list[0], 4);
-    }
-    sock = socket(PF_INET, SOCK_STREAM, 0);
-    if (sock == -1)
-    {
-        perror("socket() failed");
-        return 0;
-    }
-
-    addr.sin_port = htons(client->port);
-    addr.sin_family = AF_INET;
-
-    if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
-    {
-        perror("connect() failed");
+    
+    struct addrinfo hints, *res;
+    struct sockaddr_in *ip4 = NULL;
+    struct sockaddr_in6 *ip6 = NULL;
+    memset (&hints, 0, sizeof (hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags |= AI_CANONNAME;
+    if (getaddrinfo (client->host, NULL, &hints, &res)) {
         return 0;
     }
-
-    client->sock = sock;
-    client->flags |= SOCKET_FLAG_CONNECTED | SOCKET_FLAG_RECONNECT;
-    client->connection_time = time(0);
-
-
-    if(client->flags & SOCKET_FLAG_SSL) {
-        ssl_connect(client);
-    }
-
-
-    //send the IRC Headers
-    char sendBuf[512];
-    int len;
-
-    if(client->pass && strcmp(client->pass, "")) {
-        len = sprintf(sendBuf, "PASS :%s\n", client->pass);
-        write_socket(client, sendBuf, len);
+    while (res) {
+        switch (res->ai_family) {
+        case AF_INET:
+            ip4 = (struct sockaddr_in *) res->ai_addr;
+            break;
+        case AF_INET6:
+            ip6 = (struct sockaddr_in6 *) res->ai_addr;
+            break;
+        }
+        res = res->ai_next;
     }
-    len = sprintf(sendBuf, "USER %s 0 0 :%s\n", client->ident, client->realname);
-    write_socket(client, sendBuf, len);
-    len = sprintf(sendBuf, "NICK %s\n", client->nick);
-    write_socket(client, sendBuf, len);
-
-    return 1;
-}
-
-#else
-
-int connect_socket(struct ClientSocket *client) {
-    if((client->flags & SOCKET_FLAG_CONNECTED)) return 1;
-    struct hostent *host;
-    struct sockaddr_in addr;
-    int sock;
-    if (!inet_aton(client->host, &addr.sin_addr))
-    {
-        host = gethostbyname(client->host);
-        if (!host)
-        {
-            perror("gethostbyname() failed");
+    
+    if(ip6) {
+        sock = socket(AF_INET6, SOCK_STREAM, 0);
+        if(sock == -1) {
+            perror("socket() failed");
             return 0;
         }
-        addr.sin_addr = *(struct in_addr*)host->h_addr;
-    }
-    sock = socket(PF_INET, SOCK_STREAM, 0);
-    if (sock == -1)
-    {
-        perror("socket() failed");
-        return 0;
-    }
-
-    addr.sin_port = htons(client->port);
-    addr.sin_family = AF_INET;
-
-    if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
-    {
-        perror("connect() failed");
+        
+        ip6->sin6_family = AF_INET6;
+        ip6->sin6_port = htons(client->port);
+        
+        if (connect(sock, (struct sockaddr*)ip6, sizeof(*ip6)) == -1) {
+            perror("connect() failed");
+            return 0;
+        }
+        
+    } else if(ip4) {
+        sock = socket(AF_INET, SOCK_STREAM, 0);
+        if(sock == -1) {
+            perror("socket() failed");
+            return 0;
+        }
+        
+        ip4->sin_family = AF_INET;
+        ip4->sin_port = htons(client->port);
+        
+        if (connect(sock, (struct sockaddr*)ip4, sizeof(*ip4)) == -1) {
+            perror("connect() failed");
+            return 0;
+        }
+        
+    } else
         return 0;
-    }
-
+    
     client->sock = sock;
     client->flags |= SOCKET_FLAG_CONNECTED | SOCKET_FLAG_RECONNECT;
     client->connection_time = time(0);
-
+    
     if(client->flags & SOCKET_FLAG_SSL) {
         ssl_connect(client);
     }
-
+    
     //send the IRC Headers
     char sendBuf[512];
     int len;
-
+    
     if(client->pass && strcmp(client->pass, "")) {
         len = sprintf(sendBuf, "PASS :%s\n", client->pass);
         write_socket(client, sendBuf, len);
@@ -190,8 +158,6 @@ int connect_socket(struct ClientSocket *client) {
     return 1;
 }
 
-#endif
-
 int close_socket(struct ClientSocket *client) {
     if(client == NULL) return 0;
     if((client->flags & SOCKET_FLAG_CONNECTED))