summaryrefslogtreecommitdiff
path: root/src/core/wee-network.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/wee-network.c')
-rw-r--r--src/core/wee-network.c122
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);
}