1
0
mirror of https://github.com/irssi/irssi.git synced 2024-11-03 04:27:19 -05:00

Merge pull request #425 from mauke/irssiproxy-multiplex

irssi proxy: allow multiplexing multiple networks over a single port
This commit is contained in:
ailin-nemui 2016-02-24 16:14:43 +01:00
commit f83a29b764
5 changed files with 112 additions and 47 deletions

View File

@ -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 <network>:<password> 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:

View File

@ -735,6 +735,13 @@ reason, and you only use one server connection, you may simply set:</p>
/SET irssiproxy_ports *=2777
</pre>
<p>The special network name <code>?</code> allows the client to select the
network dynamically on connect (see below):</p>
<pre>
/SET irssiproxy_ports ?=2777
</pre>
<p>Usage in client side:</p>
<p>Just connect to the irssi proxy like it is a normal server with password
@ -745,6 +752,16 @@ specified in <code>/SET irssiproxy_password</code>. For example:</p>
/SERVER ADD -network efnet my.irssi-proxy.org 2778 secret
</pre>
<p>Or, if you used <code>?</code> in <code>irssiproxy_ports</code>:</p>
<pre>
/SERVER ADD -network IRCnet my.irssi-proxy.org 2777 IRCnet:secret
/SERVER ADD -network efnet my.irssi-proxy.org 2777 efnet:secret
</pre>
<p>I.e. the network to connect to is specified as part of the password,
separated by <code>:</code> from the actual proxy password.</p>
<p>Irssi proxy works fine with other IRC clients as well.</p>
<p><strong>SOCKS</strong></p>

View File

@ -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, ':')) != NULL) {
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 (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 {
@ -176,9 +206,9 @@ static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args,
client->want_ctcp = 1;
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) &&
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)) {
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);
@ -187,7 +217,7 @@ static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args,
}
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->want_ctcp = 0;
@ -354,7 +384,11 @@ static void sig_listen(LISTEN_REC *listen)
rec->handle = sendbuf;
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 {
@ -366,7 +400,7 @@ static void sig_listen(LISTEN_REC *listen)
(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,

View File

@ -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

View File

@ -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);
}