mirror of
https://github.com/weechat/weechat.git
synced 2026-07-04 00:33:13 +02:00
relay: add support of IPv6, new option relay.network.ipv6, add support of "ipv4." and/or "ipv6." before protocol name, to force IPv4/IPv6 (task #12270)
This commit is contained in:
@@ -149,16 +149,14 @@ relay_command_server_list ()
|
||||
}
|
||||
|
||||
weechat_printf (NULL,
|
||||
_(" port %s%d%s, relay: %s%s%s%s%s%s, started on: %s"),
|
||||
_(" port %s%d%s, relay: %s%s%s, %s, started on: %s"),
|
||||
RELAY_COLOR_CHAT_BUFFER,
|
||||
ptr_server->port,
|
||||
RELAY_COLOR_CHAT,
|
||||
RELAY_COLOR_CHAT_BUFFER,
|
||||
(ptr_server->ssl) ? "ssl." : "",
|
||||
relay_protocol_string[ptr_server->protocol],
|
||||
(ptr_server->protocol_args) ? "." : "",
|
||||
(ptr_server->protocol_args) ? ptr_server->protocol_args : "",
|
||||
ptr_server->protocol_string,
|
||||
RELAY_COLOR_CHAT,
|
||||
((ptr_server->ipv4 && ptr_server->ipv6) ? "IPv4+6" : ((ptr_server->ipv6) ? "IPv6" : "IPv4")),
|
||||
date_start);
|
||||
i++;
|
||||
}
|
||||
@@ -315,8 +313,8 @@ relay_command_init ()
|
||||
weechat_hook_command ("relay",
|
||||
N_("relay control"),
|
||||
N_("list|listfull|listrelay"
|
||||
" || add <protocol.name> <port>"
|
||||
" || del <protocol.name>"
|
||||
" || add [ipv4.][ipv6.][ssl.]<protocol.name> <port>"
|
||||
" || del [ipv4.][ipv6.][ssl.]<protocol.name>"
|
||||
" || raw"
|
||||
" || sslcertkey"),
|
||||
N_(" list: list relay clients (only active "
|
||||
@@ -326,13 +324,14 @@ relay_command_init ()
|
||||
" listrelay: list relays (name and port)\n"
|
||||
" add: add relay for a protocol + name\n"
|
||||
" del: remove relay for a protocol + name\n"
|
||||
" ipv4: force use of IPv4\n"
|
||||
" ipv6: force use of IPv6\n"
|
||||
" ssl: enable SSL\n"
|
||||
"protocol.name: protocol and name to relay:\n"
|
||||
" - protocol \"irc\": name is the "
|
||||
"server to share\n"
|
||||
" - protocol \"weechat\" (name is "
|
||||
"not used)\n"
|
||||
" Note: the protocol can be prefixed "
|
||||
"by \"ssl.\" to enable SSL\n"
|
||||
" port: port used for relay\n"
|
||||
" raw: open buffer with raw Relay data\n"
|
||||
" sslcertkey: set SSL certificate/key using path "
|
||||
@@ -347,7 +346,13 @@ relay_command_init ()
|
||||
" weechat protocol:\n"
|
||||
" /relay add weechat 9000\n"
|
||||
" weechat protocol with SSL:\n"
|
||||
" /relay add ssl.weechat 9001"),
|
||||
" /relay add ssl.weechat 9001\n"
|
||||
" weechat protocol with SSL, using only IPv4:\n"
|
||||
" /relay add ipv4.ssl.weechat 9001\n"
|
||||
" 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"),
|
||||
"list %(relay_relays)"
|
||||
" || listfull %(relay_relays)"
|
||||
" || listrelay"
|
||||
|
||||
@@ -84,7 +84,6 @@ relay_completion_relays_cb (void *data, const char *completion_item,
|
||||
struct t_gui_completion *completion)
|
||||
{
|
||||
struct t_relay_server *ptr_server;
|
||||
char protocol_name[512];
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
@@ -94,12 +93,8 @@ relay_completion_relays_cb (void *data, const char *completion_item,
|
||||
for (ptr_server = relay_servers; ptr_server;
|
||||
ptr_server = ptr_server->next_server)
|
||||
{
|
||||
snprintf (protocol_name, sizeof (protocol_name), "%s%s%s%s",
|
||||
(ptr_server->ssl) ? "ssl." : "",
|
||||
relay_protocol_string[ptr_server->protocol],
|
||||
(ptr_server->protocol_args) ? "." : "",
|
||||
(ptr_server->protocol_args) ? ptr_server->protocol_args : "");
|
||||
weechat_hook_completion_list_add (completion, protocol_name,
|
||||
weechat_hook_completion_list_add (completion,
|
||||
ptr_server->protocol_string,
|
||||
0, WEECHAT_LIST_POS_SORT);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ struct t_config_option *relay_config_color_status[RELAY_NUM_STATUS];
|
||||
struct t_config_option *relay_config_network_allowed_ips;
|
||||
struct t_config_option *relay_config_network_bind_address;
|
||||
struct t_config_option *relay_config_network_compression_level;
|
||||
struct t_config_option *relay_config_network_ipv6;
|
||||
struct t_config_option *relay_config_network_max_clients;
|
||||
struct t_config_option *relay_config_network_password;
|
||||
struct t_config_option *relay_config_network_ssl_cert_key;
|
||||
@@ -119,8 +120,9 @@ relay_config_change_network_allowed_ips (void *data,
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_config_change_network_bind_address_cb: callback called when user changes
|
||||
* network bind address option
|
||||
* relay_config_change_network_bind_address_cb: callback called when user
|
||||
* changes network bind address
|
||||
* option
|
||||
*/
|
||||
|
||||
void
|
||||
@@ -141,6 +143,31 @@ relay_config_change_network_bind_address_cb (void *data,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_config_change_network_ipv6_cb: callback called when user changes ipv6
|
||||
* option
|
||||
*/
|
||||
|
||||
void
|
||||
relay_config_change_network_ipv6_cb (void *data, struct t_config_option *option)
|
||||
{
|
||||
struct t_relay_server *ptr_server;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) option;
|
||||
|
||||
for (ptr_server = relay_servers; ptr_server;
|
||||
ptr_server = ptr_server->next_server)
|
||||
{
|
||||
relay_server_get_protocol_args (ptr_server->protocol_string,
|
||||
&ptr_server->ipv4, &ptr_server->ipv6,
|
||||
NULL, NULL, NULL);
|
||||
relay_server_close_socket (ptr_server);
|
||||
relay_server_create_socket (ptr_server);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* relay_config_change_network_ssl_cert_key: called when ssl_cert_key is changed
|
||||
*/
|
||||
@@ -238,7 +265,7 @@ relay_config_create_option_port (void *data,
|
||||
const char *option_name,
|
||||
const char *value)
|
||||
{
|
||||
int rc, protocol_number, ssl;
|
||||
int rc, protocol_number, ipv4, ipv6, ssl;
|
||||
char *error, *protocol, *protocol_args;
|
||||
long port;
|
||||
struct t_relay_server *ptr_server;
|
||||
@@ -251,8 +278,8 @@ relay_config_create_option_port (void *data,
|
||||
protocol_number = -1;
|
||||
port = -1;
|
||||
|
||||
relay_server_get_protocol_args (option_name,
|
||||
&ssl, &protocol, &protocol_args);
|
||||
relay_server_get_protocol_args (option_name, &ipv4, &ipv6, &ssl,
|
||||
&protocol, &protocol_args);
|
||||
|
||||
#ifndef HAVE_GNUTLS
|
||||
if (ssl)
|
||||
@@ -323,7 +350,8 @@ relay_config_create_option_port (void *data,
|
||||
|
||||
if (rc != WEECHAT_CONFIG_OPTION_SET_ERROR)
|
||||
{
|
||||
if (relay_server_new (protocol_number, protocol_args, port, ssl))
|
||||
if (relay_server_new (option_name, protocol_number, protocol_args,
|
||||
port, ipv4, ipv6, ssl))
|
||||
{
|
||||
/* create config option */
|
||||
weechat_config_new_option (
|
||||
@@ -479,8 +507,10 @@ relay_config_init ()
|
||||
relay_config_file, ptr_section,
|
||||
"allowed_ips", "string",
|
||||
N_("regular expression with IPs allowed to use relay (case insensitive, "
|
||||
"use \"(?-i)\" at beginning to make it case sensitive), example: "
|
||||
"\"^(123.45.67.89|192.160.*)$\""),
|
||||
"use \"(?-i)\" at beginning to make it case sensitive); if IPv6 is "
|
||||
"enabled and that connection is made using IPv4, it will be "
|
||||
"IPv4-mapped IPv6 address (like: \"::ffff:127.0.0.1\"), example: "
|
||||
"\"^((::ffff:)?123.45.67.89|192.160.*)$\""),
|
||||
NULL, 0, 0, "", NULL, 0, NULL, NULL,
|
||||
&relay_config_change_network_allowed_ips, NULL, NULL, NULL);
|
||||
relay_config_network_bind_address = weechat_config_new_option (
|
||||
@@ -499,6 +529,14 @@ relay_config_init ()
|
||||
"compression)"),
|
||||
NULL, 0, 9, "6", NULL, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
relay_config_network_ipv6 = weechat_config_new_option (
|
||||
relay_config_file, ptr_section,
|
||||
"ipv6", "boolean",
|
||||
N_("listen on IPv6 socket by default (in addition to IPv4 which is "
|
||||
"default); protocols IPv4 and IPv6 can be forced (individually or "
|
||||
"together) in the protocol name (see /help relay)"),
|
||||
NULL, 0, 0, "on", NULL, 0, NULL, NULL,
|
||||
&relay_config_change_network_ipv6_cb, NULL, NULL, NULL);
|
||||
relay_config_network_max_clients = weechat_config_new_option (
|
||||
relay_config_file, ptr_section,
|
||||
"max_clients", "integer",
|
||||
|
||||
@@ -39,6 +39,7 @@ extern struct t_config_option *relay_config_color_status[];
|
||||
extern struct t_config_option *relay_config_network_allowed_ips;
|
||||
extern struct t_config_option *relay_config_network_bind_address;
|
||||
extern struct t_config_option *relay_config_network_compression_level;
|
||||
extern struct t_config_option *relay_config_network_ipv6;
|
||||
extern struct t_config_option *relay_config_network_max_clients;
|
||||
extern struct t_config_option *relay_config_network_password;
|
||||
extern struct t_config_option *relay_config_network_ssl_cert_key;
|
||||
|
||||
+217
-104
@@ -45,35 +45,99 @@ struct t_relay_server *last_relay_server = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* relay_server_get_protocol_args: get protocol and arguments from a string
|
||||
* with format "protocol.args"
|
||||
* relay_server_get_protocol_args: get protocol, arguments and options
|
||||
* from a string with format
|
||||
* "options.protocol.args", examples:
|
||||
* irc.freenode
|
||||
* ssl.irc.freenode
|
||||
* ipv4.irc.freenode
|
||||
* ipv6.irc.freenode
|
||||
* ipv4.ipv6.irc.freenode
|
||||
* ipv6.ssl.irc.freenode
|
||||
* weechat
|
||||
* ssl.weechat
|
||||
* ipv6.ssl.weechat
|
||||
* Note: *protocol and *protocol_args must be
|
||||
* freed after use
|
||||
*/
|
||||
|
||||
void
|
||||
relay_server_get_protocol_args (const char *protocol_and_args,
|
||||
int *ssl, char **protocol, char **protocol_args)
|
||||
int *ipv4, int *ipv6, int *ssl,
|
||||
char **protocol, char **protocol_args)
|
||||
{
|
||||
int opt_ipv4, opt_ipv6, opt_ssl;
|
||||
char *pos;
|
||||
|
||||
*ssl = 0;
|
||||
if (strncmp (protocol_and_args, "ssl.", 4) == 0)
|
||||
opt_ipv4 = -1;
|
||||
opt_ipv6 = -1;
|
||||
opt_ssl = 0;
|
||||
while (1)
|
||||
{
|
||||
*ssl = 1;
|
||||
protocol_and_args += 4;
|
||||
if (strncmp (protocol_and_args, "ipv4.", 5) == 0)
|
||||
{
|
||||
opt_ipv4 = 1;
|
||||
protocol_and_args += 5;
|
||||
}
|
||||
else if (strncmp (protocol_and_args, "ipv6.", 5) == 0)
|
||||
{
|
||||
opt_ipv6 = 1;
|
||||
protocol_and_args += 5;
|
||||
}
|
||||
else if (strncmp (protocol_and_args, "ssl.", 4) == 0)
|
||||
{
|
||||
opt_ssl = 1;
|
||||
protocol_and_args += 4;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
pos = strchr (protocol_and_args, '.');
|
||||
if (pos)
|
||||
if ((opt_ipv4 == -1) && (opt_ipv6 == -1))
|
||||
{
|
||||
*protocol = weechat_strndup (protocol_and_args,
|
||||
pos - protocol_and_args);
|
||||
*protocol_args = strdup (pos + 1);
|
||||
/*
|
||||
* no IPv4/IPv6 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
*protocol = strdup (protocol_and_args);
|
||||
*protocol_args = NULL;
|
||||
if (opt_ipv4 == -1)
|
||||
opt_ipv4 = 0;
|
||||
if (opt_ipv6 == -1)
|
||||
opt_ipv6 = 0;
|
||||
}
|
||||
if (!opt_ipv4 && !opt_ipv6)
|
||||
{
|
||||
/* both IPv4/IPv6 disabled (should never occur!) */
|
||||
opt_ipv4 = 1;
|
||||
}
|
||||
if (ipv4)
|
||||
*ipv4 = opt_ipv4;
|
||||
if (ipv6)
|
||||
*ipv6 = opt_ipv6;
|
||||
if (ssl)
|
||||
*ssl = opt_ssl;
|
||||
|
||||
pos = strchr (protocol_and_args, '.');
|
||||
if (pos)
|
||||
{
|
||||
if (protocol)
|
||||
{
|
||||
*protocol = weechat_strndup (protocol_and_args,
|
||||
pos - protocol_and_args);
|
||||
}
|
||||
if (protocol_args)
|
||||
*protocol_args = strdup (pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (protocol)
|
||||
*protocol = strdup (protocol_and_args);
|
||||
if (protocol_args)
|
||||
*protocol_args = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,40 +148,16 @@ relay_server_get_protocol_args (const char *protocol_and_args,
|
||||
struct t_relay_server *
|
||||
relay_server_search (const char *protocol_and_args)
|
||||
{
|
||||
int ssl;
|
||||
char *protocol, *protocol_args;
|
||||
struct t_relay_server *ptr_server;
|
||||
|
||||
relay_server_get_protocol_args (protocol_and_args,
|
||||
&ssl, &protocol, &protocol_args);
|
||||
|
||||
ptr_server = NULL;
|
||||
|
||||
if (protocol)
|
||||
for (ptr_server = relay_servers; ptr_server;
|
||||
ptr_server = ptr_server->next_server)
|
||||
{
|
||||
for (ptr_server = relay_servers; ptr_server;
|
||||
ptr_server = ptr_server->next_server)
|
||||
{
|
||||
if ((ptr_server->ssl == ssl)
|
||||
&& (strcmp (protocol, relay_protocol_string[ptr_server->protocol]) == 0))
|
||||
{
|
||||
if (!protocol_args && !ptr_server->protocol_args)
|
||||
break;
|
||||
if (protocol_args && ptr_server->protocol_args
|
||||
&& (strcmp (protocol_args, ptr_server->protocol_args) == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strcmp (protocol_and_args, ptr_server->protocol_string) == 0)
|
||||
return ptr_server;
|
||||
}
|
||||
|
||||
if (protocol)
|
||||
free (protocol);
|
||||
if (protocol_args)
|
||||
free (protocol_args);
|
||||
|
||||
return ptr_server;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -160,11 +200,8 @@ relay_server_close_socket (struct t_relay_server *server)
|
||||
if (!relay_signal_upgrade_received)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s: socket closed for %s%s%s (port %d)"),
|
||||
RELAY_PLUGIN_NAME,
|
||||
relay_protocol_string[server->protocol],
|
||||
(server->protocol_args) ? "." : "",
|
||||
(server->protocol_args) ? server->protocol_args : "",
|
||||
_("%s: socket closed for %s (port %d)"),
|
||||
RELAY_PLUGIN_NAME, server->protocol_string,
|
||||
server->port);
|
||||
}
|
||||
}
|
||||
@@ -179,45 +216,67 @@ relay_server_sock_cb (void *data, int fd)
|
||||
{
|
||||
struct t_relay_server *server;
|
||||
struct sockaddr_in client_addr;
|
||||
socklen_t client_length;
|
||||
struct sockaddr_in6 client_addr6;
|
||||
socklen_t client_addr_size;
|
||||
void *ptr_addr;
|
||||
int client_fd, flags, set;
|
||||
char ipv4_address[INET_ADDRSTRLEN + 1], *ptr_address;
|
||||
char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1];
|
||||
char *ptr_ip_address;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) fd;
|
||||
|
||||
server = (struct t_relay_server *)data;
|
||||
|
||||
client_length = sizeof (client_addr);
|
||||
memset (&client_addr, 0, client_length);
|
||||
if (server->ipv6)
|
||||
{
|
||||
ptr_addr = &client_addr6;
|
||||
client_addr_size = sizeof (struct sockaddr_in6);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_addr = &client_addr;
|
||||
client_addr_size = sizeof (struct sockaddr_in);
|
||||
}
|
||||
|
||||
client_fd = accept (server->sock, (struct sockaddr *) &client_addr,
|
||||
&client_length);
|
||||
memset (&client_addr, 0, client_addr_size);
|
||||
|
||||
client_fd = accept (server->sock, (struct sockaddr *)ptr_addr,
|
||||
&client_addr_size);
|
||||
if (client_fd < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: cannot accept client on port %d (%s%s%s)"),
|
||||
weechat_prefix ("error"),
|
||||
RELAY_PLUGIN_NAME,
|
||||
server->port,
|
||||
relay_protocol_string[server->protocol],
|
||||
(server->protocol_args) ? "." : "",
|
||||
(server->protocol_args) ? server->protocol_args : "");
|
||||
_("%s%s: cannot accept client on port %d (%s)"),
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
|
||||
server->port, server->protocol_string);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
ptr_address = NULL;
|
||||
if (inet_ntop (AF_INET,
|
||||
&(client_addr.sin_addr),
|
||||
ipv4_address,
|
||||
INET_ADDRSTRLEN))
|
||||
ptr_ip_address = NULL;
|
||||
if (server->ipv6)
|
||||
{
|
||||
ptr_address = ipv4_address;
|
||||
if (inet_ntop (AF_INET6,
|
||||
&(client_addr6.sin6_addr),
|
||||
ipv6_address,
|
||||
INET6_ADDRSTRLEN))
|
||||
{
|
||||
ptr_ip_address = ipv6_address;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inet_ntop (AF_INET,
|
||||
&(client_addr.sin_addr),
|
||||
ipv4_address,
|
||||
INET_ADDRSTRLEN))
|
||||
{
|
||||
ptr_ip_address = ipv4_address;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if IP is allowed, if not, just close socket */
|
||||
if (relay_config_regex_allowed_ips
|
||||
&& (regexec (relay_config_regex_allowed_ips, ptr_address, 0, NULL, 0) != 0))
|
||||
&& (regexec (relay_config_regex_allowed_ips, ptr_ip_address, 0, NULL, 0) != 0))
|
||||
{
|
||||
if (weechat_relay_plugin->debug >= 2)
|
||||
{
|
||||
@@ -225,7 +284,7 @@ relay_server_sock_cb (void *data, int fd)
|
||||
_("%s%s: IP address \"%s\" not allowed for relay"),
|
||||
weechat_prefix ("error"),
|
||||
RELAY_PLUGIN_NAME,
|
||||
ptr_address);
|
||||
ptr_ip_address);
|
||||
}
|
||||
close (client_fd);
|
||||
return WEECHAT_RC_OK;
|
||||
@@ -251,7 +310,7 @@ relay_server_sock_cb (void *data, int fd)
|
||||
}
|
||||
|
||||
/* add the client */
|
||||
relay_client_new (client_fd, ptr_address, server);
|
||||
relay_client_new (client_fd, ptr_ip_address, server);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
@@ -263,10 +322,49 @@ relay_server_sock_cb (void *data, int fd)
|
||||
int
|
||||
relay_server_create_socket (struct t_relay_server *server)
|
||||
{
|
||||
int set, max_clients;
|
||||
int domain, set, max_clients, addr_size;
|
||||
struct sockaddr_in server_addr;
|
||||
struct sockaddr_in6 server_addr6;
|
||||
void *ptr_addr;
|
||||
|
||||
server->sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (server->ipv6)
|
||||
{
|
||||
domain = AF_INET6;
|
||||
memset (&server_addr6, 0, sizeof (struct sockaddr_in6));
|
||||
server_addr6.sin6_family = domain;
|
||||
server_addr6.sin6_port = htons (server->port);
|
||||
server_addr6.sin6_addr = in6addr_any;
|
||||
ptr_addr = &server_addr6;
|
||||
addr_size = sizeof (struct sockaddr_in6);
|
||||
}
|
||||
else
|
||||
{
|
||||
domain = AF_INET;
|
||||
memset (&server_addr, 0, sizeof (struct sockaddr_in));
|
||||
server_addr.sin_family = domain;
|
||||
server_addr.sin_port = htons (server->port);
|
||||
if (weechat_config_string (relay_config_network_bind_address)
|
||||
&& weechat_config_string (relay_config_network_bind_address)[0])
|
||||
{
|
||||
server_addr.sin_addr.s_addr = inet_addr (weechat_config_string (relay_config_network_bind_address));
|
||||
}
|
||||
else
|
||||
{
|
||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
ptr_addr = &server_addr;
|
||||
addr_size = sizeof (struct sockaddr_in);
|
||||
}
|
||||
if (weechat_config_string (relay_config_network_bind_address)
|
||||
&& weechat_config_string (relay_config_network_bind_address)[0])
|
||||
{
|
||||
inet_pton (domain,
|
||||
weechat_config_string (relay_config_network_bind_address),
|
||||
ptr_addr);
|
||||
}
|
||||
|
||||
/* create socket */
|
||||
server->sock = socket (domain, SOCK_STREAM, 0);
|
||||
if (server->sock < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
@@ -275,55 +373,59 @@ relay_server_create_socket (struct t_relay_server *server)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
/* set option IPV6_V6ONLY to 0 or 1 */
|
||||
if (server->ipv6)
|
||||
{
|
||||
set = (server->ipv4) ? 0 : 1;
|
||||
if (setsockopt (server->sock, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
(void *) &set, sizeof (set)) < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: cannot set socket option \"IPV6_V6ONLY\" "
|
||||
"to value %d"),
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
|
||||
set);
|
||||
close (server->sock);
|
||||
server->sock = -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set option SO_REUSEADDR to 1 */
|
||||
set = 1;
|
||||
if (setsockopt (server->sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(void *) &set, sizeof (set)) < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: cannot set socket option "
|
||||
"\"SO_REUSEADDR\""),
|
||||
_("%s%s: cannot set socket option \"SO_REUSEADDR\""),
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
|
||||
close (server->sock);
|
||||
server->sock = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set option SO_KEEPALIVE to 1 */
|
||||
set = 1;
|
||||
if (setsockopt (server->sock, SOL_SOCKET, SO_KEEPALIVE,
|
||||
(void *) &set, sizeof (set)) < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: cannot set socket option "
|
||||
"\"SO_KEEPALIVE\""),
|
||||
_("%s%s: cannot set socket option \"SO_KEEPALIVE\""),
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME);
|
||||
close (server->sock);
|
||||
server->sock = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&server_addr, 0, sizeof(struct sockaddr_in));
|
||||
server_addr.sin_family = AF_INET;
|
||||
if (weechat_config_string (relay_config_network_bind_address)
|
||||
&& weechat_config_string (relay_config_network_bind_address)[0])
|
||||
{
|
||||
server_addr.sin_addr.s_addr = inet_addr (weechat_config_string (relay_config_network_bind_address));
|
||||
}
|
||||
else
|
||||
{
|
||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
server_addr.sin_port = htons (server->port);
|
||||
|
||||
if (bind (server->sock, (struct sockaddr *) &server_addr,
|
||||
sizeof (server_addr)) < 0)
|
||||
/* bind */
|
||||
if (bind (server->sock, (struct sockaddr *)ptr_addr, addr_size) < 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: error with \"bind\" on port %d (%s%s%s)"),
|
||||
_("%s%s: error with \"bind\" on port %d (%s)"),
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
|
||||
server->port,
|
||||
relay_protocol_string[server->protocol],
|
||||
(server->protocol_args) ? "." : "",
|
||||
(server->protocol_args) ? server->protocol_args : "");
|
||||
server->port, server->protocol_string);
|
||||
close (server->sock);
|
||||
server->sock = -1;
|
||||
return 0;
|
||||
@@ -334,13 +436,11 @@ relay_server_create_socket (struct t_relay_server *server)
|
||||
listen (server->sock, max_clients);
|
||||
|
||||
weechat_printf (NULL,
|
||||
_("%s: listening on port %d (relay: %s%s%s,%s max %d clients)"),
|
||||
_("%s: listening on port %d (relay: %s, %s, max %d clients)"),
|
||||
RELAY_PLUGIN_NAME,
|
||||
server->port,
|
||||
relay_protocol_string[server->protocol],
|
||||
(server->protocol_args) ? "." : "",
|
||||
(server->protocol_args) ? server->protocol_args : "",
|
||||
(server->ssl) ? " SSL," : "",
|
||||
server->protocol_string,
|
||||
((server->ipv4 && server->ipv6) ? "IPv4+6" : ((server->ipv6) ? "IPv6" : "IPv4")),
|
||||
max_clients);
|
||||
|
||||
server->hook_fd = weechat_hook_fd (server->sock,
|
||||
@@ -358,12 +458,15 @@ relay_server_create_socket (struct t_relay_server *server)
|
||||
*/
|
||||
|
||||
struct t_relay_server *
|
||||
relay_server_new (enum t_relay_protocol protocol,
|
||||
const char *protocol_args,
|
||||
int port, int ssl)
|
||||
relay_server_new (const char *protocol_string, enum t_relay_protocol protocol,
|
||||
const char *protocol_args, int port, int ipv4, int ipv6,
|
||||
int ssl)
|
||||
{
|
||||
struct t_relay_server *new_server;
|
||||
|
||||
if (!protocol_string)
|
||||
return NULL;
|
||||
|
||||
if (relay_server_search_port (port))
|
||||
{
|
||||
weechat_printf (NULL, _("%s%s: error: port \"%d\" is already used"),
|
||||
@@ -375,10 +478,13 @@ relay_server_new (enum t_relay_protocol protocol,
|
||||
new_server = malloc (sizeof (*new_server));
|
||||
if (new_server)
|
||||
{
|
||||
new_server->protocol_string = strdup (protocol_string);
|
||||
new_server->protocol = protocol;
|
||||
new_server->protocol_args =
|
||||
(protocol_args) ? strdup (protocol_args) : NULL;
|
||||
new_server->port = port;
|
||||
new_server->ipv4 = ipv4;
|
||||
new_server->ipv6 = ipv6;
|
||||
new_server->ssl = ssl;
|
||||
new_server->sock = -1;
|
||||
new_server->hook_fd = NULL;
|
||||
@@ -386,6 +492,8 @@ relay_server_new (enum t_relay_protocol protocol,
|
||||
|
||||
if (!relay_server_create_socket (new_server))
|
||||
{
|
||||
if (new_server->protocol_string)
|
||||
free (new_server->protocol_string);
|
||||
if (new_server->protocol_args)
|
||||
free (new_server->protocol_args);
|
||||
free (new_server);
|
||||
@@ -452,6 +560,8 @@ relay_server_free (struct t_relay_server *server)
|
||||
|
||||
/* free data */
|
||||
relay_server_close_socket (server);
|
||||
if (server->protocol_string)
|
||||
free (server->protocol_string);
|
||||
if (server->protocol_args)
|
||||
free (server->protocol_args);
|
||||
|
||||
@@ -487,11 +597,14 @@ relay_server_print_log ()
|
||||
{
|
||||
weechat_log_printf ("");
|
||||
weechat_log_printf ("[relay server (addr:0x%lx)]", ptr_server);
|
||||
weechat_log_printf (" protocol_string . . : '%s'", ptr_server->protocol_string);
|
||||
weechat_log_printf (" protocol. . . . . . : %d (%s)",
|
||||
ptr_server->protocol,
|
||||
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 (" ipv4. . . . . . . . : %d", ptr_server->ipv4);
|
||||
weechat_log_printf (" ipv6. . . . . . . . : %d", ptr_server->ipv6);
|
||||
weechat_log_printf (" ssl . . . . . . . . : %d", ptr_server->ssl);
|
||||
weechat_log_printf (" sock. . . . . . . . : %d", ptr_server->sock);
|
||||
weechat_log_printf (" hook_fd . . . . . . : 0x%lx", ptr_server->hook_fd);
|
||||
|
||||
@@ -26,10 +26,13 @@
|
||||
|
||||
struct t_relay_server
|
||||
{
|
||||
enum t_relay_protocol protocol; /* protocol (irc,..) */
|
||||
char *protocol_string; /* example: "ipv6.ssl.irc.freenode" */
|
||||
enum t_relay_protocol protocol; /* protocol (irc/weechat) */
|
||||
char *protocol_args; /* arguments used for protocol */
|
||||
/* example: server for irc protocol */
|
||||
int port; /* listening on this port */
|
||||
int ipv4; /* IPv4 protocol enabled */
|
||||
int ipv6; /* IPv6 protocol enabled */
|
||||
int ssl; /* 1 if SSL is enabled */
|
||||
int sock; /* socket for connection */
|
||||
struct t_hook *hook_fd; /* hook for socket */
|
||||
@@ -42,6 +45,7 @@ extern struct t_relay_server *relay_servers;
|
||||
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,
|
||||
char **protocol,
|
||||
char **protocol_args);
|
||||
@@ -49,9 +53,11 @@ 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 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 (enum t_relay_protocol protocol,
|
||||
extern struct t_relay_server *relay_server_new (const char *protocol_string,
|
||||
enum t_relay_protocol protocol,
|
||||
const char *protocol_args,
|
||||
int port, int ssl);
|
||||
int port, int ipv4, int ipv6,
|
||||
int ssl);
|
||||
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 ();
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "relay.h"
|
||||
@@ -65,7 +66,7 @@ relay_protocol_search (const char *name)
|
||||
|
||||
for (i = 0; i < RELAY_NUM_PROTOCOLS; i++)
|
||||
{
|
||||
if (weechat_strcasecmp (relay_protocol_string[i], name) == 0)
|
||||
if (strcmp (relay_protocol_string[i], name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user