diff options
author | Andrew Potter <agpotter@gmail.com> | 2014-01-09 12:48:54 +0100 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2014-01-09 12:48:54 +0100 |
commit | 144dc60d0ab062aa5b3943d57f8f6515310f2dd5 (patch) | |
tree | 06c0e13ad72be462a3b018cf9905c5af5921ff07 /src | |
parent | 9040dfbf521b12b675b6f7d5d93bb10767a40f90 (diff) | |
download | weechat-144dc60d0ab062aa5b3943d57f8f6515310f2dd5.zip |
xfer: add support of IPv6 for DCC chat/file (patch #7992)
Diffstat (limited to 'src')
-rw-r--r-- | src/core/wee-network.c | 88 | ||||
-rw-r--r-- | src/core/wee-network.h | 7 | ||||
-rw-r--r-- | src/plugins/irc/irc-command.c | 28 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 44 | ||||
-rw-r--r-- | src/plugins/weechat-plugin.h | 15 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-buffer.c | 11 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-chat.c | 7 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-command.c | 7 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-dcc.c | 6 | ||||
-rw-r--r-- | src/plugins/xfer/xfer-network.c | 59 | ||||
-rw-r--r-- | src/plugins/xfer/xfer.c | 353 | ||||
-rw-r--r-- | src/plugins/xfer/xfer.h | 11 |
12 files changed, 393 insertions, 243 deletions
diff --git a/src/core/wee-network.c b/src/core/wee-network.c index 49b258d49..1066d2ba9 100644 --- a/src/core/wee-network.c +++ b/src/core/wee-network.c @@ -645,56 +645,84 @@ network_connect (int sock, const struct sockaddr *addr, socklen_t addrlen) * process. * * Returns: - * 1: OK - * 0: error + * >= 0: connected socket fd + * -1: error */ int -network_connect_to (const char *proxy, int sock, - unsigned long address, int port) +network_connect_to (const char *proxy, struct sockaddr *address, + socklen_t address_length) { struct t_proxy *ptr_proxy; - struct sockaddr_in addr; - struct hostent *hostent; - char *ip4; + struct addrinfo *proxy_addrinfo, hints; + char str_port[16], ip[NI_MAXHOST]; + int port, sock; + + sock = -1; + proxy_addrinfo = NULL; ptr_proxy = NULL; if (proxy && proxy[0]) { ptr_proxy = proxy_search (proxy); if (!ptr_proxy) - return 0; + return -1; } if (ptr_proxy) { - memset (&addr, 0, sizeof (addr)); - addr.sin_addr.s_addr = htonl (address); - ip4 = inet_ntoa(addr.sin_addr); - - memset (&addr, 0, sizeof (addr)); - addr.sin_port = htons (CONFIG_INTEGER(ptr_proxy->options[PROXY_OPTION_PORT])); - addr.sin_family = AF_INET; - hostent = gethostbyname (CONFIG_STRING(ptr_proxy->options[PROXY_OPTION_ADDRESS])); - if (!hostent) - return 0; - memcpy(&(addr.sin_addr), *(hostent->h_addr_list), sizeof(struct in_addr)); - if (!network_connect (sock, (struct sockaddr *) &addr, sizeof (addr))) - return 0; - if (!network_pass_proxy (proxy, sock, ip4, port)) - return 0; + /* get IP address/port */ + if (getnameinfo (address, address_length, ip, sizeof (ip), + str_port, sizeof (str_port), + NI_NUMERICHOST | NI_NUMERICSERV) != 0) + { + goto error; + } + port = atoi (str_port); + + /* get sockaddr for proxy */ + memset (&hints, 0, sizeof (hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICSERV; + snprintf (str_port, sizeof (str_port), "%d", + CONFIG_INTEGER(ptr_proxy->options[PROXY_OPTION_PORT])); + if (getaddrinfo (CONFIG_STRING(ptr_proxy->options[PROXY_OPTION_ADDRESS]), + str_port, &hints, &proxy_addrinfo) != 0) + { + goto error; + } + + /* connect and pass address to proxy */ + sock = socket (proxy_addrinfo->ai_family, SOCK_STREAM, 0); + if (sock == -1) + goto error; + if (!network_connect (sock, proxy_addrinfo->ai_addr, + proxy_addrinfo->ai_addrlen)) + goto error; + if (!network_pass_proxy (proxy, sock, ip, port)) + goto error; } else { - memset (&addr, 0, sizeof (addr)); - addr.sin_port = htons (port); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl (address); - if (!network_connect (sock, (struct sockaddr *) &addr, sizeof (addr))) - return 0; + sock = socket (address->sa_family, SOCK_STREAM, 0); + if (sock == -1) + goto error; + if (!network_connect (sock, address, address_length)) + goto error; } - return 1; + if (proxy_addrinfo) + freeaddrinfo (proxy_addrinfo); + + return sock; + +error: + if (sock >= 0) + close (sock); + if (proxy_addrinfo) + freeaddrinfo (proxy_addrinfo); + return -1; } /* diff --git a/src/core/wee-network.h b/src/core/wee-network.h index 59ba9c455..c1b1c96b7 100644 --- a/src/core/wee-network.h +++ b/src/core/wee-network.h @@ -20,6 +20,9 @@ #ifndef __WEECHAT_NETWORK_H #define __WEECHAT_NETWORK_H 1 +#include <sys/types.h> +#include <sys/socket.h> + struct t_hook; struct t_network_socks4 @@ -48,8 +51,8 @@ extern void network_init_gnutls (); extern void network_end (); extern int network_pass_proxy (const char *proxy, int sock, const char *address, int port); -extern int network_connect_to (const char *proxy, int sock, - unsigned long address, int port); +extern int network_connect_to (const char *proxy, struct sockaddr *address, + socklen_t address_length); extern void network_connect_with_fork (struct t_hook *hook_connect); #endif /* __WEECHAT_NETWORK_H */ diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c index 3b643036e..82b5cd4fa 100644 --- a/src/plugins/irc/irc-command.c +++ b/src/plugins/irc/irc-command.c @@ -29,6 +29,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <netdb.h> #include "../weechat-plugin.h" #include "irc.h" @@ -1380,12 +1381,12 @@ int irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc, char **argv, char **argv_eol) { - struct sockaddr_in addr; + struct sockaddr_storage addr; socklen_t length; - unsigned long address; struct t_infolist *infolist; struct t_infolist_item *item; - char str_address[128], charset_modifier[256]; + char str_address[NI_MAXHOST], charset_modifier[256]; + int rc; IRC_BUFFER_GET_SERVER_CHANNEL(buffer); IRC_COMMAND_CHECK_SERVER("dcc", 1); @@ -1396,11 +1397,20 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) { /* use the local interface, from the server socket */ - memset (&addr, 0, sizeof (struct sockaddr_in)); + memset (&addr, 0, sizeof (addr)); length = sizeof (addr); - getsockname (ptr_server->sock, (struct sockaddr *) &addr, &length); - addr.sin_family = AF_INET; - address = ntohl (addr.sin_addr.s_addr); + getsockname (ptr_server->sock, (struct sockaddr *)&addr, &length); + rc = getnameinfo ((struct sockaddr *)&addr, length, str_address, + sizeof (str_address), NULL, 0, NI_NUMERICHOST); + if (rc != 0) + { + weechat_printf (ptr_server->buffer, + _("%s%s: unable to resolve local address of server " + "socket: error %d %s"), + weechat_prefix ("error"), IRC_PLUGIN_NAME, + rc, gai_strerror (rc)); + return WEECHAT_RC_OK; + } /* DCC SEND file */ if (weechat_strcasecmp (argv[1], "send") == 0) @@ -1422,8 +1432,6 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc, weechat_infolist_new_var_string (item, "remote_nick", argv[2]); weechat_infolist_new_var_string (item, "local_nick", ptr_server->nick); weechat_infolist_new_var_string (item, "filename", argv_eol[3]); - snprintf (str_address, sizeof (str_address), - "%lu", address); weechat_infolist_new_var_string (item, "local_address", str_address); weechat_infolist_new_var_integer (item, "socket", ptr_server->sock); weechat_hook_signal_send ("xfer_add", @@ -1454,8 +1462,6 @@ irc_command_dcc (void *data, struct t_gui_buffer *buffer, int argc, snprintf (charset_modifier, sizeof (charset_modifier), "irc.%s.%s", ptr_server->name, argv[2]); weechat_infolist_new_var_string (item, "charset_modifier", charset_modifier); - snprintf (str_address, sizeof (str_address), - "%lu", address); weechat_infolist_new_var_string (item, "local_address", str_address); weechat_hook_signal_send ("xfer_add", WEECHAT_HOOK_SIGNAL_POINTER, diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index b8acff11a..05e78fca3 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -36,6 +36,9 @@ #include <sys/socket.h> #include <sys/time.h> #endif +#include <sys/types.h> +#include <netdb.h> +#include <arpa/inet.h> #ifdef HAVE_GNUTLS #include <gnutls/gnutls.h> @@ -4402,8 +4405,11 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal, { struct t_infolist *infolist; struct t_irc_server *ptr_server; - const char *plugin_name, *plugin_id, *type, *filename; - int spaces_in_name; + const char *plugin_name, *plugin_id, *type, *filename, *local_address; + char converted_addr[NI_MAXHOST]; + struct addrinfo *ainfo; + struct sockaddr_in *saddr; + int spaces_in_name, rc; /* make C compiler happy */ (void) data; @@ -4416,14 +4422,40 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal, { plugin_name = weechat_infolist_string (infolist, "plugin_name"); plugin_id = weechat_infolist_string (infolist, "plugin_id"); - if (plugin_name && (strcmp (plugin_name, IRC_PLUGIN_NAME) == 0) && plugin_id) + if (plugin_name && (strcmp (plugin_name, IRC_PLUGIN_NAME) == 0) + && plugin_id) { ptr_server = irc_server_search (plugin_id); if (ptr_server) { + converted_addr[0] = '\0'; + local_address = weechat_infolist_string (infolist, + "local_address"); + if (local_address) + { + rc = getaddrinfo (local_address, NULL, NULL, &ainfo); + if ((rc == 0) && ainfo && ainfo->ai_addr) + { + if (ainfo->ai_family == AF_INET) + { + /* transform dotted 4 IP address to ulong string */ + saddr = (struct sockaddr_in *)ainfo->ai_addr; + snprintf (converted_addr, sizeof (converted_addr), + "%lu", + (unsigned long)ntohl (saddr->sin_addr.s_addr)); + } + else + { + snprintf (converted_addr, sizeof (converted_addr), + "%s", local_address); + } + } + } + type = weechat_infolist_string (infolist, "type_string"); - if (type) + if (type && converted_addr[0]) { + /* send DCC PRIVMSG */ if (strcmp (type, "file_send") == 0) { filename = weechat_infolist_string (infolist, "filename"); @@ -4436,7 +4468,7 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal, (spaces_in_name) ? "\"" : "", filename, (spaces_in_name) ? "\"" : "", - weechat_infolist_string (infolist, "local_address"), + converted_addr, weechat_infolist_integer (infolist, "port"), weechat_infolist_string (infolist, "size")); } @@ -4446,7 +4478,7 @@ irc_server_xfer_send_ready_cb (void *data, const char *signal, IRC_SERVER_SEND_OUTQ_PRIO_HIGH, NULL, "PRIVMSG %s :\01DCC CHAT chat %s %d\01", weechat_infolist_string (infolist, "remote_nick"), - weechat_infolist_string (infolist, "local_address"), + converted_addr, weechat_infolist_integer (infolist, "port")); } } diff --git a/src/plugins/weechat-plugin.h b/src/plugins/weechat-plugin.h index 00d5ca826..10452126f 100644 --- a/src/plugins/weechat-plugin.h +++ b/src/plugins/weechat-plugin.h @@ -27,6 +27,7 @@ extern "C" { #endif #include <sys/types.h> +#include <sys/socket.h> /* some systems like GNU/Hurd do not define PATH_MAX */ #ifndef PATH_MAX @@ -56,7 +57,7 @@ struct timeval; * please change the date with current one; for a second change at same * date, increment the 01, otherwise please keep 01. */ -#define WEECHAT_PLUGIN_API_VERSION "20140105-01" +#define WEECHAT_PLUGIN_API_VERSION "20140109-01" /* macros for defining plugin infos */ #define WEECHAT_PLUGIN_NAME(__name) \ @@ -807,8 +808,9 @@ struct t_weechat_plugin /* network */ int (*network_pass_proxy) (const char *proxy, int sock, const char *address, int port); - int (*network_connect_to) (const char *proxy, int sock, - unsigned long address, int port); + int (*network_connect_to) (const char *proxy, + struct sockaddr *address, + socklen_t address_length); /* infos */ const char *(*info_get) (struct t_weechat_plugin *plugin, @@ -1587,9 +1589,10 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin); #define weechat_network_pass_proxy(__proxy, __sock, __address, __port) \ weechat_plugin->network_pass_proxy(__proxy, __sock, __address, \ __port) -#define weechat_network_connect_to(__proxy, __sock, __address, __port) \ - weechat_plugin->network_connect_to(__proxy, __sock, __address, \ - __port) +#define weechat_network_connect_to(__proxy, __address, \ + __address_length) \ + weechat_plugin->network_connect_to(__proxy, __address, \ + __address_length) /* infos */ #define weechat_info_get(__info_name, __arguments) \ diff --git a/src/plugins/xfer/xfer-buffer.c b/src/plugins/xfer/xfer-buffer.c index 7a88c2e82..7f356b105 100644 --- a/src/plugins/xfer/xfer-buffer.c +++ b/src/plugins/xfer/xfer-buffer.c @@ -44,7 +44,7 @@ xfer_buffer_refresh (const char *hotlist) { struct t_xfer *ptr_xfer, *xfer_selected; char str_color[256], suffix[32], status[64], date[128], eta[128]; - char str_ip[32], str_hash[128]; + char str_ip[128], str_hash[128]; char *progress_bar, *str_pos, *str_total, *str_bytes_per_sec; int i, length, line, progress_bar_size, num_bars; unsigned long long pos, pct_complete; @@ -93,14 +93,11 @@ xfer_buffer_refresh (const char *hotlist) weechat_config_string (xfer_config_color_text_bg)); str_ip[0] = '\0'; - if (ptr_xfer->remote_address != 0) + if (ptr_xfer->remote_address_str) { snprintf (str_ip, sizeof (str_ip), - " (%ld.%ld.%ld.%ld)", - ptr_xfer->remote_address >> 24, - (ptr_xfer->remote_address >> 16) & 0xff, - (ptr_xfer->remote_address >> 8) & 0xff, - ptr_xfer->remote_address & 0xff); + " (%s)", + ptr_xfer->remote_address_str); } str_hash[0] = '\0'; diff --git a/src/plugins/xfer/xfer-chat.c b/src/plugins/xfer/xfer-chat.c index cf9b5202b..c465d4f22 100644 --- a/src/plugins/xfer/xfer-chat.c +++ b/src/plugins/xfer/xfer-chat.c @@ -372,14 +372,11 @@ xfer_chat_open_buffer (struct t_xfer *xfer) } weechat_printf (xfer->buffer, - _("%s%s: connected to %s (%ld.%ld.%ld.%ld)"), + _("%s%s: connected to %s (%s) via xfer chat"), weechat_prefix ("network"), XFER_PLUGIN_NAME, xfer->remote_nick, - xfer->remote_address >> 24, - (xfer->remote_address >> 16) & 0xff, - (xfer->remote_address >> 8) & 0xff, - xfer->remote_address & 0xff); + xfer->remote_address_str); free (name); } diff --git a/src/plugins/xfer/xfer-command.c b/src/plugins/xfer/xfer-command.c index 3a08774f0..dd6cb6693 100644 --- a/src/plugins/xfer/xfer-command.c +++ b/src/plugins/xfer/xfer-command.c @@ -157,15 +157,12 @@ xfer_command_xfer_list (int full) weechat_printf (NULL, _(" plugin: %s (id: %s), file: %llu " "bytes (position: %llu), address: " - "%ld.%ld.%ld.%ld (port %d)"), + "%s (port %d)"), ptr_xfer->plugin_name, ptr_xfer->plugin_id, ptr_xfer->size, ptr_xfer->pos, - ptr_xfer->remote_address >> 24, - (ptr_xfer->remote_address >> 16) & 0xff, - (ptr_xfer->remote_address >> 8) & 0xff, - ptr_xfer->remote_address & 0xff, + ptr_xfer->remote_address_str, ptr_xfer->port); date[0] = '\0'; date_tmp = localtime (&(ptr_xfer->start_transfer)); diff --git a/src/plugins/xfer/xfer-dcc.c b/src/plugins/xfer/xfer-dcc.c index 8060ac8b8..113dc7765 100644 --- a/src/plugins/xfer/xfer-dcc.c +++ b/src/plugins/xfer/xfer-dcc.c @@ -327,8 +327,10 @@ xfer_dcc_recv_file_child (struct t_xfer *xfer) } /* first connect to sender (blocking) */ - if (!weechat_network_connect_to (xfer->proxy, xfer->sock, - xfer->remote_address, xfer->port)) + xfer->sock = weechat_network_connect_to (xfer->proxy, + xfer->remote_address, + xfer->remote_address_length); + if (xfer->sock == -1) { xfer_network_write_pipe (xfer, XFER_STATUS_FAILED, XFER_ERROR_CONNECT_SENDER); diff --git a/src/plugins/xfer/xfer-network.c b/src/plugins/xfer/xfer-network.c index 57d163f92..fb9b18ac8 100644 --- a/src/plugins/xfer/xfer-network.c +++ b/src/plugins/xfer/xfer-network.c @@ -253,14 +253,11 @@ xfer_network_send_file_fork (struct t_xfer *xfer) } weechat_printf (NULL, - _("%s: sending file to %s (%ld.%ld.%ld.%ld, %s.%s), " + _("%s: sending file to %s (%s, %s.%s), " "name: %s (local filename: %s), %llu bytes (protocol: %s)"), XFER_PLUGIN_NAME, xfer->remote_nick, - xfer->remote_address >> 24, - (xfer->remote_address >> 16) & 0xff, - (xfer->remote_address >> 8) & 0xff, - xfer->remote_address & 0xff, + xfer->remote_address_str, xfer->plugin_name, xfer->plugin_id, xfer->filename, @@ -375,12 +372,15 @@ xfer_network_fd_cb (void *arg_xfer, int fd) { struct t_xfer *xfer; int sock, flags, error; - struct sockaddr_in addr; + struct sockaddr_storage addr; socklen_t length; + char str_address[NI_MAXHOST]; /* make C compiler happy */ (void) fd; + length = sizeof (addr); + memset (&addr, 0, length); xfer = (struct t_xfer *)arg_xfer; if (xfer->status == XFER_STATUS_CONNECTING) @@ -388,7 +388,6 @@ xfer_network_fd_cb (void *arg_xfer, int fd) if (xfer->type == XFER_TYPE_FILE_SEND) { xfer->last_activity = time (NULL); - length = sizeof (addr); sock = accept (xfer->sock, (struct sockaddr *) &addr, &length); error = errno; @@ -422,7 +421,15 @@ xfer_network_fd_cb (void *arg_xfer, int fd) xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } - xfer->remote_address = ntohl (addr.sin_addr.s_addr); + error = getnameinfo ((struct sockaddr *)&addr, length, str_address, + sizeof (str_address), NULL, 0, NI_NUMERICHOST); + if (error != 0) + { + snprintf (str_address, sizeof (str_address), + "error: %s", gai_strerror (error)); + } + xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length, + str_address); xfer->status = XFER_STATUS_ACTIVE; xfer->start_transfer = time (NULL); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); @@ -467,7 +474,15 @@ xfer_network_fd_cb (void *arg_xfer, int fd) xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); return WEECHAT_RC_OK; } - xfer->remote_address = ntohl (addr.sin_addr.s_addr); + error = getnameinfo ((struct sockaddr *)&addr, length, str_address, + sizeof (str_address), NULL, 0, NI_NUMERICHOST); + if (error != 0) + { + snprintf (str_address, sizeof (str_address), + "error: %s", gai_strerror (error)); + } + xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length, + str_address); xfer->status = XFER_STATUS_ACTIVE; xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); xfer->hook_fd = weechat_hook_fd (xfer->sock, @@ -528,15 +543,17 @@ xfer_network_connect (struct t_xfer *xfer) else xfer->status = XFER_STATUS_CONNECTING; - if (xfer->sock < 0) + if (XFER_IS_SEND(xfer->type)) { - xfer->sock = socket (AF_INET, SOCK_STREAM, 0); + /* create socket */ if (xfer->sock < 0) - return 0; - } + { + xfer->sock = socket (xfer->remote_address->sa_family, SOCK_STREAM, + 0); + if (xfer->sock < 0) + return 0; + } - if (XFER_IS_SEND(xfer->type)) - { /* listen to socket */ flags = fcntl (xfer->sock, F_GETFL); if (flags == -1) @@ -566,13 +583,21 @@ xfer_network_connect (struct t_xfer *xfer) /* for chat receiving, connect to listening host */ if (xfer->type == XFER_TYPE_CHAT_RECV) { + xfer->sock = weechat_network_connect_to (xfer->proxy, + xfer->remote_address, + xfer->remote_address_length); + if (xfer->sock < 0) + return 0; + flags = fcntl (xfer->sock, F_GETFL); if (flags == -1) flags = 0; if (fcntl (xfer->sock, F_SETFL, flags | O_NONBLOCK) == -1) + { + close (xfer->sock); + xfer->sock = -1; return 0; - weechat_network_connect_to (xfer->proxy, xfer->sock, - xfer->remote_address, xfer->port); + } xfer->hook_fd = weechat_hook_fd (xfer->sock, 1, 0, 0, diff --git a/src/plugins/xfer/xfer.c b/src/plugins/xfer/xfer.c index 9233701df..51621d82c 100644 --- a/src/plugins/xfer/xfer.c +++ b/src/plugins/xfer/xfer.c @@ -31,6 +31,7 @@ #include <netinet/in.h> #include <netdb.h> #include <gcrypt.h> +#include <arpa/inet.h> #include "../weechat-plugin.h" #include "xfer.h" @@ -300,16 +301,13 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status) if (XFER_IS_FILE(xfer->type)) { weechat_printf (NULL, - _("%s%s: file %s %s %s (%ld.%ld.%ld.%ld): %s"), + _("%s%s: file %s %s %s (%s): %s"), (xfer->status == XFER_STATUS_DONE) ? "" : weechat_prefix ("error"), XFER_PLUGIN_NAME, xfer->filename, (xfer->type == XFER_TYPE_FILE_SEND) ? _("sent to") : _("received from"), xfer->remote_nick, - xfer->remote_address >> 24, - (xfer->remote_address >> 16) & 0xff, - (xfer->remote_address >> 8) & 0xff, - xfer->remote_address & 0xff, + xfer->remote_address_str, (xfer->status == XFER_STATUS_DONE) ? _("OK") : _("FAILED")); xfer_network_child_kill (xfer); } @@ -320,14 +318,11 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status) { weechat_printf (xfer->buffer, _("%s%s: chat closed with %s " - "(%ld.%ld.%ld.%ld)"), + "(%s)"), weechat_prefix ("network"), XFER_PLUGIN_NAME, xfer->remote_nick, - xfer->remote_address >> 24, - (xfer->remote_address >> 16) & 0xff, - (xfer->remote_address >> 8) & 0xff, - xfer->remote_address & 0xff); + xfer->remote_address_str); } } @@ -457,8 +452,12 @@ xfer_alloc () /* default values */ new_xfer->filename = NULL; new_xfer->size = 0; - new_xfer->local_address = 0; - new_xfer->remote_address = 0; + new_xfer->local_address = NULL; + new_xfer->local_address_length = 0; + new_xfer->local_address_str = NULL; + new_xfer->remote_address = NULL; + new_xfer->remote_address_length = 0; + new_xfer->remote_address_str = NULL; new_xfer->port = 0; new_xfer->remote_nick = NULL; new_xfer->local_nick = NULL; @@ -616,11 +615,14 @@ xfer_new (const char *plugin_name, const char *plugin_id, enum t_xfer_type type, enum t_xfer_protocol protocol, const char *remote_nick, const char *local_nick, const char *charset_modifier, const char *filename, - unsigned long long size, const char *proxy, unsigned long address, - int port, int sock, const char *local_filename) + unsigned long long size, const char *proxy, struct sockaddr *address, + socklen_t address_length, int port, int sock, + const char *local_filename) { struct t_xfer *new_xfer; const char *ptr_color, *ptr_crc32; + char str_address[NI_MAXHOST]; + int rc; new_xfer = xfer_alloc (); if (!new_xfer) @@ -653,17 +655,36 @@ xfer_new (const char *plugin_name, const char *plugin_id, new_xfer->filename = strdup (_("xfer chat")); new_xfer->size = size; new_xfer->proxy = (proxy) ? strdup (proxy) : NULL; + new_xfer->port = port; + + rc = getnameinfo ((struct sockaddr *)address, address_length, str_address, + sizeof (str_address), NULL, 0, NI_NUMERICHOST); + if (rc != 0) + { + weechat_printf (NULL, + _("%s%s: unable to interpret address: error %d %s"), + weechat_prefix ("error"), XFER_PLUGIN_NAME, + rc, gai_strerror (rc)); + snprintf (str_address, sizeof (str_address), "?"); + } + + new_xfer->local_address = calloc (1, sizeof (struct sockaddr_storage)); + new_xfer->local_address_length = sizeof (struct sockaddr_storage); + new_xfer->remote_address = calloc (1, sizeof (struct sockaddr_storage)); + new_xfer->remote_address_length = sizeof (struct sockaddr_storage); + if (XFER_IS_RECV(type)) { - new_xfer->local_address = 0; - new_xfer->remote_address = address; + new_xfer->local_address_str = strdup (""); + new_xfer->remote_address_str = strdup (str_address); + memcpy (new_xfer->remote_address, address, address_length); } else { - new_xfer->local_address = address; - new_xfer->remote_address = 0; + new_xfer->local_address_str = strdup (str_address); + memcpy (new_xfer->local_address, address, address_length); + new_xfer->remote_address_str = strdup (""); } - new_xfer->port = port; new_xfer->status = XFER_STATUS_WAITING; new_xfer->sock = sock; @@ -708,14 +729,11 @@ xfer_new (const char *plugin_name, const char *plugin_id, case XFER_TYPE_FILE_RECV: weechat_printf (NULL, _("%s: incoming file from %s " - "(%ld.%ld.%ld.%ld, %s.%s), name: %s, %llu bytes " + "(%s, %s.%s), name: %s, %llu bytes " "(protocol: %s)"), XFER_PLUGIN_NAME, remote_nick, - address >> 24, - (address >> 16) & 0xff, - (address >> 8) & 0xff, - address & 0xff, + str_address, plugin_name, plugin_id, filename, @@ -740,13 +758,10 @@ xfer_new (const char *plugin_name, const char *plugin_id, case XFER_TYPE_CHAT_RECV: weechat_printf (NULL, _("%s: incoming chat request from %s " - "(%ld.%ld.%ld.%ld, %s.%s)"), + "(%s, %s.%s)"), XFER_PLUGIN_NAME, remote_nick, - address >> 24, - (address >> 16) & 0xff, - (address >> 8) & 0xff, - address & 0xff, + str_address, plugin_name, plugin_id); xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE); @@ -815,6 +830,25 @@ xfer_new (const char *plugin_name, const char *plugin_id, } /* + * Sets the remote address field. + */ + +void +xfer_set_remote_address (struct t_xfer *xfer, struct sockaddr *address, + socklen_t length, char *address_str) +{ + if (xfer->remote_address) + free (xfer->remote_address); + xfer->remote_address = calloc (1, length); + xfer->remote_address_length = length; + memcpy (xfer->remote_address, address, length); + + if (xfer->remote_address_str) + free (xfer->remote_address_str); + xfer->remote_address_str = strdup ((address_str) ? address_str : ""); +} + +/* * Frees xfer struct and removes it from list. */ @@ -850,6 +884,14 @@ xfer_free (struct t_xfer *xfer) free (xfer->charset_modifier); if (xfer->filename) free (xfer->filename); + if (xfer->local_address) + free (xfer->local_address); + if (xfer->local_address_str) + free (xfer->local_address_str); + if (xfer->remote_address) + free (xfer->remote_address); + if (xfer->remote_address_str) + free (xfer->remote_address_str); if (xfer->remote_nick_color) free (xfer->remote_nick_color); if (xfer->unterminated_message) @@ -884,15 +926,13 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, struct t_infolist *infolist; const char *plugin_name, *plugin_id, *str_type, *str_protocol; const char *remote_nick, *local_nick, *charset_modifier, *filename, *proxy; - int type, protocol, args, port_start, port_end, sock, port; - const char *weechat_dir; - char *dir1, *dir2, *filename2, *short_filename, *pos; + const char *weechat_dir, *str_address, *str_port; + int type, protocol, args, port_start, port_end, sock, port, rc, own_ip_used; + char *dir1, *dir2, *filename2, *short_filename, *pos, str_port_temp[16]; struct stat st; - struct hostent *host; - struct sockaddr_in addr; + struct addrinfo *ainfo, hints; + struct sockaddr_storage addr; socklen_t length; - struct in_addr tmpaddr; - unsigned long local_addr; unsigned long long file_size; struct t_xfer *ptr_xfer; @@ -921,6 +961,7 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, filename2 = NULL; short_filename = NULL; + file_size = 0; sock = -1; port = 0; @@ -974,10 +1015,6 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, } } - filename2 = NULL; - file_size = 0; - port = 0; - if (type == XFER_TYPE_FILE_RECV) { filename2 = strdup (filename); @@ -1029,10 +1066,8 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, if (filename2[strlen (filename2) - 1] != DIR_SEPARATOR_CHAR) strcat (filename2, DIR_SEPARATOR); strcat (filename2, filename); - if (dir1) - free (dir1); - if (dir2) - free (dir2); + free (dir1); + free (dir2); } #endif /* check if file exists */ @@ -1042,66 +1077,75 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, _("%s%s: cannot access file \"%s\""), weechat_prefix ("error"), XFER_PLUGIN_NAME, filename2); - if (filename2) - free (filename2); goto error; } file_size = st.st_size; } + port = weechat_infolist_integer (infolist, "port"); + + /* set address */ + memset (&hints, 0, sizeof (struct addrinfo)); + hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; + hints.ai_family = AF_UNSPEC; /* allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + own_ip_used = 0; if (XFER_IS_RECV(type)) { - sscanf (weechat_infolist_string (infolist, "remote_address"), "%lu", &local_addr); - port = weechat_infolist_integer (infolist, "port"); + str_address = weechat_infolist_string (infolist, "remote_address"); + snprintf (str_port_temp, sizeof (str_port_temp), "%d", port); + str_port = str_port_temp; } else { - /* get local IP address */ - sscanf (weechat_infolist_string (infolist, "local_address"), "%lu", &local_addr); - - memset (&addr, 0, sizeof (struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl (local_addr); - - /* look up the IP address from network_own_ip, if set */ - if (weechat_config_string(xfer_config_network_own_ip) - && weechat_config_string(xfer_config_network_own_ip)[0]) + str_port = NULL; + if (weechat_config_string (xfer_config_network_own_ip) + && weechat_config_string (xfer_config_network_own_ip)[0]) { - host = gethostbyname (weechat_config_string (xfer_config_network_own_ip)); - if (host) - { - memcpy (&tmpaddr, host->h_addr_list[0], sizeof(struct in_addr)); - local_addr = ntohl (tmpaddr.s_addr); - - sock = weechat_infolist_integer (infolist, "socket"); - if (sock > 0) - { - memset (&addr, 0, sizeof (struct sockaddr_in)); - length = sizeof (addr); - getsockname (sock, (struct sockaddr *) &addr, &length); - addr.sin_family = AF_INET; - } - } - else - { - weechat_printf (NULL, - _("%s%s: could not find address for \"%s\", " - "falling back to local IP"), - weechat_prefix ("error"), XFER_PLUGIN_NAME, - weechat_config_string (xfer_config_network_own_ip)); - } + str_address = weechat_config_string (xfer_config_network_own_ip); + hints.ai_flags = AI_NUMERICSERV; + own_ip_used = 1; } + else + str_address = weechat_infolist_string (infolist, "local_address"); + } + + rc = getaddrinfo (str_address, str_port, &hints, &ainfo); + if ((rc == 0) && ainfo && ainfo->ai_addr) + { + memset (&addr, 0, sizeof (addr)); + memcpy (&addr, ainfo->ai_addr, ainfo->ai_addrlen); + length = ainfo->ai_addrlen; + freeaddrinfo (ainfo); + } + else + { + weechat_printf (NULL, + (own_ip_used) ? + _("%s%s: invalid address \"%s\" (option " + "xfer.network.own_ip): error %d %s") : + _("%s%s: unable to find address for \"%s\": " + "error %d %s"), + weechat_prefix ("error"), XFER_PLUGIN_NAME, + str_address, rc, gai_strerror (rc)); + goto error; + } + if (XFER_IS_SEND(type)) + { /* open socket for xfer */ - sock = socket (AF_INET, SOCK_STREAM, 0); + sock = socket (addr.ss_family, SOCK_STREAM, 0); if (sock < 0) { weechat_printf (NULL, _("%s%s: cannot create socket for xfer: error %d %s"), weechat_prefix ("error"), XFER_PLUGIN_NAME, errno, strerror (errno)); - if (filename2) - free (filename2); goto error; } @@ -1126,8 +1170,11 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, if (!xfer_port_in_use (port)) { /* attempt to bind to the free port */ - addr.sin_port = htons (port); - if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == 0) + if (addr.ss_family == AF_INET) + ((struct sockaddr_in *)&addr)->sin_port = htons (port); + else + ((struct sockaddr_in6 *)&addr)->sin6_port = htons (port); + if (bind (sock, (struct sockaddr *)&addr, length) == 0) break; } port++; @@ -1141,12 +1188,13 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, if (port == 0) { /* find port automatically */ - addr.sin_port = 0; - if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == 0) + if (bind (sock, (struct sockaddr *)&addr, length) == 0) { - length = sizeof (addr); - getsockname (sock, (struct sockaddr *) &addr, &length); - port = ntohs (addr.sin_port); + getsockname (sock, (struct sockaddr *)&addr, &length); + if (addr.ss_family == AF_INET) + port = ntohs (((struct sockaddr_in *)&addr)->sin_port); + else + port = ntohs (((struct sockaddr_in6 *)&addr)->sin6_port); } else port = -1; @@ -1159,8 +1207,6 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, _("%s%s: cannot find available port for xfer"), weechat_prefix ("error"), XFER_PLUGIN_NAME); close (sock); - if (filename2) - free (filename2); goto error; } } @@ -1198,14 +1244,20 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, /* add xfer entry and listen to socket if type is file or chat "send" */ if (XFER_IS_FILE(type)) + { ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol, remote_nick, local_nick, charset_modifier, - short_filename, file_size, proxy, local_addr, - port, sock, filename2); + short_filename, file_size, proxy, + (struct sockaddr *)&addr, length, port, sock, + filename2); + } else + { ptr_xfer = xfer_new (plugin_name, plugin_id, type, protocol, remote_nick, local_nick, charset_modifier, NULL, - 0, proxy, local_addr, port, sock, NULL); + 0, proxy, (struct sockaddr *)&addr, length, + port, sock, NULL); + } if (!ptr_xfer) { @@ -1213,10 +1265,6 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, _("%s%s: error creating xfer"), weechat_prefix ("error"), XFER_PLUGIN_NAME); close (sock); - if (short_filename) - free (short_filename); - if (filename2) - free (filename2); goto error; } @@ -1224,15 +1272,18 @@ xfer_add_cb (void *data, const char *signal, const char *type_data, if (XFER_IS_SEND(ptr_xfer->type) && !XFER_HAS_ENDED(ptr_xfer->status)) xfer_send_signal (ptr_xfer, "xfer_send_ready"); - if (short_filename) - free (short_filename); if (filename2) free (filename2); - + if (short_filename) + free (short_filename); weechat_infolist_reset_item_cursor (infolist); return WEECHAT_RC_OK; error: + if (filename2) + free (filename2); + if (short_filename) + free (short_filename); weechat_infolist_reset_item_cursor (infolist); return WEECHAT_RC_ERROR; } @@ -1458,11 +1509,9 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer) return 0; if (!weechat_infolist_new_var_string (ptr_item, "proxy", xfer->proxy)) return 0; - snprintf (value, sizeof (value), "%lu", xfer->local_address); - if (!weechat_infolist_new_var_string (ptr_item, "local_address", value)) + if (!weechat_infolist_new_var_string (ptr_item, "local_address", xfer->local_address_str)) return 0; - snprintf (value, sizeof (value), "%lu", xfer->remote_address); - if (!weechat_infolist_new_var_string (ptr_item, "remote_address", value)) + if (!weechat_infolist_new_var_string (ptr_item, "remote_address", xfer->remote_address_str)) return 0; if (!weechat_infolist_new_var_integer (ptr_item, "port", xfer->port)) return 0; @@ -1548,57 +1597,61 @@ xfer_print_log () { weechat_log_printf (""); weechat_log_printf ("[xfer (addr:0x%lx)]", ptr_xfer); - weechat_log_printf (" plugin_name . . . . : '%s'", ptr_xfer->plugin_name); - weechat_log_printf (" plugin_id . . . . . : '%s'", ptr_xfer->plugin_id); - weechat_log_printf (" type. . . . . . . . : %d (%s)", + weechat_log_printf (" plugin_name . . . . . . : '%s'", ptr_xfer->plugin_name); + weechat_log_printf (" plugin_id . . . . . . . : '%s'", ptr_xfer->plugin_id); + weechat_log_printf (" type. . . . . . . . . . : %d (%s)", ptr_xfer->type, xfer_type_string[ptr_xfer->type]); - weechat_log_printf (" protocol. . . . . . : %d (%s)", + weechat_log_printf (" protocol. . . . . . . . : %d (%s)", ptr_xfer->protocol, xfer_protocol_string[ptr_xfer->protocol]); - weechat_log_printf (" remote_nick . . . . : '%s'", ptr_xfer->remote_nick); - weechat_log_printf (" local_nick. . . . . : '%s'", ptr_xfer->local_nick); - weechat_log_printf (" charset_modifier. . : '%s'", ptr_xfer->charset_modifier); - weechat_log_printf (" filename. . . . . . : '%s'", ptr_xfer->filename); - weechat_log_printf (" size. . . . . . . . : %llu", ptr_xfer->size); - weechat_log_printf (" proxy . . . . . . . : '%s'", ptr_xfer->proxy); - weechat_log_printf (" local_address . . . : %lu", ptr_xfer->local_address); - weechat_log_printf (" remote_address. . . : %lu", ptr_xfer->remote_address); - weechat_log_printf (" port. . . . . . . . : %d", ptr_xfer->port); - - weechat_log_printf (" status. . . . . . . : %d (%s)", + weechat_log_printf (" remote_nick . . . . . . : '%s'", ptr_xfer->remote_nick); + weechat_log_printf (" local_nick. . . . . . . : '%s'", ptr_xfer->local_nick); + weechat_log_printf (" charset_modifier. . . . : '%s'", ptr_xfer->charset_modifier); + weechat_log_printf (" filename. . . . . . . . : '%s'", ptr_xfer->filename); + weechat_log_printf (" size. . . . . . . . . . : %llu", ptr_xfer->size); + weechat_log_printf (" proxy . . . . . . . . . : '%s'", ptr_xfer->proxy); + weechat_log_printf (" local_address . . . . . : 0x%lx", ptr_xfer->local_address); + weechat_log_printf (" local_address_length. . : %d", ptr_xfer->local_address_length); + weechat_log_printf (" local_address_str . . . : '%s'" , ptr_xfer->local_address_str); + weechat_log_printf (" remote_address. . . . . : 0x%lx", ptr_xfer->remote_address); + weechat_log_printf (" remote_address_length . : %d", ptr_xfer->remote_address_length); + weechat_log_printf (" remote_address_str. . . : '%s'", ptr_xfer->remote_address_str); + weechat_log_printf (" port. . . . . . . . . . : %d", ptr_xfer->port); + + weechat_log_printf (" status. . . . . . . . . : %d (%s)", ptr_xfer->status, xfer_status_string[ptr_xfer->status]); - weechat_log_printf (" buffer. . . . . . . : 0x%lx", ptr_xfer->buffer); - weechat_log_printf (" remote_nick_color . : '%s'", ptr_xfer->remote_nick_color); - weechat_log_printf (" fast_send . . . . . : %d", ptr_xfer->fast_send); - weechat_log_printf (" blocksize . . . . . : %d", ptr_xfer->blocksize); - weechat_log_printf (" start_time. . . . . : %ld", ptr_xfer->start_time); - weechat_log_printf (" start_transfer. . . : %ld", ptr_xfer->start_transfer); - weechat_log_printf (" sock. . . . . . . . : %d", ptr_xfer->sock); - weechat_log_printf (" child_pid . . . . . : %d", ptr_xfer->child_pid); - weechat_log_printf (" child_read. . . . . : %d", ptr_xfer->child_read); - weechat_log_printf (" child_write . . . . : %d", ptr_xfer->child_write); - weechat_log_printf (" hook_fd . . . . . . : 0x%lx", ptr_xfer->hook_fd); - weechat_log_printf (" hook_timer. . . . . : 0x%lx", ptr_xfer->hook_timer); - weechat_log_printf (" unterminated_message: '%s'", ptr_xfer->unterminated_message); - weechat_log_printf (" file. . . . . . . . : %d", ptr_xfer->file); - weechat_log_printf (" local_filename. . . : '%s'", ptr_xfer->local_filename); - weechat_log_printf (" filename_suffix . . : %d", ptr_xfer->filename_suffix); - weechat_log_printf (" pos . . . . . . . . : %llu", ptr_xfer->pos); - weechat_log_printf (" ack . . . . . . . . : %llu", ptr_xfer->ack); - weechat_log_printf (" start_resume. . . . : %llu", ptr_xfer->start_resume); - weechat_log_printf (" last_check_time . . : %ld", ptr_xfer->last_check_time); - weechat_log_printf (" last_check_pos. . . : %llu", ptr_xfer->last_check_pos); - weechat_log_printf (" last_activity . . . : %ld", ptr_xfer->last_activity); - weechat_log_printf (" bytes_per_sec . . . : %llu", ptr_xfer->bytes_per_sec); - weechat_log_printf (" eta . . . . . . . . : %llu", ptr_xfer->eta); - weechat_log_printf (" hash_target . . . . : '%s'", ptr_xfer->hash_target); - weechat_log_printf (" hash_status . . . . : %d (%s)", + weechat_log_printf (" buffer. . . . . . . . . : 0x%lx", ptr_xfer->buffer); + weechat_log_printf (" remote_nick_color . . . : '%s'", ptr_xfer->remote_nick_color); + weechat_log_printf (" fast_send . . . . . . . : %d", ptr_xfer->fast_send); + weechat_log_printf (" blocksize . . . . . . . : %d", ptr_xfer->blocksize); + weechat_log_printf (" start_time. . . . . . . : %ld", ptr_xfer->start_time); + weechat_log_printf (" start_transfer. . . . . : %ld", ptr_xfer->start_transfer); + weechat_log_printf (" sock. . . . . . . . . . : %d", ptr_xfer->sock); + weechat_log_printf (" child_pid . . . . . . . : %d", ptr_xfer->child_pid); + weechat_log_printf (" child_read. . . . . . . : %d", ptr_xfer->child_read); + weechat_log_printf (" child_write . . . . . . : %d", ptr_xfer->child_write); + weechat_log_printf (" hook_fd . . . . . . . . : 0x%lx", ptr_xfer->hook_fd); + weechat_log_printf (" hook_timer. . . . . . . : 0x%lx", ptr_xfer->hook_timer); + weechat_log_printf (" unterminated_message. . : '%s'", ptr_xfer->unterminated_message); + weechat_log_printf (" file. . . . . . . . . . : %d", ptr_xfer->file); + weechat_log_printf (" local_filename. . . . . : '%s'", ptr_xfer->local_filename); + weechat_log_printf (" filename_suffix . . . . : %d", ptr_xfer->filename_suffix); + weechat_log_printf (" pos . . . . . . . . . . : %llu", ptr_xfer->pos); + weechat_log_printf (" ack . . . . . . . . . . : %llu", ptr_xfer->ack); + weechat_log_printf (" start_resume. . . . . . : %llu", ptr_xfer->start_resume); + weechat_log_printf (" last_check_time . . . . : %ld", ptr_xfer->last_check_time); + weechat_log_printf (" last_check_pos. . . . . : %llu", ptr_xfer->last_check_pos); + weechat_log_printf (" last_activity . . . . . : %ld", ptr_xfer->last_activity); + weechat_log_printf (" bytes_per_sec . . . . . : %llu", ptr_xfer->bytes_per_sec); + weechat_log_printf (" eta . . . . . . . . . . : %llu", ptr_xfer->eta); + weechat_log_printf (" hash_target . . . . . . : '%s'", ptr_xfer->hash_target); + weechat_log_printf (" hash_status . . . . . . : %d (%s)", ptr_xfer->hash_status, xfer_hash_status_string[ptr_xfer->hash_status]); - weechat_log_printf (" prev_xfer . . . . . : 0x%lx", ptr_xfer->prev_xfer); - weechat_log_printf (" next_xfer . . . . . : 0x%lx", ptr_xfer->next_xfer); + weechat_log_printf (" prev_xfer . . . . . . . : 0x%lx", ptr_xfer->prev_xfer); + weechat_log_printf (" next_xfer . . . . . . . : 0x%lx", ptr_xfer->next_xfer); } } diff --git a/src/plugins/xfer/xfer.h b/src/plugins/xfer/xfer.h index 2afbd50b3..c4f9758d4 100644 --- a/src/plugins/xfer/xfer.h +++ b/src/plugins/xfer/xfer.h @@ -140,8 +140,12 @@ struct t_xfer char *filename; /* filename */ unsigned long long size; /* file size */ char *proxy; /* proxy to use (optional) */ - unsigned long local_address; /* local IP address */ - unsigned long remote_address; /* remote IP address */ + struct sockaddr *local_address; /* local IP address */ + socklen_t local_address_length; /* local sockaddr length */ + char *local_address_str; /* local IP address as string */ + struct sockaddr *remote_address; /* remote IP address */ + socklen_t remote_address_length; /* remote sockaddr length */ + char *remote_address_str; /* remote IP address as string */ int port; /* remote port */ /* internal data */ @@ -191,6 +195,9 @@ extern struct t_xfer *xfer_search_by_number (int number); extern struct t_xfer *xfer_search_by_buffer (struct t_gui_buffer *buffer); extern void xfer_close (struct t_xfer *xfer, enum t_xfer_status status); extern void xfer_send_signal (struct t_xfer *xfer, const char *signal); +extern void xfer_set_remote_address (struct t_xfer *xfer, + struct sockaddr *address, socklen_t length, + char *address_str); extern void xfer_free (struct t_xfer *xfer); extern int xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer); |