From 7c283fbc460a559c4e83becfb9583f8c9de129a0 Mon Sep 17 00:00:00 2001 From: pk910 Date: Sat, 10 Dec 2011 13:31:48 +0100 Subject: [PATCH] implemented ipv6 support --- src/ClientSocket.c | 140 +++++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 87 deletions(-) diff --git a/src/ClientSocket.c b/src/ClientSocket.c index 898b05f..7ddaa3e 100644 --- a/src/ClientSocket.c +++ b/src/ClientSocket.c @@ -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)) -- 2.20.1