summaryrefslogtreecommitdiff
path: root/src/plugins/irc/irc-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/irc/irc-server.c')
-rw-r--r--src/plugins/irc/irc-server.c130
1 files changed, 62 insertions, 68 deletions
diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c
index 6c7100fd8..2b331171e 100644
--- a/src/plugins/irc/irc-server.c
+++ b/src/plugins/irc/irc-server.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
* Copyright (C) 2005-2010 Emmanuel Bouthenot <kolter@openics.org>
+ * Copyright (C) 2012 Simon Arlott
*
* This file is part of WeeChat, the extensible chat client.
*
@@ -82,7 +83,7 @@ char *irc_server_option_string[IRC_SERVER_NUM_OPTIONS] =
};
char *irc_server_option_default[IRC_SERVER_NUM_OPTIONS] =
-{ "", "", "off",
+{ "", "", "on",
"off", "", "NORMAL", "2048", "on",
"", "",
"plain", "", "", "15",
@@ -362,6 +363,11 @@ irc_server_set_addresses (struct t_irc_server *server, const char *addresses)
free (server->ports_array);
server->ports_array = NULL;
}
+ if (server->retry_array)
+ {
+ free (server->retry_array);
+ server->retry_array = NULL;
+ }
/* set new addresses/ports */
if (addresses && addresses[0])
@@ -370,6 +376,7 @@ irc_server_set_addresses (struct t_irc_server *server, const char *addresses)
",", 0, 0,
&server->addresses_count);
server->ports_array = malloc (server->addresses_count * sizeof (server->ports_array[0]));
+ server->retry_array = malloc (server->addresses_count * sizeof (server->retry_array[0]));
for (i = 0; i < server->addresses_count; i++)
{
pos = strchr (server->addresses_array[i], '/');
@@ -386,6 +393,7 @@ irc_server_set_addresses (struct t_irc_server *server, const char *addresses)
{
server->ports_array[i] = IRC_SERVER_DEFAULT_PORT;
}
+ server->retry_array[i] = 0;
}
}
}
@@ -401,8 +409,13 @@ irc_server_set_index_current_address (struct t_irc_server *server, int index)
{
free (server->current_address);
server->current_address = NULL;
+
+ /* copy current retry value before loading next server */
+ if (server->index_current_address < server->addresses_count)
+ server->retry_array[server->index_current_address] = server->current_retry;
}
server->current_port = 0;
+ server->current_retry = 0;
if (server->addresses_count > 0)
{
@@ -410,6 +423,7 @@ irc_server_set_index_current_address (struct t_irc_server *server, int index)
server->index_current_address = index;
server->current_address = strdup (server->addresses_array[index]);
server->current_port = server->ports_array[index];
+ server->current_retry = server->retry_array[index];
}
}
@@ -860,10 +874,12 @@ irc_server_alloc (const char *name)
new_server->addresses_count = 0;
new_server->addresses_array = NULL;
new_server->ports_array = NULL;
+ new_server->retry_array = NULL;
new_server->index_current_address = 0;
new_server->current_address = NULL;
new_server->current_ip = NULL;
new_server->current_port = 0;
+ new_server->current_retry = 0;
new_server->sock = -1;
new_server->hook_connect = NULL;
new_server->hook_fd = NULL;
@@ -1331,6 +1347,8 @@ irc_server_free_data (struct t_irc_server *server)
weechat_string_free_split (server->addresses_array);
if (server->ports_array)
free (server->ports_array);
+ if (server->retry_array)
+ free (server->retry_array);
if (server->current_address)
free (server->current_address);
if (server->current_ip)
@@ -3022,7 +3040,7 @@ irc_server_switch_address (struct t_irc_server *server, int connection)
*/
int
-irc_server_connect_cb (void *data, int status, int gnutls_rc,
+irc_server_connect_cb (void *data, int status, int gnutls_rc, int sock,
const char *error, const char *ip_address)
{
struct t_irc_server *server;
@@ -3037,7 +3055,8 @@ irc_server_connect_cb (void *data, int status, int gnutls_rc,
switch (status)
{
case WEECHAT_HOOK_CONNECT_OK:
- /* login to server */
+ /* set socket and IP */
+ server->sock = sock;
if (server->current_ip)
free (server->current_ip);
server->current_ip = (ip_address) ? strdup (ip_address) : NULL;
@@ -3052,6 +3071,7 @@ irc_server_connect_cb (void *data, int status, int gnutls_rc,
1, 0, 0,
&irc_server_recv_cb,
server);
+ /* login to server */
irc_server_login (server);
break;
case WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND:
@@ -3101,6 +3121,7 @@ irc_server_connect_cb (void *data, int status, int gnutls_rc,
error);
}
irc_server_close_connection (server);
+ server->current_retry++;
irc_server_switch_address (server, 1);
break;
case WEECHAT_HOOK_CONNECT_PROXY_ERROR:
@@ -3147,6 +3168,7 @@ irc_server_connect_cb (void *data, int status, int gnutls_rc,
error);
}
irc_server_close_connection (server);
+ server->current_retry++;
irc_server_reconnect_schedule (server);
break;
case WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR:
@@ -3176,6 +3198,7 @@ irc_server_connect_cb (void *data, int status, int gnutls_rc,
(void) gnutls_rc;
#endif
irc_server_close_connection (server);
+ server->current_retry++;
irc_server_switch_address (server, 1);
break;
case WEECHAT_HOOK_CONNECT_MEMORY_ERROR:
@@ -3204,8 +3227,24 @@ irc_server_connect_cb (void *data, int status, int gnutls_rc,
error);
}
irc_server_close_connection (server);
+ server->current_retry++;
irc_server_switch_address (server, 1);
break;
+ case WEECHAT_HOOK_CONNECT_SOCKET_ERROR:
+ weechat_printf (server->buffer,
+ _("%s%s: unable to create socket"),
+ weechat_prefix ("error"), IRC_PLUGIN_NAME);
+ if (error && error[0])
+ {
+ weechat_printf (server->buffer,
+ _("%s%s: error: %s"),
+ weechat_prefix ("error"), IRC_PLUGIN_NAME,
+ error);
+ }
+ irc_server_close_connection (server);
+ server->current_retry++;
+ irc_server_reconnect_schedule (server);
+ break;
}
return WEECHAT_RC_OK;
@@ -3618,7 +3657,7 @@ irc_server_gnutls_callback (void *data, gnutls_session_t tls_session,
int
irc_server_connect (struct t_irc_server *server)
{
- int set, length, flags;
+ int length;
char *option_name;
struct t_config_option *proxy_type, *proxy_ipv6, *proxy_address, *proxy_port;
const char *proxy, *str_proxy_type, *str_proxy_address;
@@ -3737,26 +3776,22 @@ irc_server_connect (struct t_irc_server *server)
if (proxy_type)
{
weechat_printf (server->buffer,
- _("%s%s: connecting to server %s/%d%s%s via %s "
+ _("%s%s: connecting to server %s/%d%s via %s "
"proxy %s/%d%s..."),
weechat_prefix ("network"),
IRC_PLUGIN_NAME,
server->current_address,
server->current_port,
- (IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6)) ?
- " (IPv6)" : "",
(IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_SSL)) ?
" (SSL)" : "",
str_proxy_type,
str_proxy_address,
weechat_config_integer (proxy_port),
(weechat_config_boolean (proxy_ipv6)) ? " (IPv6)" : "");
- weechat_log_printf (_("Connecting to server %s/%d%s%s via %s proxy "
+ weechat_log_printf (_("Connecting to server %s/%d%s via %s proxy "
"%s/%d%s..."),
server->current_address,
server->current_port,
- (IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6)) ?
- " (IPv6)" : "",
(IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_SSL)) ?
" (SSL)" : "",
str_proxy_type,
@@ -3767,22 +3802,18 @@ irc_server_connect (struct t_irc_server *server)
else
{
weechat_printf (server->buffer,
- _("%s%s: connecting to server %s/%d%s%s..."),
+ _("%s%s: connecting to server %s/%d%s..."),
weechat_prefix ("network"),
IRC_PLUGIN_NAME,
server->current_address,
server->current_port,
- (IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6)) ?
- " (IPv6)" : "",
(IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_SSL)) ?
" (SSL)" : "");
- weechat_log_printf (_("%s%s: connecting to server %s/%d%s%s..."),
+ weechat_log_printf (_("%s%s: connecting to server %s/%d%s..."),
"",
IRC_PLUGIN_NAME,
server->current_address,
server->current_port,
- (IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6)) ?
- " (IPv6)" : "",
(IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_SSL)) ?
" (SSL)" : "");
}
@@ -3790,55 +3821,6 @@ irc_server_connect (struct t_irc_server *server)
/* close connection if opened */
irc_server_close_connection (server);
- /* create socket and set options */
- if (proxy_type)
- {
- server->sock = socket ((weechat_config_integer (proxy_ipv6)) ?
- AF_INET6 : AF_INET,
- SOCK_STREAM, 0);
- }
- else
- {
- server->sock = socket ((IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6)) ?
- AF_INET6 : AF_INET,
- SOCK_STREAM, 0);
- }
- if (server->sock == -1)
- {
- weechat_printf (server->buffer,
- _("%s%s: cannot create socket"),
- weechat_prefix ("error"), IRC_PLUGIN_NAME);
- return 0;
- }
-
- /* set SO_REUSEADDR option for socket */
- set = 1;
- if (setsockopt (server->sock, SOL_SOCKET, SO_REUSEADDR,
- (void *) &set, sizeof (set)) == -1)
- {
- weechat_printf (server->buffer,
- _("%s%s: cannot set socket option "
- "\"SO_REUSEADDR\""),
- weechat_prefix ("error"), IRC_PLUGIN_NAME);
- }
-
- /* set SO_KEEPALIVE option for socket */
- set = 1;
- if (setsockopt (server->sock, SOL_SOCKET, SO_KEEPALIVE,
- (void *) &set, sizeof (set)) == -1)
- {
- weechat_printf (server->buffer,
- _("%s%s: cannot set socket option "
- "\"SO_KEEPALIVE\""),
- weechat_prefix ("error"), IRC_PLUGIN_NAME);
- }
-
- /* set flag O_NONBLOCK on socket */
- flags = fcntl (server->sock, F_GETFL);
- if (flags == -1)
- flags = 0;
- fcntl (server->sock, F_SETFL, flags | O_NONBLOCK);
-
/* init SSL if asked and connect */
server->ssl_connected = 0;
#ifdef HAVE_GNUTLS
@@ -3847,8 +3829,9 @@ irc_server_connect (struct t_irc_server *server)
server->hook_connect = weechat_hook_connect (proxy,
server->current_address,
server->current_port,
- server->sock,
- IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6),
+ proxy_type ? weechat_config_integer (proxy_ipv6)
+ : IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6),
+ server->current_retry,
(server->ssl_connected) ? &server->gnutls_sess : NULL,
(server->ssl_connected) ? irc_server_gnutls_callback : NULL,
IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_SSL_DHKEY_SIZE),
@@ -3860,7 +3843,9 @@ irc_server_connect (struct t_irc_server *server)
server->hook_connect = weechat_hook_connect (proxy,
server->current_address,
server->current_port,
- server->sock,
+ proxy_type ? weechat_config_integer (proxy_ipv6)
+ : IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6),
+ server->current_retry,
IRC_SERVER_OPTION_BOOLEAN(server, IRC_SERVER_OPTION_IPV6),
NULL, NULL, 0, NULL,
IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_LOCAL_HOSTNAME),
@@ -3966,6 +3951,9 @@ irc_server_disconnect (struct t_irc_server *server, int switch_address,
IRC_PLUGIN_NAME);
}
+ if (reconnect)
+ server->current_retry++;
+
if (switch_address)
irc_server_switch_address (server, 0);
else
@@ -4444,10 +4432,12 @@ irc_server_hdata_server_cb (void *data, const char *hdata_name)
WEECHAT_HDATA_VAR(struct t_irc_server, addresses_count, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, addresses_array, STRING, 0, "addresses_count", NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, ports_array, INTEGER, 0, "addresses_count", NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_server, retry_array, INTEGER, 0, "addresses_count", NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, index_current_address, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, current_address, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, current_ip, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, current_port, INTEGER, 0, NULL, NULL);
+ WEECHAT_HDATA_VAR(struct t_irc_server, current_retry, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, sock, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_irc_server, hook_connect, POINTER, 0, NULL, "hook");
WEECHAT_HDATA_VAR(struct t_irc_server, hook_fd, POINTER, 0, NULL, "hook");
@@ -4647,6 +4637,8 @@ irc_server_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "current_port", server->current_port))
return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "current_retry", server->current_retry))
+ return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "sock", server->sock))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "is_connected", server->is_connected))
@@ -4962,10 +4954,12 @@ irc_server_print_log ()
weechat_log_printf (" addresses_count. . . : %d", ptr_server->addresses_count);
weechat_log_printf (" addresses_array. . . : 0x%lx", ptr_server->addresses_array);
weechat_log_printf (" ports_array. . . . . : 0x%lx", ptr_server->ports_array);
+ weechat_log_printf (" retry_array. . . . . : 0x%lx", ptr_server->retry_array);
weechat_log_printf (" index_current_address: %d", ptr_server->index_current_address);
weechat_log_printf (" current_address. . . : '%s'", ptr_server->current_address);
weechat_log_printf (" current_ip . . . . . : '%s'", ptr_server->current_ip);
weechat_log_printf (" current_port . . . . : %d", ptr_server->current_port);
+ weechat_log_printf (" current_retry. . . . : %d", ptr_server->current_retry);
weechat_log_printf (" sock . . . . . . . . : %d", ptr_server->sock);
weechat_log_printf (" hook_connect . . . . : 0x%lx", ptr_server->hook_connect);
weechat_log_printf (" hook_fd. . . . . . . : 0x%lx", ptr_server->hook_fd);