relay: add UNIX socket support (closes #733)
This commit is contained in:
parent
5f87112ec5
commit
ffefd1b785
@ -3194,6 +3194,27 @@ websocket = new WebSocket("ws://server.com:9000/weechat");
|
||||
The port (9000 in example) is the port defined in Relay plugin.
|
||||
The URI must always end with "/weechat" (for _irc_ and _weechat_ protocols).
|
||||
|
||||
[[relay_unixsocket]]
|
||||
==== UNIX domain sockets
|
||||
|
||||
Using the protocol option "unix" with the "/relay add" command, you can
|
||||
listen using any protocol on a UNIX domain socket at a given path. For exmaple:
|
||||
|
||||
----
|
||||
/relay add unix.weechat /tmp/weesock
|
||||
----
|
||||
|
||||
will allow clients to connect using the WeeChat protocol to /tmp/weesock. This
|
||||
is particularly useful to allow SSH forwarding for relay clients, when other
|
||||
ports cannot be opened. Using OpenSSH:
|
||||
|
||||
----
|
||||
$ ssh -L9000:/tmp/weesock foo_host
|
||||
----
|
||||
|
||||
will then allow for local relay clients to connect on port 9000 to a WeeChat
|
||||
instance running on "foo_host".
|
||||
|
||||
[[relay_commands]]
|
||||
==== Commands
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
@ -509,6 +511,75 @@ relay_config_check_port_cb (const void *pointer, void *data,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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)
|
||||
@ -187,6 +200,28 @@ relay_server_search_port (int port)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
@ -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 ();
|
||||
|
Loading…
x
Reference in New Issue
Block a user