diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2005-06-27 16:27:31 +0000 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2005-06-27 16:27:31 +0000 |
commit | b330ec3dae2db59089ce44ec7c1ab7f0473e8ee6 (patch) | |
tree | 4caafcea72386061eb092c32df1ab8c32ef47f9f /src | |
parent | ae8f8a570067e1e1e65bfac3f60c7bec0d4faf31 (diff) | |
download | weechat-b330ec3dae2db59089ce44ec7c1ab7f0473e8ee6.zip |
Added IPv6 support
Diffstat (limited to 'src')
-rw-r--r-- | src/common/command.c | 9 | ||||
-rw-r--r-- | src/common/weechat.c | 2 | ||||
-rw-r--r-- | src/common/weeconfig.c | 23 | ||||
-rw-r--r-- | src/irc/irc-display.c | 3 | ||||
-rw-r--r-- | src/irc/irc-server.c | 121 | ||||
-rw-r--r-- | src/irc/irc.h | 5 |
6 files changed, 91 insertions, 72 deletions
diff --git a/src/common/command.c b/src/common/command.c index 6297f28e4..0a3b81f01 100644 --- a/src/common/command.c +++ b/src/common/command.c @@ -84,13 +84,14 @@ t_weechat_command weechat_commands[] = 0, 2, weechat_cmd_python, NULL }, { "server", N_("list, add or remove servers"), N_("[servername] | " - "[servername hostname port [-auto | -noauto] [-ssl] [-pwd password] [-nicks nick1 " + "[servername hostname port [-auto | -noauto] [-ipv6] [-ssl] [-pwd password] [-nicks nick1 " "[nick2 [nick3]]] [-username username] [-realname realname] " "[-command command] [-autojoin channel[,channel]] ] | " "[del servername]"), N_("servername: server name, for internal & display use\n" "hostname: name or IP address of server\n" "port: port for server (integer)\n" + "ipv6: use IPv6 protocol\n" "ssl: use SSL protocol\n" "password: password for server\n" "nick1: first nick for server\n" @@ -1765,6 +1766,8 @@ weechat_cmd_server (int argc, char **argv) server.autoconnect = 1; if (strcasecmp (argv[i], "-noauto") == 0) server.autoconnect = 0; + if (strcasecmp (argv[i], "-ipv6") == 0) + server.ipv6 = 1; if (strcasecmp (argv[i], "-ssl") == 0) server.ssl = 1; if (strcasecmp (argv[i], "-pwd") == 0) @@ -1854,8 +1857,8 @@ weechat_cmd_server (int argc, char **argv) new_server = server_new (server.name, server.autoconnect, server.autoreconnect, server.autoreconnect_delay, - 0, server.address, server.port, server.ssl, - server.password, + 0, server.address, server.port, server.ipv6, + server.ssl, server.password, server.nick1, server.nick2, server.nick3, server.username, server.realname, server.command, 1, server.autojoin, 1, NULL); diff --git a/src/common/weechat.c b/src/common/weechat.c index d6ddb3a24..28549a0d7 100644 --- a/src/common/weechat.c +++ b/src/common/weechat.c @@ -376,7 +376,7 @@ wee_parse_args (int argc, char *argv[]) if (!server_new (server_tmp.name, server_tmp.autoconnect, server_tmp.autoreconnect, server_tmp.autoreconnect_delay, - 1, server_tmp.address, server_tmp.port, 0, + 1, server_tmp.address, server_tmp.port, 0, 0, server_tmp.password, server_tmp.nick1, server_tmp.nick2, server_tmp.nick3, NULL, NULL, NULL, 0, server_tmp.autojoin, 1, NULL)) diff --git a/src/common/weeconfig.c b/src/common/weeconfig.c index eb94abe1d..f33be90c0 100644 --- a/src/common/weeconfig.c +++ b/src/common/weeconfig.c @@ -650,6 +650,10 @@ t_config_option weechat_options_server[] = N_("port for connecting to server"), OPTION_TYPE_INT, 0, 65535, 6667, NULL, NULL, &(cfg_server.port), NULL, NULL }, + { "server_ipv6", N_("use IPv6 protocol for server communication"), + N_("use IPv6 protocol for server communication"), + OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE, + NULL, NULL, &(cfg_server.ipv6), NULL, NULL }, { "server_ssl", N_("use SSL for server communication"), N_("use SSL for server communication"), OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE, @@ -924,6 +928,8 @@ config_get_server_option_ptr (t_irc_server *server, char *option_name) return (void *)(&server->address); if (strcasecmp (option_name, "server_port") == 0) return (void *)(&server->port); + if (strcasecmp (option_name, "server_ipv6") == 0) + return (void *)(&server->ipv6); if (strcasecmp (option_name, "server_ssl") == 0) return (void *)(&server->ssl); if (strcasecmp (option_name, "server_password") == 0) @@ -1099,12 +1105,13 @@ config_allocate_server (char *filename, int line_number) return 0; } if (!server_new (cfg_server.name, - cfg_server.autoconnect, cfg_server.autoreconnect, - cfg_server.autoreconnect_delay, 0, cfg_server.address, cfg_server.port, - cfg_server.ssl, cfg_server.password, cfg_server.nick1, cfg_server.nick2, - cfg_server.nick3, cfg_server.username, cfg_server.realname, - cfg_server.command, cfg_server.command_delay, cfg_server.autojoin, - cfg_server.autorejoin, cfg_server.notify_levels)) + cfg_server.autoconnect, cfg_server.autoreconnect, + cfg_server.autoreconnect_delay, 0, cfg_server.address, + cfg_server.port, cfg_server.ipv6, cfg_server.ssl, + cfg_server.password, cfg_server.nick1, cfg_server.nick2, + cfg_server.nick3, cfg_server.username, cfg_server.realname, + cfg_server.command, cfg_server.command_delay, cfg_server.autojoin, + cfg_server.autorejoin, cfg_server.notify_levels)) { server_free_all (); gui_printf (NULL, @@ -1502,6 +1509,8 @@ config_create_default () fprintf (file, "server_autoreconnect_delay=30\n"); fprintf (file, "server_address=irc.freenode.net\n"); fprintf (file, "server_port=6667\n"); + fprintf (file, "server_ipv6=off\n"); + fprintf (file, "server_ssl=off\n"); fprintf (file, "server_password=\n"); /* Get the user's name from /etc/passwd */ @@ -1678,6 +1687,8 @@ config_write (char *config_name) ptr_server->autoreconnect_delay); fprintf (file, "server_address=%s\n", ptr_server->address); fprintf (file, "server_port=%d\n", ptr_server->port); + fprintf (file, "server_ipv6=%s\n", + (ptr_server->ipv6) ? "on" : "off"); fprintf (file, "server_ssl=%s\n", (ptr_server->ssl) ? "on" : "off"); fprintf (file, "server_password=%s\n", diff --git a/src/irc/irc-display.c b/src/irc/irc-display.c index ab7276d45..8aafd29b0 100644 --- a/src/irc/irc-display.c +++ b/src/irc/irc-display.c @@ -176,6 +176,9 @@ irc_display_server (t_irc_server *server) " server_port . . . . . . .: %d\n", server->port); gui_printf_color (NULL, COLOR_WIN_CHAT, + " server_ipv6 . . . . . . .: %s\n", + (server->ipv6) ? _("yes") : _("no")); + gui_printf_color (NULL, COLOR_WIN_CHAT, " server_ssl . . . . . . . .: %s\n", (server->ssl) ? _("yes") : _("no")); gui_printf_color (NULL, COLOR_WIN_CHAT, diff --git a/src/irc/irc-server.c b/src/irc/irc-server.c index f51837b7c..5ac4e314e 100644 --- a/src/irc/irc-server.c +++ b/src/irc/irc-server.c @@ -71,6 +71,7 @@ server_init (t_irc_server *server) server->command_line = 0; server->address = NULL; server->port = -1; + server->ipv6 = 0; server->ssl = 0; server->password = NULL; server->nick1 = NULL; @@ -90,9 +91,9 @@ server_init (t_irc_server *server) server->child_write = -1; server->sock = -1; server->is_connected = 0; - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS server->ssl_connected = 0; - #endif +#endif server->unterminated_message = NULL; server->nick = NULL; server->reconnect_start = 0; @@ -325,7 +326,7 @@ server_free_all () t_irc_server * server_new (char *name, int autoconnect, int autoreconnect, int autoreconnect_delay, - int command_line, char *address, int port, int ssl, char *password, + int command_line, char *address, int port, int ipv6, int ssl, char *password, char *nick1, char *nick2, char *nick3, char *username, char *realname, char *command, int command_delay, char *autojoin, int autorejoin, char *notify_levels) @@ -335,7 +336,7 @@ server_new (char *name, int autoconnect, int autoreconnect, int autoreconnect_de if (!name || !address || (port < 0)) return NULL; - #ifdef DEBUG +#ifdef DEBUG wee_log_printf ("Creating new server (name:%s, address:%s, port:%d, pwd:%s, " "nick1:%s, nick2:%s, nick3:%s, username:%s, realname:%s, " "command:%s, autojoin:%s, autorejoin:%s, notify_levels:%s)\n", @@ -344,7 +345,7 @@ server_new (char *name, int autoconnect, int autoreconnect, int autoreconnect_de (username) ? username : "", (realname) ? realname : "", (command) ? command : "", (autojoin) ? autojoin : "", (autorejoin) ? "on" : "off", (notify_levels) ? notify_levels : ""); - #endif +#endif if ((new_server = server_alloc ())) { @@ -355,6 +356,7 @@ server_new (char *name, int autoconnect, int autoreconnect, int autoreconnect_de new_server->command_line = command_line; new_server->address = strdup (address); new_server->port = port; + new_server->ipv6 = ipv6; new_server->ssl = ssl; new_server->password = (password) ? strdup (password) : strdup (""); new_server->nick1 = (nick1) ? strdup (nick1) : strdup ("weechat_user"); @@ -389,11 +391,11 @@ server_send (t_irc_server *server, char *buffer, int size_buf) if (!server) return -1; - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS if (server->ssl_connected) return gnutls_record_send (server->gnutls_sess, buffer, size_buf); else - #endif +#endif return send (server->sock, buffer, size_buf, 0); } @@ -422,11 +424,11 @@ server_sendf (t_irc_server *server, char *fmt, ...) buffer[sizeof (buffer) - 1] = '\0'; if ((size_buf < 0) || (size_buf > (int) (sizeof (buffer) - 1))) size_buf = strlen (buffer); - #ifdef DEBUG +#ifdef DEBUG buffer[size_buf - 2] = '\0'; gui_printf (server->buffer, "[DEBUG] Sending to server >>> %s\n", buffer); buffer[size_buf - 2] = '\r'; - #endif +#endif buf2 = weechat_convert_encoding ((cfg_look_charset_internal && cfg_look_charset_internal[0]) ? cfg_look_charset_internal : local_charset, cfg_look_charset_encode, @@ -572,9 +574,9 @@ server_msgq_flush () { if (recv_msgq->data) { - #ifdef DEBUG +#ifdef DEBUG gui_printf (gui_current_window->buffer, "[DEBUG] %s\n", recv_msgq->data); - #endif +#endif ptr_data = recv_msgq->data; entire_line = strdup (ptr_data); @@ -584,9 +586,9 @@ server_msgq_flush () if (ptr_data) { - #ifdef DEBUG +#ifdef DEBUG gui_printf (NULL, "[DEBUG] data received from server: %s\n", ptr_data); - #endif +#endif host = NULL; command = NULL; @@ -668,11 +670,11 @@ server_recv (t_irc_server *server) if (!server) return; - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS if (server->ssl_connected) num_read = gnutls_record_recv (server->gnutls_sess, buffer, sizeof (buffer) - 2); else - #endif +#endif num_read = recv (server->sock, buffer, sizeof (buffer) - 2, 0); if (num_read > 0) @@ -731,16 +733,16 @@ server_close_connection (t_irc_server *server) /* close network socket */ if (server->sock != -1) { - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS if (server->ssl_connected) gnutls_bye (server->gnutls_sess, GNUTLS_SHUT_RDWR); - #endif +#endif close (server->sock); server->sock = -1; - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS if (server->ssl_connected) gnutls_deinit (server->gnutls_sess); - #endif +#endif } /* free any pending message */ @@ -752,9 +754,9 @@ server_close_connection (t_irc_server *server) /* server is now disconnected */ server->is_connected = 0; - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS server->ssl_connected = 0; - #endif +#endif } /* @@ -793,7 +795,7 @@ server_child_read (t_irc_server *server) /* connection OK */ case '0': /* enable SSL if asked */ - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS if (server->ssl_connected) { gnutls_transport_set_ptr (server->gnutls_sess, (gnutls_transport_ptr) server->sock); @@ -808,7 +810,7 @@ server_child_read (t_irc_server *server) return; } } - #endif +#endif /* kill child and login to server */ server_kill_child (server); irc_login (server); @@ -849,42 +851,34 @@ server_child_read (t_irc_server *server) int server_child (t_irc_server *server) { - struct hostent *ip4_hostent; - struct sockaddr_in addr; - char *ip_address; - int error; + struct addrinfo hints, *res; - /* bind to hostname */ - ip4_hostent = gethostbyname (server->address); - if (!ip4_hostent) + memset (&hints, 0, sizeof(hints)); + hints.ai_family = (server->ipv6) ? AF_INET6 : AF_INET; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo (server->address, NULL, &hints, &res) !=0) { - write (server->child_write, "1", 1); + write(server->child_write, "1", 1); return 0; } - memset (&addr, 0, sizeof (addr)); - memcpy (&addr.sin_addr, ip4_hostent->h_addr, ip4_hostent->h_length); - addr.sin_port = htons (server->port); - addr.sin_family = AF_INET; - - /* find IP address */ - ip_address = inet_ntoa (addr.sin_addr); - if (!ip_address) + if ((server->ipv6 && (res->ai_family != AF_INET6)) + || ((!server->ipv6 && (res->ai_family != AF_INET)))) { - write (server->child_write, "2", 1); + write(server->child_write, "2", 1); return 0; } - /* connect to server */ - error = connect (server->sock, (struct sockaddr *) &addr, sizeof (addr)); - if (error != 0) + if (server->ipv6) + ((struct sockaddr_in6 *)(res->ai_addr))->sin6_port = htons (server->port); + else + ((struct sockaddr_in *)(res->ai_addr))->sin_port = htons (server->port); + + if (connect (server->sock, res->ai_addr, res->ai_addrlen) != 0) { - write (server->child_write, "3", 1); + write(server->child_write, "3", 1); return 0; } - - /* connection OK */ write (server->child_write, "0", 1); - return 0; } @@ -897,11 +891,11 @@ server_connect (t_irc_server *server) { int child_pipe[2], set; pid_t pid; - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS const int cert_type_prio[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; - #endif +#endif - #ifndef HAVE_GNUTLS +#ifndef HAVE_GNUTLS if (server->ssl) { irc_display_prefix (server->buffer, PREFIX_ERROR); @@ -910,21 +904,23 @@ server_connect (t_irc_server *server) "with GNUtls support\n"), WEECHAT_ERROR); return 0; } - #endif +#endif irc_display_prefix (server->buffer, PREFIX_INFO); gui_printf (server->buffer, - _("%s: connecting to %s:%d%s...\n"), + _("%s: connecting to server %s:%d%s%s...\n"), PACKAGE_NAME, server->address, server->port, - (server->ssl) ? "(ssl)" : ""); - wee_log_printf (_("Connecting to server %s:%d%s...\n"), + (server->ipv6) ? " (IPv6)" : "", + (server->ssl) ? " (SSL)" : ""); + wee_log_printf (_("Connecting to server %s:%d%s%s...\n"), server->address, server->port, - (server->ssl) ? "(ssl)" : ""); + (server->ipv6) ? " (IPv6)" : "", + (server->ssl) ? " (SSL)" : ""); /* close any opened connection and kill child process if running */ server_close_connection (server); /* init SSL if asked */ - #ifdef HAVE_GNUTLS +#ifdef HAVE_GNUTLS server->ssl_connected = 0; if (server->ssl) { @@ -940,7 +936,7 @@ server_connect (t_irc_server *server) gnutls_credentials_set (server->gnutls_sess, GNUTLS_CRD_CERTIFICATE, gnutls_xcred); server->ssl_connected = 1; } - #endif +#endif /* create pipe for child process */ if (pipe (child_pipe) < 0) @@ -954,13 +950,12 @@ server_connect (t_irc_server *server) server->child_write = child_pipe[1]; /* create socket and set options */ - server->sock = socket (AF_INET, SOCK_STREAM, 0); + server->sock = socket ((server->ipv6) ? AF_INET6 : AF_INET, SOCK_STREAM, 0); if (server->sock == -1) { irc_display_prefix (server->buffer, PREFIX_ERROR); gui_printf (server->buffer, _("%s cannot create socket\n"), WEECHAT_ERROR); - server_close_connection (server); return 0; } @@ -1040,7 +1035,8 @@ server_auto_connect (int command_line) { (void) gui_buffer_new (gui_current_window, ptr_server, NULL, 0, 1); gui_redraw_buffer (gui_current_window->buffer); - server_connect (ptr_server); + if (!server_connect (ptr_server)) + server_reconnect_schedule (ptr_server); } } } @@ -1236,6 +1232,8 @@ server_print_log (t_irc_server *server) wee_log_printf (" command_line. . . . : %d\n", server->command_line); wee_log_printf (" address . . . . . . : '%s'\n", server->address); wee_log_printf (" port. . . . . . . . : %d\n", server->port); + wee_log_printf (" ipv6. . . . . . . . : %d\n", server->ipv6); + wee_log_printf (" ssl . . . . . . . . : %d\n", server->ssl); wee_log_printf (" password. . . . . . : '%s'\n", (server->password && server->password[0]) ? "(hidden)" : server->password); wee_log_printf (" nick1 . . . . . . . : '%s'\n", server->nick1); @@ -1254,6 +1252,9 @@ server_print_log (t_irc_server *server) wee_log_printf (" child_write . . . . : %d\n", server->child_write); wee_log_printf (" sock. . . . . . . . : %d\n", server->sock); wee_log_printf (" is_connected. . . . : %d\n", server->is_connected); +#ifdef HAVE_GNUTLS + wee_log_printf(" ssl_connected . . . : %d\n", server->ssl_connected); +#endif wee_log_printf (" unterminated_message: '%s'\n", server->unterminated_message); wee_log_printf (" nick. . . . . . . . : '%s'\n", server->nick); wee_log_printf (" reconnect_start . . : %ld\n", server->reconnect_start); diff --git a/src/irc/irc.h b/src/irc/irc.h index 6676b0fb3..1087a4052 100644 --- a/src/irc/irc.h +++ b/src/irc/irc.h @@ -146,6 +146,7 @@ struct t_irc_server int command_line; /* server was given on command line */ char *address; /* address of server (IP or name) */ int port; /* port for server (6667 by default) */ + int ipv6; /* use IPv6 protocol */ int ssl; /* SSL protocol */ char *password; /* password for server */ char *nick1; /* first nickname for the server */ @@ -163,7 +164,7 @@ struct t_irc_server pid_t child_pid; /* pid of child process (connecting) */ int child_read; /* to read into child pipe */ int child_write; /* to write into child pipe */ - int sock; /* socket for server */ + int sock; /* socket for server (IPv4 or IPv6) */ int is_connected; /* 1 if WeeChat is connected to server */ #ifdef HAVE_GNUTLS int ssl_connected; /* = 1 if connected with SSL */ @@ -264,7 +265,7 @@ extern t_irc_server *server_alloc (); extern void server_destroy (t_irc_server *); extern void server_free (t_irc_server *); extern void server_free_all (); -extern t_irc_server *server_new (char *, int, int, int, int, char *, int, int, +extern t_irc_server *server_new (char *, int, int, int, int, char *, int, int, int, char *, char *, char *, char *, char *, char *, char *, int, char *, int, char *); extern int server_send (t_irc_server *, char *, int); |