diff options
Diffstat (limited to 'src/core/wee-network.c')
-rw-r--r-- | src/core/wee-network.c | 122 |
1 files changed, 83 insertions, 39 deletions
diff --git a/src/core/wee-network.c b/src/core/wee-network.c index 7eb94ca49..a221ff134 100644 --- a/src/core/wee-network.c +++ b/src/core/wee-network.c @@ -1,7 +1,7 @@ /* * wee-network.c - network functions * - * Copyright (C) 2003-2015 Sébastien Helleu <flashcode@flashtux.org> + * Copyright (C) 2003-2016 Sébastien Helleu <flashcode@flashtux.org> * Copyright (C) 2005-2010 Emmanuel Bouthenot <kolter@openics.org> * Copyright (C) 2010 Gu1ll4um3r0m41n <aeroxteam@gmail.com> * Copyright (C) 2012 Simon Arlott @@ -42,7 +42,9 @@ #include <poll.h> #include <netinet/in.h> #include <arpa/inet.h> +#include <arpa/nameser.h> #include <netdb.h> +#include <resolv.h> #include <errno.h> #include <gcrypt.h> #include <sys/time.h> @@ -311,6 +313,8 @@ network_resolve (const char *hostname, char *ip, int *version) res = NULL; + res_init (); + if (getaddrinfo (hostname, NULL, NULL, &res) != 0) return 0; @@ -696,6 +700,7 @@ network_connect_to (const char *proxy, struct sockaddr *address, hints.ai_flags = AI_NUMERICSERV; snprintf (str_port, sizeof (str_port), "%d", CONFIG_INTEGER(ptr_proxy->options[PROXY_OPTION_PORT])); + res_init (); if (getaddrinfo (CONFIG_STRING(ptr_proxy->options[PROXY_OPTION_ADDRESS]), str_port, &hints, &proxy_addrinfo) != 0) { @@ -806,6 +811,7 @@ network_connect_child (struct t_hook *hook_connect) #ifdef AI_ADDRCONFIG hints.ai_flags = AI_ADDRCONFIG; #endif /* AI_ADDRCONFIG */ + res_init (); if (ptr_proxy) { hints.ai_family = (CONFIG_BOOLEAN(ptr_proxy->options[PROXY_OPTION_IPV6])) ? @@ -1233,19 +1239,22 @@ end: */ int -network_connect_child_timer_cb (void *arg_hook_connect, int remaining_calls) +network_connect_child_timer_cb (const void *pointer, void *data, + int remaining_calls) { struct t_hook *hook_connect; /* make C compiler happy */ + (void) data; (void) remaining_calls; - hook_connect = (struct t_hook *)arg_hook_connect; + hook_connect = (struct t_hook *)pointer; HOOK_CONNECT(hook_connect, hook_child_timer) = NULL; (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_TIMEOUT, 0, -1, NULL, NULL); unhook (hook_connect); @@ -1262,15 +1271,17 @@ network_connect_child_timer_cb (void *arg_hook_connect, int remaining_calls) #ifdef HAVE_GNUTLS int -network_connect_gnutls_handshake_fd_cb (void *arg_hook_connect, int fd) +network_connect_gnutls_handshake_fd_cb (const void *pointer, void *data, + int fd) { struct t_hook *hook_connect; int rc, direction, flags; /* make C compiler happy */ + (void) data; (void) fd; - hook_connect = (struct t_hook *)arg_hook_connect; + hook_connect = (struct t_hook *)pointer; rc = gnutls_handshake (*HOOK_CONNECT(hook_connect, gnutls_sess)); @@ -1290,7 +1301,8 @@ network_connect_gnutls_handshake_fd_cb (void *arg_hook_connect, int fd) else if (rc != GNUTLS_E_SUCCESS) { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR, rc, HOOK_CONNECT(hook_connect, sock), gnutls_strerror (rc), @@ -1310,7 +1322,8 @@ network_connect_gnutls_handshake_fd_cb (void *arg_hook_connect, int fd) if (hook_connect_gnutls_verify_certificates (*HOOK_CONNECT(hook_connect, gnutls_sess)) != 0) { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR, rc, HOOK_CONNECT(hook_connect, sock), "Error in the certificate.", @@ -1321,10 +1334,11 @@ network_connect_gnutls_handshake_fd_cb (void *arg_hook_connect, int fd) #endif /* LIBGNUTLS_VERSION_NUMBER < 0x02090a */ unhook (HOOK_CONNECT(hook_connect, handshake_hook_fd)); (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, - WEECHAT_HOOK_CONNECT_OK, 0, - HOOK_CONNECT(hook_connect, sock), - NULL, HOOK_CONNECT(hook_connect, handshake_ip_address)); + (hook_connect->callback_pointer, + hook_connect->callback_data, + WEECHAT_HOOK_CONNECT_OK, 0, + HOOK_CONNECT(hook_connect, sock), + NULL, HOOK_CONNECT(hook_connect, handshake_ip_address)); unhook (hook_connect); } @@ -1338,25 +1352,28 @@ network_connect_gnutls_handshake_fd_cb (void *arg_hook_connect, int fd) #ifdef HAVE_GNUTLS int -network_connect_gnutls_handshake_timer_cb (void *arg_hook_connect, +network_connect_gnutls_handshake_timer_cb (const void *pointer, + void *data, int remaining_calls) { struct t_hook *hook_connect; /* make C compiler happy */ + (void) data; (void) remaining_calls; - hook_connect = (struct t_hook *)arg_hook_connect; + hook_connect = (struct t_hook *)pointer; HOOK_CONNECT(hook_connect, handshake_hook_timer) = NULL; (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, - WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR, - GNUTLS_E_EXPIRED, - HOOK_CONNECT(hook_connect, sock), - gnutls_strerror (GNUTLS_E_EXPIRED), - HOOK_CONNECT(hook_connect, handshake_ip_address)); + (hook_connect->callback_pointer, + hook_connect->callback_data, + WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR, + GNUTLS_E_EXPIRED, + HOOK_CONNECT(hook_connect, sock), + gnutls_strerror (GNUTLS_E_EXPIRED), + HOOK_CONNECT(hook_connect, handshake_ip_address)); unhook (hook_connect); return WEECHAT_RC_OK; @@ -1368,7 +1385,7 @@ network_connect_gnutls_handshake_timer_cb (void *arg_hook_connect, */ int -network_connect_child_read_cb (void *arg_hook_connect, int fd) +network_connect_child_read_cb (const void *pointer, void *data, int fd) { struct t_hook *hook_connect; char buffer[1], buf_size[6], *cb_error, *cb_ip_address, *error; @@ -1389,9 +1406,10 @@ network_connect_child_read_cb (void *arg_hook_connect, int fd) #endif /* HOOK_CONNECT_MAX_SOCKETS */ /* make C compiler happy */ + (void) data; (void) fd; - hook_connect = (struct t_hook *)arg_hook_connect; + hook_connect = (struct t_hook *)pointer; cb_error = NULL; cb_ip_address = NULL; @@ -1507,19 +1525,20 @@ network_connect_child_read_cb (void *arg_hook_connect, int fd) HOOK_CONNECT(hook_connect, sock), (!direction ? 1 : 0), (direction ? 1 : 0), 0, &network_connect_gnutls_handshake_fd_cb, - hook_connect); + hook_connect, NULL); HOOK_CONNECT(hook_connect, handshake_hook_timer) = hook_timer (hook_connect->plugin, CONFIG_INTEGER(config_network_gnutls_handshake_timeout) * 1000, 0, 1, &network_connect_gnutls_handshake_timer_cb, - hook_connect); + hook_connect, NULL); return WEECHAT_RC_OK; } else if (rc != GNUTLS_E_SUCCESS) { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR, rc, sock, gnutls_strerror (rc), @@ -1540,7 +1559,8 @@ network_connect_child_read_cb (void *arg_hook_connect, int fd) if (hook_connect_gnutls_verify_certificates (*HOOK_CONNECT(hook_connect, gnutls_sess)) != 0) { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR, rc, sock, "Error in the certificate.", @@ -1583,15 +1603,19 @@ network_connect_child_read_cb (void *arg_hook_connect, int fd) } } (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, buffer[0] - '0', 0, + (hook_connect->callback_pointer, + hook_connect->callback_data, + buffer[0] - '0', 0, sock, cb_error, cb_ip_address); unhook (hook_connect); } else { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, WEECHAT_HOOK_CONNECT_MEMORY_ERROR, - 0, sock, cb_error, cb_ip_address); + (hook_connect->callback_pointer, + hook_connect->callback_data, + WEECHAT_HOOK_CONNECT_MEMORY_ERROR, + 0, sock, "child_read_cb", NULL); unhook (hook_connect); } @@ -1628,19 +1652,35 @@ network_connect_with_fork (struct t_hook *hook_connect) if (gnutls_init (HOOK_CONNECT(hook_connect, gnutls_sess), GNUTLS_CLIENT) != GNUTLS_E_SUCCESS) { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR, 0, -1, NULL, NULL); unhook (hook_connect); return; } + rc = gnutls_server_name_set (*HOOK_CONNECT(hook_connect, gnutls_sess), + GNUTLS_NAME_DNS, + HOOK_CONNECT(hook_connect, address), + strlen (HOOK_CONNECT(hook_connect, address))); + if (rc != GNUTLS_E_SUCCESS) + { + (void) (HOOK_CONNECT(hook_connect, callback)) + (hook_connect->callback_pointer, + hook_connect->callback_data, + WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR, + 0, -1, _("set server name indication (SNI) failed"), NULL); + unhook (hook_connect); + return; + } rc = gnutls_priority_set_direct (*HOOK_CONNECT(hook_connect, gnutls_sess), HOOK_CONNECT(hook_connect, gnutls_priorities), &pos_error); if (rc != GNUTLS_E_SUCCESS) { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR, 0, -1, _("invalid priorities"), NULL); unhook (hook_connect); @@ -1658,9 +1698,10 @@ network_connect_with_fork (struct t_hook *hook_connect) if (pipe (child_pipe) < 0) { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_MEMORY_ERROR, - 0, -1, NULL, NULL); + 0, -1, "pipe", NULL); unhook (hook_connect); return; } @@ -1672,9 +1713,10 @@ network_connect_with_fork (struct t_hook *hook_connect) if (socketpair (AF_LOCAL, SOCK_DGRAM, 0, child_socket) < 0) { (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_MEMORY_ERROR, - 0, -1, NULL, NULL); + 0, -1, "socketpair", NULL); unhook (hook_connect); return; } @@ -1693,9 +1735,10 @@ network_connect_with_fork (struct t_hook *hook_connect) /* fork failed */ case -1: (void) (HOOK_CONNECT(hook_connect, callback)) - (hook_connect->callback_data, + (hook_connect->callback_pointer, + hook_connect->callback_data, WEECHAT_HOOK_CONNECT_MEMORY_ERROR, - 0, -1, NULL, NULL); + 0, -1, "fork", NULL); unhook (hook_connect); return; /* child process */ @@ -1721,10 +1764,11 @@ network_connect_with_fork (struct t_hook *hook_connect) CONFIG_INTEGER(config_network_connection_timeout) * 1000, 0, 1, &network_connect_child_timer_cb, - hook_connect); + hook_connect, + NULL); HOOK_CONNECT(hook_connect, hook_fd) = hook_fd (hook_connect->plugin, HOOK_CONNECT(hook_connect, child_read), 1, 0, 0, &network_connect_child_read_cb, - hook_connect); + hook_connect, NULL); } |