From 88e2449f832d5c64b8ea30047f15319a66b17c1f Mon Sep 17 00:00:00 2001
From: Lukas Mai
Date: Wed, 17 Feb 2016 22:34:44 +0100
Subject: [PATCH 1/5] fix formatting
---
src/irc/proxy/listen.c | 70 +++++++++++++++++++++---------------------
1 file changed, 35 insertions(+), 35 deletions(-)
diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c
index 5dc9a704..ad1e4588 100644
--- a/src/irc/proxy/listen.c
+++ b/src/irc/proxy/listen.c
@@ -48,7 +48,7 @@ static void remove_client(CLIENT_REC *rec)
signal_emit("proxy client disconnected", 1, rec);
printtext(rec->server, NULL, MSGLEVEL_CLIENTNOTICE,
- "Proxy: Client %s:%d disconnected", rec->host, rec->port);
+ "Proxy: Client %s:%d disconnected", rec->host, rec->port);
g_free(rec->proxy_address);
net_sendbuffer_destroy(rec->handle, TRUE);
@@ -59,7 +59,7 @@ static void remove_client(CLIENT_REC *rec)
}
static void proxy_redirect_event(CLIENT_REC *client, const char *command,
- int count, const char *arg, int remote)
+ int count, const char *arg, int remote)
{
char *str;
@@ -67,7 +67,7 @@ static void proxy_redirect_event(CLIENT_REC *client, const char *command,
str = g_strdup_printf("proxy %p", client);
server_redirect_event(client->server, command, count,
- arg, remote, NULL, "", str, NULL);
+ arg, remote, NULL, "", str, NULL);
g_free(str);
}
@@ -94,15 +94,15 @@ static void grab_who(CLIENT_REC *client, const char *channel)
}
proxy_redirect_event(client, "who",
- client->server->one_endofwho ? 1 : count,
- arg->str, -1);
+ client->server->one_endofwho ? 1 : count,
+ arg->str, -1);
g_strfreev(list);
g_string_free(arg, TRUE);
}
static void handle_client_connect_cmd(CLIENT_REC *client,
- const char *cmd, const char *args)
+ const char *cmd, const char *args)
{
const char *password;
@@ -114,7 +114,7 @@ static void handle_client_connect_cmd(CLIENT_REC *client,
else {
/* wrong password! */
remove_client(client);
- return;
+ return;
}
} else if (g_strcmp0(cmd, "NICK") == 0) {
g_free_not_null(client->nick);
@@ -130,8 +130,8 @@ static void handle_client_connect_cmd(CLIENT_REC *client,
} else {
signal_emit("proxy client connected", 1, client);
printtext(client->server, NULL, MSGLEVEL_CLIENTNOTICE,
- "Proxy: Client %s:%d connected",
- client->host, client->port);
+ "Proxy: Client %s:%d connected",
+ client->host, client->port);
client->connected = TRUE;
proxy_dump_data(client);
}
@@ -139,7 +139,7 @@ static void handle_client_connect_cmd(CLIENT_REC *client,
}
static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args,
- const char *data)
+ const char *data)
{
GSList *tmp;
if (!client->connected) {
@@ -162,8 +162,8 @@ static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args,
g_ascii_strcasecmp(target, client->proxy_address) == 0 ||
g_ascii_strcasecmp(target, client->nick) == 0) {
proxy_outdata(client, ":%s PONG %s :%s\r\n",
- client->proxy_address,
- client->proxy_address, origin);
+ client->proxy_address,
+ client->proxy_address, origin);
g_free(params);
return;
}
@@ -174,25 +174,25 @@ static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args,
if (g_ascii_strcasecmp(args, "CTCP ON") == 0) {
/* client wants all ctcps */
client->want_ctcp = 1;
- for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
+ for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
CLIENT_REC *rec = tmp->data;
- if ((g_ascii_strcasecmp(client->listen->ircnet,rec->listen->ircnet) == 0) &&
- /* kludgy way to check if the clients aren't the same */
- (client->recv_tag != rec->recv_tag)) {
- if (rec->want_ctcp == 1)
- proxy_outdata(rec, ":%s NOTICE %s :Another client is now receiving CTCPs sent to %s\r\n",
- rec->proxy_address, rec->nick, rec->listen->ircnet);
- rec->want_ctcp = 0;
- }
+ if (g_ascii_strcasecmp(client->listen->ircnet, rec->listen->ircnet) == 0 &&
+ /* kludgy way to check if the clients aren't the same */
+ client->recv_tag != rec->recv_tag) {
+ if (rec->want_ctcp == 1)
+ proxy_outdata(rec, ":%s NOTICE %s :Another client is now receiving CTCPs sent to %s\r\n",
+ rec->proxy_address, rec->nick, rec->listen->ircnet);
+ rec->want_ctcp = 0;
+ }
}
proxy_outdata(client, ":%s NOTICE %s :You're now receiving CTCPs sent to %s\r\n",
- client->proxy_address, client->nick,client->listen->ircnet);
+ client->proxy_address, client->nick, client->listen->ircnet);
} else if (g_ascii_strcasecmp(args, "CTCP OFF") == 0) {
- /* client wants proxy to handle all ctcps */
+ /* client wants proxy to handle all ctcps */
client->want_ctcp = 0;
proxy_outdata(client, ":%s NOTICE %s :Proxy is now handling itself CTCPs sent to %s\r\n",
- client->proxy_address, client->nick, client->listen->ircnet);
+ client->proxy_address, client->nick, client->listen->ircnet);
} else {
signal_emit("proxy client command", 3, client, args, data);
}
@@ -201,11 +201,11 @@ static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args,
if (client->server == NULL || !client->server->connected) {
proxy_outdata(client, ":%s NOTICE %s :Not connected to server\r\n",
- client->proxy_address, client->nick);
- return;
+ client->proxy_address, client->nick);
+ return;
}
- /* check if the command could be redirected */
+ /* check if the command could be redirected */
if (g_strcmp0(cmd, "WHO") == 0)
grab_who(client, args);
else if (g_strcmp0(cmd, "WHOWAS") == 0)
@@ -263,29 +263,29 @@ static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args,
char *params, *target, *msg;
params = event_get_params(args, 2 | PARAM_FLAG_GETREST,
- &target, &msg);
+ &target, &msg);
proxy_outserver_all_except(client, "PRIVMSG %s", args);
ignore_next = TRUE;
if (*msg != '\001' || msg[strlen(msg)-1] != '\001') {
signal_emit(server_ischannel(SERVER(client->server), target) ?
- "message own_public" : "message own_private", 4,
- client->server, msg, target, target);
+ "message own_public" : "message own_private", 4,
+ client->server, msg, target, target);
} else if (strncmp(msg+1, "ACTION ", 7) == 0) {
/* action */
- msg[strlen(msg)-1] = '\0';
+ msg[strlen(msg)-1] = '\0';
signal_emit("message irc own_action", 3,
- client->server, msg+8, target);
+ client->server, msg+8, target);
} else {
- /* CTCP */
+ /* CTCP */
char *p;
msg[strlen(msg)-1] = '\0';
p = strchr(msg, ' ');
- if (p != NULL) *p++ = '\0'; else p = "";
+ if (p != NULL) *p++ = '\0'; else p = "";
signal_emit("message irc own_ctcp", 4,
- client->server, msg+1, p, target);
+ client->server, msg+1, p, target);
}
ignore_next = FALSE;
g_free(params);
From 4732e33ca9c9f9a48b57062ab254bf3aa90078bf Mon Sep 17 00:00:00 2001
From: Lukas Mai
Date: Wed, 17 Feb 2016 23:06:51 +0100
Subject: [PATCH 2/5] irssi proxy: allow multiplexing multiple networks over a
single port
---
src/irc/proxy/listen.c | 58 +++++++++++++++++++++++++++++++++---------
src/irc/proxy/proxy.h | 1 +
src/perl/irc/Irc.xs | 1 +
3 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c
index ad1e4588..2322d47a 100644
--- a/src/irc/proxy/listen.c
+++ b/src/irc/proxy/listen.c
@@ -108,14 +108,44 @@ static void handle_client_connect_cmd(CLIENT_REC *client,
password = settings_get_str("irssiproxy_password");
- if (password != NULL && g_strcmp0(cmd, "PASS") == 0) {
- if (g_strcmp0(password, args) == 0)
- client->pass_sent = TRUE;
- else {
+ if (g_strcmp0(cmd, "PASS") == 0) {
+ const char *args_pass;
+
+ if (!client->multiplex) {
+ args_pass = args;
+ } else {
+ IRC_SERVER_REC *server;
+ char *tag;
+ const char *tag_end;
+
+ if ((tag_end = strchr(args, ':'))) {
+ args_pass = tag_end + 1;
+ } else {
+ tag_end = args + strlen(args);
+ args_pass = "";
+ }
+
+ tag = g_strndup(args, tag_end - args);
+ server = IRC_SERVER(server_find_chatnet(tag));
+ g_free(tag);
+
+ if (!server) {
+ /* an invalid network was specified */
+ remove_client(client);
+ return;
+ }
+
+ client->server = server;
+ g_free(client->proxy_address);
+ client->proxy_address = g_strdup_printf("%*s.proxy", (int)(tag_end - args), args);
+ }
+
+ if (password && g_strcmp0(password, args_pass) != 0) {
/* wrong password! */
remove_client(client);
return;
}
+ client->pass_sent = TRUE;
} else if (g_strcmp0(cmd, "NICK") == 0) {
g_free_not_null(client->nick);
client->nick = g_strdup(args);
@@ -124,7 +154,7 @@ static void handle_client_connect_cmd(CLIENT_REC *client,
}
if (client->nick != NULL && client->user_sent) {
- if (*password != '\0' && !client->pass_sent) {
+ if ((*password != '\0' || client->multiplex) && !client->pass_sent) {
/* client didn't send us PASS, kill it */
remove_client(client);
} else {
@@ -337,7 +367,7 @@ static void sig_listen(LISTEN_REC *listen)
CLIENT_REC *rec;
IPADDR ip;
NET_SENDBUF_REC *sendbuf;
- GIOChannel *handle;
+ GIOChannel *handle;
char host[MAX_IP_LEN];
int port;
@@ -352,9 +382,13 @@ static void sig_listen(LISTEN_REC *listen)
rec = g_new0(CLIENT_REC, 1);
rec->listen = listen;
rec->handle = sendbuf;
- rec->host = g_strdup(host);
+ rec->host = g_strdup(host);
rec->port = port;
- if (g_strcmp0(listen->ircnet, "*") == 0) {
+ if (g_strcmp0(listen->ircnet, "?") == 0) {
+ rec->multiplex = TRUE;
+ rec->proxy_address = g_strdup("multiplex.proxy");
+ rec->server = NULL;
+ } else if (g_strcmp0(listen->ircnet, "*") == 0) {
rec->proxy_address = g_strdup("irc.proxy");
rec->server = servers == NULL ? NULL : IRC_SERVER(servers->data);
} else {
@@ -363,15 +397,15 @@ static void sig_listen(LISTEN_REC *listen)
IRC_SERVER(server_find_chatnet(listen->ircnet));
}
rec->recv_tag = g_input_add(handle, G_INPUT_READ,
- (GInputFunction) sig_listen_client, rec);
+ (GInputFunction) sig_listen_client, rec);
proxy_clients = g_slist_prepend(proxy_clients, rec);
- rec->listen->clients = g_slist_prepend(rec->listen->clients, rec);
+ listen->clients = g_slist_prepend(listen->clients, rec);
signal_emit("proxy client connecting", 1, rec);
printtext(rec->server, NULL, MSGLEVEL_CLIENTNOTICE,
- "Proxy: New client %s:%d on port %d (%s)",
- rec->host, rec->port, listen->port, listen->ircnet);
+ "Proxy: New client %s:%d on port %d (%s)",
+ rec->host, rec->port, listen->port, listen->ircnet);
}
static void sig_incoming(IRC_SERVER_REC *server, const char *line)
diff --git a/src/irc/proxy/proxy.h b/src/irc/proxy/proxy.h
index 158b0675..f37e9c95 100644
--- a/src/irc/proxy/proxy.h
+++ b/src/irc/proxy/proxy.h
@@ -29,6 +29,7 @@ typedef struct {
unsigned int user_sent:1;
unsigned int connected:1;
unsigned int want_ctcp:1;
+ unsigned int multiplex:1;
} CLIENT_REC;
#endif
diff --git a/src/perl/irc/Irc.xs b/src/perl/irc/Irc.xs
index db5c5f79..4217b4eb 100644
--- a/src/perl/irc/Irc.xs
+++ b/src/perl/irc/Irc.xs
@@ -157,6 +157,7 @@ static void perl_client_fill_hash(HV *hv, CLIENT_REC *client)
(void) hv_store(hv, "user_sent", 9, newSViv(client->user_sent), 0);
(void) hv_store(hv, "connected", 9, newSViv(client->connected), 0);
(void) hv_store(hv, "want_ctcp", 9, newSViv(client->want_ctcp), 0);
+ (void) hv_store(hv, "multiplex", 9, newSViv(client->multiplex), 0);
(void) hv_store(hv, "ircnet", 6, new_pv(client->listen->ircnet), 0);
}
From effb00b858db17b3abf27661682255bd8139a95a Mon Sep 17 00:00:00 2001
From: Lukas Mai
Date: Thu, 18 Feb 2016 01:17:24 +0100
Subject: [PATCH 3/5] add some documentation
---
docs/proxy.txt | 12 ++++++++++++
docs/startup-HOWTO.html | 17 +++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/docs/proxy.txt b/docs/proxy.txt
index e6360a82..224d24e3 100644
--- a/docs/proxy.txt
+++ b/docs/proxy.txt
@@ -30,6 +30,18 @@ There we have 3 different irc networks answering in 3 ports. Note that
you'll have to make the correct /IRCNET ADD and /SERVER ADD commands to
make it work properly.
+The special network name "?" allows the client to select the network
+dynamically on connect:
+
+ /SET irssiproxy_ports ?=2777
+
+Now the client can send : as the server password, e.g.
+
+ /CONNECT ... 2777 efnet:secret
+
+to connect to efnet. If there is no irssiproxy_password set, you can
+omit the ":" and just send the network name as the password.
+
By default, the proxy binds to all available interfaces. To make it
only listen on (for example) the loopback address:
diff --git a/docs/startup-HOWTO.html b/docs/startup-HOWTO.html
index deff3116..1b912b96 100644
--- a/docs/startup-HOWTO.html
+++ b/docs/startup-HOWTO.html
@@ -735,6 +735,13 @@ reason, and you only use one server connection, you may simply set:
/SET irssiproxy_ports *=2777
+The special network name ?
allows the client to select the
+network dynamically on connect (see below):
+
+
+/SET irssiproxy_ports ?=2777
+
+
Usage in client side:
Just connect to the irssi proxy like it is a normal server with password
@@ -745,6 +752,16 @@ specified in /SET irssiproxy_password
. For example:
/SERVER ADD -network efnet my.irssi-proxy.org 2778 secret
+Or, if you used ?
in irssiproxy_ports
:
+
+
+/SERVER ADD -network IRCnet my.irssi-proxy.org 2777 IRCnet:secret
+/SERVER ADD -network efnet my.irssi-proxy.org 2777 efnet:secret
+
+
+I.e. the network to connect to is specified as part of the password,
+separated by :
from the actual proxy password.
+
Irssi proxy works fine with other IRC clients as well.
SOCKS
From c9ce0c521a559727493b42f422b5cc10ede2d9b2 Mon Sep 17 00:00:00 2001
From: Lukas Mai
Date: Thu, 18 Feb 2016 02:23:00 +0100
Subject: [PATCH 4/5] make pointer check explicit
---
src/irc/proxy/listen.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c
index 2322d47a..cd946baa 100644
--- a/src/irc/proxy/listen.c
+++ b/src/irc/proxy/listen.c
@@ -118,7 +118,7 @@ static void handle_client_connect_cmd(CLIENT_REC *client,
char *tag;
const char *tag_end;
- if ((tag_end = strchr(args, ':'))) {
+ if ((tag_end = strchr(args, ':')) != NULL) {
args_pass = tag_end + 1;
} else {
tag_end = args + strlen(args);
From 3167ccfbc21e6918133e5898f5e76596bb6de788 Mon Sep 17 00:00:00 2001
From: Lukas Mai
Date: Thu, 18 Feb 2016 02:23:09 +0100
Subject: [PATCH 5/5] remove redundant check
---
src/irc/proxy/listen.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c
index cd946baa..3ec83773 100644
--- a/src/irc/proxy/listen.c
+++ b/src/irc/proxy/listen.c
@@ -140,7 +140,7 @@ static void handle_client_connect_cmd(CLIENT_REC *client,
client->proxy_address = g_strdup_printf("%*s.proxy", (int)(tag_end - args), args);
}
- if (password && g_strcmp0(password, args_pass) != 0) {
+ if (g_strcmp0(password, args_pass) != 0) {
/* wrong password! */
remove_client(client);
return;