summaryrefslogtreecommitdiff
path: root/src/plugins/relay
diff options
context:
space:
mode:
authorRyan Farley <ryan.farley@gmx.com>2019-05-12 18:51:13 +0200
committerSébastien Helleu <flashcode@flashtux.org>2019-05-12 18:51:13 +0200
commitffefd1b7851c3ee01ef259ea406fbcfaa564bead (patch)
treeec925205d89a5f49ad42534954f3597faf329cf1 /src/plugins/relay
parent5f87112ec553dcaef0650feabbdb4629e9f9b67f (diff)
downloadweechat-ffefd1b7851c3ee01ef259ea406fbcfaa564bead.zip
relay: add UNIX socket support (closes #733)
Diffstat (limited to 'src/plugins/relay')
-rw-r--r--src/plugins/relay/relay-client.c4
-rw-r--r--src/plugins/relay/relay-command.c48
-rw-r--r--src/plugins/relay/relay-config.c130
-rw-r--r--src/plugins/relay/relay-config.h2
-rw-r--r--src/plugins/relay/relay-server.c167
-rw-r--r--src/plugins/relay/relay-server.h14
6 files changed, 291 insertions, 74 deletions
diff --git a/src/plugins/relay/relay-client.c b/src/plugins/relay/relay-client.c
index 0ea02c356..4455d5301 100644
--- a/src/plugins/relay/relay-client.c
+++ b/src/plugins/relay/relay-client.c
@@ -1355,9 +1355,9 @@ relay_client_new (int sock, const char *address, struct t_relay_server *server)
relay_clients = new_client;
weechat_printf_date_tags (NULL, 0, "relay_client",
- _("%s: new client on port %d: %s%s%s"),
+ _("%s: new client on port/path %s: %s%s%s"),
RELAY_PLUGIN_NAME,
- server->port,
+ server->path,
RELAY_COLOR_CHAT_CLIENT,
new_client->desc,
RELAY_COLOR_CHAT);
diff --git a/src/plugins/relay/relay-command.c b/src/plugins/relay/relay-command.c
index 539b3aef7..8f3627368 100644
--- a/src/plugins/relay/relay-command.c
+++ b/src/plugins/relay/relay-command.c
@@ -134,7 +134,7 @@ relay_command_server_list ()
if (relay_servers)
{
weechat_printf (NULL, "");
- weechat_printf (NULL, _("Listening on ports:"));
+ weechat_printf (NULL, _("Listening on:"));
i = 1;
for (ptr_server = relay_servers; ptr_server;
ptr_server = ptr_server->next_server)
@@ -143,14 +143,15 @@ relay_command_server_list ()
{
weechat_printf (
NULL,
- _(" port %s%d%s, relay: %s%s%s, %s (not started)"),
+ _(" %s %s%s%s, relay: %s%s%s, %s (not started)"),
RELAY_COLOR_CHAT_BUFFER,
- ptr_server->port,
+ ptr_server->un ? _("path") : _("port"),
+ ptr_server->path,
RELAY_COLOR_CHAT,
RELAY_COLOR_CHAT_BUFFER,
ptr_server->protocol_string,
RELAY_COLOR_CHAT,
- ((ptr_server->ipv4 && ptr_server->ipv6) ? "IPv4+6" : ((ptr_server->ipv6) ? "IPv6" : "IPv4")));
+ ((ptr_server->ipv4 && ptr_server->ipv6) ? "IPv4+6" : ((ptr_server->ipv6) ? "IPv6" : ((ptr_server->ipv4) ? "IPv4" : "UNIX"))));
}
else
{
@@ -164,15 +165,16 @@ relay_command_server_list ()
}
weechat_printf (
NULL,
- _(" port %s%d%s, relay: %s%s%s, %s, started on: %s"),
+ _(" %s %s%s%s, relay: %s%s%s, %s, started on: %s"),
+ ptr_server->un ? _("path") : _("port"),
RELAY_COLOR_CHAT_BUFFER,
- ptr_server->port,
+ ptr_server->path,
RELAY_COLOR_CHAT,
RELAY_COLOR_CHAT_BUFFER,
ptr_server->protocol_string,
RELAY_COLOR_CHAT,
- ((ptr_server->ipv4 && ptr_server->ipv6) ? "IPv4+6" : ((ptr_server->ipv6) ? "IPv6" : "IPv4")),
- date_start);
+ ((ptr_server->ipv4 && ptr_server->ipv6) ? "IPv4+6" : ((ptr_server->ipv6) ? "IPv6" : ((ptr_server->ipv4) ? "IPv4" : "UNIX"))),
+ date_start);
}
i++;
}
@@ -192,7 +194,8 @@ relay_command_relay (const void *pointer, void *data,
{
struct t_relay_server *ptr_server;
struct t_config_option *ptr_option;
- int port;
+ struct t_config_section *port_path_section;
+ char *path;
/* make C compiler happy */
(void) pointer;
@@ -222,15 +225,19 @@ relay_command_relay (const void *pointer, void *data,
if (weechat_strcasecmp (argv[1], "add") == 0)
{
WEECHAT_COMMAND_MIN_ARGS(4, "add");
+ /* check if we're expecting a path or a port */
+ port_path_section = strncmp (argv[2], "unix.", 5) ?
+ relay_config_section_port :
+ relay_config_section_path;
if (relay_config_create_option_port (
NULL, NULL,
relay_config_file,
- relay_config_section_port,
+ port_path_section,
argv[2],
argv_eol[3]) != WEECHAT_CONFIG_OPTION_SET_ERROR)
{
weechat_printf (NULL,
- _("%s: relay \"%s\" (port %s) added"),
+ _("%s: relay \"%s\" (path/port: %s) added"),
RELAY_PLUGIN_NAME,
argv[2], argv_eol[3]);
}
@@ -243,17 +250,21 @@ relay_command_relay (const void *pointer, void *data,
ptr_server = relay_server_search (argv_eol[2]);
if (ptr_server)
{
- port = ptr_server->port;
+ path = strdup (ptr_server->path);
relay_server_free (ptr_server);
ptr_option = weechat_config_search_option (relay_config_file,
- relay_config_section_port,
+ ptr_server->un ?
+ relay_config_section_path :
+ relay_config_section_port,
argv_eol[2]);
if (ptr_option)
weechat_config_option_free (ptr_option);
weechat_printf (NULL,
- _("%s: relay \"%s\" (port %d) removed"),
+ _("%s: relay \"%s\" (%s %s) removed"),
RELAY_PLUGIN_NAME,
- argv[2], port);
+ argv[2], ptr_server->un ? _("path") : _("port"),
+ path);
+ free (path);
}
else
{
@@ -391,7 +402,7 @@ relay_command_init ()
N_(" list: list relay clients (only active relays)\n"
" listfull: list relay clients (verbose, all relays)\n"
" listrelay: list relays (name and port)\n"
- " add: add a relay (listen on a port)\n"
+ " add: add a relay (listen on a port/path)\n"
" del: remove a relay (clients remain connected)\n"
" start: listen on port\n"
" restart: close the server socket and listen again on port "
@@ -407,6 +418,7 @@ relay_command_init ()
" ipv4: force use of IPv4\n"
" ipv6: force use of IPv6\n"
" ssl: enable SSL\n"
+ " unix: use UNIX domain socket\n"
"protocol.name: protocol and name to relay:\n"
" - protocol \"irc\": name is the server to share "
"(optional, if not given, the server name must be sent by client in "
@@ -437,7 +449,9 @@ relay_command_init ()
" weechat protocol with SSL, using only IPv6:\n"
" /relay add ipv6.ssl.weechat 9001\n"
" weechat protocol with SSL, using IPv4 + IPv6:\n"
- " /relay add ipv4.ipv6.ssl.weechat 9001"),
+ " /relay add ipv4.ipv6.ssl.weechat 9001\n"
+ " weechat protocol over UNIX domain socket:\n"
+ " /relay add unix.weechat /tmp/weesock\n"),
"list %(relay_relays)"
" || listfull %(relay_relays)"
" || listrelay"
diff --git a/src/plugins/relay/relay-config.c b/src/plugins/relay/relay-config.c
index 93e3e978c..f4d1be9ff 100644
--- a/src/plugins/relay/relay-config.c
+++ b/src/plugins/relay/relay-config.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <limits.h>
#include <regex.h>
+#include <sys/un.h>
#include "../weechat-plugin.h"
#include "relay.h"
@@ -36,6 +37,7 @@
struct t_config_file *relay_config_file = NULL;
struct t_config_section *relay_config_section_port = NULL;
+struct t_config_section *relay_config_section_path = NULL;
/* relay config, look section */
@@ -185,7 +187,7 @@ relay_config_change_network_ipv6_cb (const void *pointer, void *data,
{
relay_server_get_protocol_args (ptr_server->protocol_string,
&ptr_server->ipv4, &ptr_server->ipv6,
- NULL, NULL, NULL);
+ NULL, &ptr_server->un, NULL, NULL);
relay_server_close_socket (ptr_server);
relay_server_create_socket (ptr_server);
}
@@ -510,6 +512,75 @@ relay_config_check_port_cb (const void *pointer, void *data,
}
/*
+ * Checks if a UNIX path is too long or empty.
+ *
+ * Returns:
+ * 1: path is valid
+ * 0: path is empty, or too long
+ */
+
+int
+relay_config_check_path_len (const char *path)
+{
+ struct sockaddr_un addr;
+ size_t max_path, path_len;
+
+ max_path = sizeof (addr.sun_path);
+ path_len = strlen (path);
+ if (!path_len)
+ {
+ weechat_printf (NULL, _("%s%s: error: path is empty"),
+ weechat_prefix ("error"), RELAY_PLUGIN_NAME);
+ return 0;
+ }
+ if (path_len >= max_path)
+ {
+ weechat_printf (NULL,
+ _("%s%s: error: path \"%s\" too long (length: %d; max: %d)"),
+ weechat_prefix ("error"), RELAY_PLUGIN_NAME, path,
+ path_len, max_path);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Checks if a path is valid.
+ *
+ * Returns:
+ * 1: path is valid
+ * 0: path is not valid
+ */
+
+int
+relay_config_check_path_cb (const void *pointer, void *data,
+ struct t_config_option *option,
+ const char *value)
+{
+ struct t_relay_server *ptr_server;
+
+ /* make C compiler happy */
+ (void) pointer;
+ (void) data;
+ (void) option;
+
+ if (!relay_config_check_path_len (value))
+ return 0;
+
+ ptr_server = relay_server_search_path (value);
+ if (ptr_server)
+ {
+ weechat_printf (NULL, _("%s%s: error: path \"%s\" is already used"),
+ weechat_prefix ("error"),
+ RELAY_PLUGIN_NAME, value);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
* Callback for changes on options in section "port".
*/
@@ -561,7 +632,7 @@ relay_config_create_option_port (const void *pointer, void *data,
const char *option_name,
const char *value)
{
- int rc, protocol_number, ipv4, ipv6, ssl;
+ int rc, protocol_number, ipv4, ipv6, ssl, un;
char *error, *protocol, *protocol_args;
long port;
struct t_relay_server *ptr_server;
@@ -575,7 +646,7 @@ relay_config_create_option_port (const void *pointer, void *data,
protocol_number = -1;
port = -1;
- relay_server_get_protocol_args (option_name, &ipv4, &ipv6, &ssl,
+ relay_server_get_protocol_args (option_name, &ipv4, &ipv6, &ssl, &un,
&protocol, &protocol_args);
#ifndef HAVE_GNUTLS
@@ -625,14 +696,23 @@ relay_config_create_option_port (const void *pointer, void *data,
if (rc != WEECHAT_CONFIG_OPTION_SET_ERROR)
{
- error = NULL;
- port = strtol (value, &error, 10);
- ptr_server = relay_server_search_port ((int)port);
+ if (un)
+ {
+ ptr_server = relay_server_search_path (value);
+ }
+ else
+ {
+ error = NULL;
+ port = strtol (value, &error, 10);
+ ptr_server = relay_server_search_port ((int)port);
+ }
if (ptr_server)
{
- weechat_printf (NULL, _("%s%s: error: port \"%d\" is already used"),
+ weechat_printf (NULL, _("%s%s: error: %s \"%s\" is already used"),
weechat_prefix ("error"),
- RELAY_PLUGIN_NAME, (int)port);
+ RELAY_PLUGIN_NAME,
+ un ? _("path") : _("port"),
+ value);
rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
}
}
@@ -640,16 +720,29 @@ relay_config_create_option_port (const void *pointer, void *data,
if (rc != WEECHAT_CONFIG_OPTION_SET_ERROR)
{
if (relay_server_new (option_name, protocol_number, protocol_args,
- port, ipv4, ipv6, ssl))
+ port, value, ipv4, ipv6, ssl, un))
{
/* create configuration option */
- weechat_config_new_option (
+ if (un)
+ {
+ weechat_config_new_option (
+ config_file, section,
+ option_name, "string", NULL,
+ NULL, 0, 0, "", value, 0,
+ &relay_config_check_path_cb, NULL, NULL,
+ &relay_config_change_port_cb, NULL, NULL,
+ &relay_config_delete_port_cb, NULL, NULL);
+ }
+ else
+ {
+ weechat_config_new_option (
config_file, section,
option_name, "integer", NULL,
NULL, 0, 65535, "", value, 0,
&relay_config_check_port_cb, NULL, NULL,
&relay_config_change_port_cb, NULL, NULL,
&relay_config_delete_port_cb, NULL, NULL);
+ }
rc = WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
}
else
@@ -1067,6 +1160,23 @@ relay_config_init ()
relay_config_section_port = ptr_section;
+ /* section path */
+ ptr_section = weechat_config_new_section (
+ relay_config_file, "path",
+ 1, 1,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ &relay_config_create_option_port, NULL, NULL,
+ NULL, NULL, NULL);
+ if (!ptr_section)
+ {
+ weechat_config_free (relay_config_file);
+ relay_config_file = NULL;
+ return 0;
+ }
+
+ relay_config_section_path = ptr_section;
return 1;
}
diff --git a/src/plugins/relay/relay-config.h b/src/plugins/relay/relay-config.h
index 14fce3420..52ab8ae64 100644
--- a/src/plugins/relay/relay-config.h
+++ b/src/plugins/relay/relay-config.h
@@ -26,6 +26,7 @@
extern struct t_config_file *relay_config_file;
extern struct t_config_section *relay_config_section_port;
+extern struct t_config_section *relay_config_section_path;
extern struct t_config_option *relay_config_look_auto_open_buffer;
extern struct t_config_option *relay_config_look_raw_messages;
@@ -72,6 +73,7 @@ extern int relay_config_create_option_port (const void *pointer, void *data,
struct t_config_section *section,
const char *option_name,
const char *value);
+extern int relay_config_check_path_len (const char *path);
extern int relay_config_init ();
extern int relay_config_read ();
extern int relay_config_write ();
diff --git a/src/plugins/relay/relay-server.c b/src/plugins/relay/relay-server.c
index 713acc063..f73c3dd80 100644
--- a/src/plugins/relay/relay-server.c
+++ b/src/plugins/relay/relay-server.c
@@ -30,6 +30,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <sys/un.h>
#include "../weechat-plugin.h"
#include "relay.h"
@@ -49,32 +50,34 @@ struct t_relay_server *last_relay_server = NULL;
*
* Examples:
*
- * string ipv4 ipv6 ssl protocol protocol_args
+ * string ipv4 ipv6 ssl unix protocol protocol_args
* ---------------------------------------------------------------
- * irc.freenode 1 1 0 irc freenode
- * ssl.irc.freenode 1 1 1 irc freenode
- * ipv4.irc.freenode 1 0 0 irc freenode
- * ipv6.irc.freenode 0 1 0 irc freenode
- * ipv4.ipv6.irc.freenode 1 1 0 irc freenode
- * ipv6.ssl.irc.freenode 0 1 1 irc freenode
- * weechat 1 1 0 weechat
- * ssl.weechat 1 1 1 weechat
- * ipv6.ssl.weechat 0 1 1 weechat
+ * irc.freenode 1 1 0 0 irc freenode
+ * ssl.irc.freenode 1 1 1 0 irc freenode
+ * ipv4.irc.freenode 1 0 0 0 irc freenode
+ * ipv6.irc.freenode 0 1 0 0 irc freenode
+ * ipv4.ipv6.irc.freenode 1 1 0 0 irc freenode
+ * ipv6.ssl.irc.freenode 0 1 1 0 irc freenode
+ * weechat 1 1 0 0 weechat
+ * ssl.weechat 1 1 1 0 weechat
+ * ipv6.ssl.weechat 0 1 1 0 weechat
+ * unix.weechat 0 0 0 1 weechat
*
* Note: *protocol and *protocol_args must be freed after use.
*/
void
relay_server_get_protocol_args (const char *protocol_and_args,
- int *ipv4, int *ipv6, int *ssl,
+ int *ipv4, int *ipv6, int *ssl, int *un,
char **protocol, char **protocol_args)
{
- int opt_ipv4, opt_ipv6, opt_ssl;
+ int opt_ipv4, opt_ipv6, opt_ssl, opt_un;
char *pos;
opt_ipv4 = -1;
opt_ipv6 = -1;
opt_ssl = 0;
+ opt_un = -1;
while (1)
{
if (strncmp (protocol_and_args, "ipv4.", 5) == 0)
@@ -92,18 +95,24 @@ relay_server_get_protocol_args (const char *protocol_and_args,
opt_ssl = 1;
protocol_and_args += 4;
}
+ else if (strncmp (protocol_and_args, "unix.", 5) == 0)
+ {
+ opt_un = 1;
+ protocol_and_args += 5;
+ }
else
break;
}
- if ((opt_ipv4 == -1) && (opt_ipv6 == -1))
+ if ((opt_ipv4 == -1) && (opt_ipv6 == -1) && (opt_un == -1))
{
/*
- * no IPv4/IPv6 specified, then use defaults:
+ * no IPv4/IPv6/UNIX specified, then use defaults:
* - IPv4 enabled
* - IPv6 enabled if option relay.network.ipv6 is on
*/
opt_ipv4 = 1;
opt_ipv6 = weechat_config_boolean (relay_config_network_ipv6);
+ opt_un = 0;
}
else
{
@@ -111,10 +120,12 @@ relay_server_get_protocol_args (const char *protocol_and_args,
opt_ipv4 = 0;
if (opt_ipv6 == -1)
opt_ipv6 = 0;
+ if (opt_un == -1)
+ opt_un = 0;
}
- if (!opt_ipv4 && !opt_ipv6)
+ if (!opt_ipv4 && !opt_ipv6 && !opt_un)
{
- /* both IPv4/IPv6 disabled (should never occur!) */
+ /* IPv4/IPv6/UNIX disabled (should never occur!) */
opt_ipv4 = 1;
}
if (ipv4)
@@ -123,6 +134,8 @@ relay_server_get_protocol_args (const char *protocol_and_args,
*ipv6 = opt_ipv6;
if (ssl)
*ssl = opt_ssl;
+ if (un)
+ *un = opt_un;
pos = strchr (protocol_and_args, '.');
if (pos)
@@ -188,6 +201,28 @@ relay_server_search_port (int port)
}
/*
+ * Searches for a server by path. Only returns servers using a UNIX socket.
+ *
+ * Returns pointer to new server, NULL if not found.
+ */
+
+struct t_relay_server *
+relay_server_search_path (const char *path)
+{
+ struct t_relay_server *ptr_server;
+
+ for (ptr_server = relay_servers; ptr_server;
+ ptr_server = ptr_server->next_server)
+ {
+ /* only include UNIX socket relays, to allow for numerical paths */
+ if (!strcmp (path, ptr_server->path) && ptr_server->un)
+ return ptr_server;
+ }
+
+ /* server not found */
+ return NULL;
+}
+/*
* Closes socket for a relay server.
*/
@@ -203,13 +238,17 @@ relay_server_close_socket (struct t_relay_server *server)
{
close (server->sock);
server->sock = -1;
-
+ if (server->un)
+ {
+ unlink (server->path);
+ }
if (!relay_signal_upgrade_received)
{
weechat_printf (NULL,
- _("%s: socket closed for %s (port %d)"),
+ _("%s: socket closed for %s (%s %s)"),
RELAY_PLUGIN_NAME, server->protocol_string,
- server->port);
+ server->un ? _("path") : _("port"),
+ server->path);
}
}
}
@@ -224,10 +263,13 @@ relay_server_sock_cb (const void *pointer, void *data, int fd)
struct t_relay_server *server;
struct sockaddr_in client_addr;
struct sockaddr_in6 client_addr6;
+ struct sockaddr_un client_addr_un;
+
socklen_t client_addr_size;
void *ptr_addr;
int client_fd, flags, set, max_clients, num_clients_on_port;
char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1];
+ char un_address[sizeof (client_addr_un.sun_path)];
char *ptr_ip_address, *relay_password, *relay_totp_secret;
/* make C compiler happy */
@@ -245,11 +287,16 @@ relay_server_sock_cb (const void *pointer, void *data, int fd)
ptr_addr = &client_addr6;
client_addr_size = sizeof (struct sockaddr_in6);
}
- else
+ else if (server->ipv4)
{
ptr_addr = &client_addr;
client_addr_size = sizeof (struct sockaddr_in);
}
+ else if (server->un)
+ {
+ ptr_addr = &client_addr_un;
+ client_addr_size = sizeof (struct sockaddr_un);
+ }
memset (ptr_addr, 0, client_addr_size);
@@ -258,9 +305,10 @@ relay_server_sock_cb (const void *pointer, void *data, int fd)
if (client_fd < 0)
{
weechat_printf (NULL,
- _("%s%s: cannot accept client on port %d (%s): error %d %s"),
+ _("%s%s: cannot accept client on %s %s (%s): error %d %s"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
- server->port, server->protocol_string,
+ server->un ? _("path") : _("port"),
+ server->path, server->protocol_string,
errno, strerror (errno));
goto error;
}
@@ -345,7 +393,7 @@ relay_server_sock_cb (const void *pointer, void *data, int fd)
}
}
}
- else
+ else if (server->ipv4)
{
if (inet_ntop (AF_INET,
&(client_addr.sin_addr),
@@ -355,6 +403,11 @@ relay_server_sock_cb (const void *pointer, void *data, int fd)
ptr_ip_address = ipv4_address;
}
}
+ else
+ {
+ strncpy (un_address, client_addr_un.sun_path, sizeof (un_address));
+ ptr_ip_address = un_address;
+ }
/* check if IP is allowed, if not, just close socket */
if (relay_config_regex_allowed_ips
@@ -422,6 +475,7 @@ relay_server_create_socket (struct t_relay_server *server)
int domain, set, max_clients, addr_size;
struct sockaddr_in server_addr;
struct sockaddr_in6 server_addr6;
+ struct sockaddr_un server_addr_un;
const char *bind_address;
void *ptr_addr;
@@ -449,7 +503,7 @@ relay_server_create_socket (struct t_relay_server *server)
ptr_addr = &server_addr6;
addr_size = sizeof (struct sockaddr_in6);
}
- else
+ else if (server->ipv4)
{
domain = AF_INET;
memset (&server_addr, 0, sizeof (struct sockaddr_in));
@@ -471,6 +525,21 @@ relay_server_create_socket (struct t_relay_server *server)
ptr_addr = &server_addr;
addr_size = sizeof (struct sockaddr_in);
}
+ else
+ {
+ domain = AF_UNIX;
+ memset (&server_addr_un, 0, sizeof (struct sockaddr_un));
+ server_addr_un.sun_family = domain;
+ strncpy (server_addr_un.sun_path, server->path,
+ sizeof (server_addr_un.sun_path));
+ ptr_addr = &server_addr_un;
+ addr_size = sizeof (struct sockaddr_un);
+ if (!relay_config_check_path_len (server->path))
+ return 0;
+ /* just in case it already exists */
+ unlink (server->path);
+ }
+
/* create socket */
server->sock = socket (domain, SOCK_STREAM, 0);
@@ -543,9 +612,10 @@ relay_server_create_socket (struct t_relay_server *server)
if (bind (server->sock, (struct sockaddr *)ptr_addr, addr_size) < 0)
{
weechat_printf (NULL,
- _("%s%s: cannot \"bind\" on port %d (%s): error %d %s"),
+ _("%s%s: cannot \"bind\" on %s %s (%s): error %d %s"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
- server->port, server->protocol_string,
+ server->un ? _("path") : _("port"),
+ server->path, server->protocol_string,
errno, strerror (errno));
close (server->sock);
server->sock = -1;
@@ -559,9 +629,10 @@ relay_server_create_socket (struct t_relay_server *server)
#endif
{
weechat_printf (NULL,
- _("%s%s: cannot \"listen\" on port %d (%s): error %d %s"),
+ _("%s%s: cannot \"listen\" on %s %s (%s): error %d %s"),
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
- server->port, server->protocol_string,
+ server->un ? _("path") : _("port"),
+ server->path, server->protocol_string,
errno, strerror (errno));
close (server->sock);
server->sock = -1;
@@ -573,24 +644,26 @@ relay_server_create_socket (struct t_relay_server *server)
{
weechat_printf (
NULL,
- NG_("%s: listening on port %d (relay: %s, %s, max %d client)",
- "%s: listening on port %d (relay: %s, %s, max %d clients)",
+ NG_("%s: listening on %s %s (relay: %s, %s, max %d client)",
+ "%s: listening on %s %s (relay: %s, %s, max %d clients)",
max_clients),
RELAY_PLUGIN_NAME,
- server->port,
+ server->un ? _("path") : _("port"),
+ server->path,
server->protocol_string,
- ((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : "IPv4")),
+ ((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : ((server->ipv4) ? "IPv4" : "UNIX"))),
max_clients);
}
else
{
weechat_printf (
NULL,
- _("%s: listening on port %d (relay: %s, %s)"),
+ _("%s: listening on %s %s (relay: %s, %s)"),
RELAY_PLUGIN_NAME,
- server->port,
+ server->un ? _("path") : _("port"),
+ server->path,
server->protocol_string,
- ((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : "IPv4")));
+ ((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : ((server->ipv4) ? "IPv4" : "UNIX"))));
}
server->hook_fd = weechat_hook_fd (server->sock,
1, 0, 0,
@@ -610,17 +683,21 @@ relay_server_create_socket (struct t_relay_server *server)
struct t_relay_server *
relay_server_new (const char *protocol_string, enum t_relay_protocol protocol,
- const char *protocol_args, int port, int ipv4, int ipv6,
- int ssl)
+ const char *protocol_args, int port, const char *path,
+ int ipv4, int ipv6, int ssl, int un)
{
- struct t_relay_server *new_server;
+ struct t_relay_server *new_server, *dup_server;
if (!protocol_string)
return NULL;
- if (relay_server_search_port (port))
+ /* look for duplicate ports/paths */
+ dup_server = un ?
+ relay_server_search_path (path) : relay_server_search_port (port);
+ if (dup_server)
{
- weechat_printf (NULL, _("%s%s: error: port \"%d\" is already used"),
+ weechat_printf (NULL, _("%s%s: error: %s \"%s\" is already used"),
+ un ? _("path") : _("port"),
weechat_prefix ("error"),
RELAY_PLUGIN_NAME, port);
return NULL;
@@ -634,9 +711,11 @@ relay_server_new (const char *protocol_string, enum t_relay_protocol protocol,
new_server->protocol_args =
(protocol_args) ? strdup (protocol_args) : NULL;
new_server->port = port;
+ new_server->path = strdup (path);
new_server->ipv4 = ipv4;
new_server->ipv6 = ipv6;
new_server->ssl = ssl;
+ new_server->un = un;
new_server->sock = -1;
new_server->hook_fd = NULL;
new_server->start_time = 0;
@@ -708,7 +787,7 @@ relay_server_free (struct t_relay_server *server)
free (server->protocol_string);
if (server->protocol_args)
free (server->protocol_args);
-
+ free (server->path);
free (server);
relay_servers = new_relay_servers;
@@ -756,12 +835,16 @@ relay_server_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "port", server->port))
return 0;
+ if (!weechat_infolist_new_var_string (ptr_item, "path", server->path))
+ return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "ipv4", server->ipv4))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "ipv6", server->ipv6))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "ssl", server->ssl))
return 0;
+ if (!weechat_infolist_new_var_integer (ptr_item, "un", server->un))
+ return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "sock", server->sock))
return 0;
if (!weechat_infolist_new_var_pointer (ptr_item, "hook_fd", server->hook_fd))
@@ -794,9 +877,11 @@ relay_server_print_log ()
relay_protocol_string[ptr_server->protocol]);
weechat_log_printf (" protocol_args . . . . : '%s'", ptr_server->protocol_args);
weechat_log_printf (" port. . . . . . . . . : %d", ptr_server->port);
+ weechat_log_printf (" path. . . . . . . . . : %s", ptr_server->path);
weechat_log_printf (" ipv4. . . . . . . . . : %d", ptr_server->ipv4);
weechat_log_printf (" ipv6. . . . . . . . . : %d", ptr_server->ipv6);
weechat_log_printf (" ssl . . . . . . . . . : %d", ptr_server->ssl);
+ weechat_log_printf (" unix. . . . . . . . . : %d", ptr_server->un);
weechat_log_printf (" sock. . . . . . . . . : %d", ptr_server->sock);
weechat_log_printf (" hook_fd . . . . . . . : 0x%lx", ptr_server->hook_fd);
weechat_log_printf (" start_time. . . . . . : %lld", (long long)ptr_server->start_time);
diff --git a/src/plugins/relay/relay-server.h b/src/plugins/relay/relay-server.h
index db7ace2cd..edbf4b187 100644
--- a/src/plugins/relay/relay-server.h
+++ b/src/plugins/relay/relay-server.h
@@ -21,7 +21,6 @@
#define WEECHAT_PLUGIN_RELAY_SERVER_H
#include <time.h>
-
#ifdef HAVE_GNUTLS
#define RELAY_SERVER_GNUTLS_DH_BITS 1024
#endif /* HAVE_GNUTLS */
@@ -33,9 +32,14 @@ struct t_relay_server
char *protocol_args; /* arguments used for protocol */
/* example: server for irc protocol */
int port; /* listening on this port */
+ /* or UNIX socket, if negative. */
+ char *path; /* listening on this path (UNIX) */
+ /* contains string representation of */
+ /* port if IP */
int ipv4; /* IPv4 protocol enabled */
int ipv6; /* IPv6 protocol enabled */
int ssl; /* 1 if SSL is enabled */
+ int un; /* 1 if UNIX socket */
int sock; /* socket for connection */
struct t_hook *hook_fd; /* hook for socket */
time_t start_time; /* start time */
@@ -49,18 +53,20 @@ extern struct t_relay_server *last_relay_server;
extern void relay_server_get_protocol_args (const char *protocol_and_string,
int *ipv4, int *ipv6,
- int *ssl,
+ int *ssl, int *un,
char **protocol,
char **protocol_args);
extern struct t_relay_server *relay_server_search (const char *protocol_and_args);
extern struct t_relay_server *relay_server_search_port (int port);
+extern struct t_relay_server *relay_server_search_path (const char *path);
extern void relay_server_close_socket (struct t_relay_server *server);
extern int relay_server_create_socket (struct t_relay_server *server);
extern struct t_relay_server *relay_server_new (const char *protocol_string,
enum t_relay_protocol protocol,
const char *protocol_args,
- int port, int ipv4, int ipv6,
- int ssl);
+ int port, const char *path,
+ int ipv4, int ipv6,
+ int ssl, int un);
extern void relay_server_update_port (struct t_relay_server *server, int port);
extern void relay_server_free (struct t_relay_server *server);
extern void relay_server_free_all ();