Rewrite socks to async
Not quite working yet, however it's a massive and important change.
This commit is contained in:
114
zyklonb.c
114
zyklonb.c
@@ -1647,16 +1647,99 @@ end:
|
||||
irc_reset_connection_timeouts (ctx);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// The bot is currently mostly synchronous (which also makes it shorter),
|
||||
// however our current SOCKS code is not, hence we must wrap it.
|
||||
|
||||
struct irc_socks_data
|
||||
{
|
||||
struct bot_context *ctx; ///< Bot context
|
||||
struct poller inner_poller; ///< Special inner poller
|
||||
bool polling; ///< Inner poller is no longer needed
|
||||
struct socks_connector connector; ///< SOCKS connector
|
||||
bool succeeded; ///< Were we successful in connecting?
|
||||
};
|
||||
|
||||
static void
|
||||
irc_on_socks_connected (void *user_data, int socket)
|
||||
{
|
||||
struct irc_socks_data *data = user_data;
|
||||
data->ctx->irc_fd = socket;
|
||||
data->succeeded = true;
|
||||
data->polling = true;
|
||||
}
|
||||
|
||||
static void
|
||||
irc_on_socks_failure (void *user_data)
|
||||
{
|
||||
struct irc_socks_data *data = user_data;
|
||||
data->succeeded = false;
|
||||
data->polling = true;
|
||||
}
|
||||
|
||||
static void
|
||||
irc_on_socks_connecting (void *user_data,
|
||||
const char *address, const char *via, const char *version)
|
||||
{
|
||||
(void) user_data;
|
||||
print_status ("connecting to %s via %s (%s)...", address, via, version);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_on_socks_error (void *user_data, const char *error)
|
||||
{
|
||||
(void) user_data;
|
||||
print_error ("%s: %s", "SOCKS connection failed", error);
|
||||
}
|
||||
|
||||
static bool
|
||||
irc_establish_connection_socks (struct bot_context *ctx,
|
||||
const char *socks_host, const char *socks_port,
|
||||
const char *host, const char *service, struct error **e)
|
||||
{
|
||||
struct irc_socks_data data;
|
||||
struct poller *poller = &data.inner_poller;
|
||||
struct socks_connector *connector = &data.connector;
|
||||
|
||||
data.ctx = ctx;
|
||||
poller_init (poller);
|
||||
data.polling = true;
|
||||
socks_connector_init (connector, poller);
|
||||
data.succeeded = false;
|
||||
|
||||
connector->hostname = socks_host;
|
||||
connector->service = socks_port;
|
||||
connector->username = str_map_find (&ctx->config, "socks_username");
|
||||
connector->password = str_map_find (&ctx->config, "socks_password");
|
||||
|
||||
connector->on_connected = irc_on_socks_connected;
|
||||
connector->on_connecting = irc_on_socks_connecting;
|
||||
connector->on_error = irc_on_socks_error;
|
||||
connector->on_failure = irc_on_socks_failure;
|
||||
connector->user_data = &data;
|
||||
|
||||
if (socks_connector_add_target (connector, host, service, e))
|
||||
{
|
||||
socks_connector_run (connector);
|
||||
while (data.polling)
|
||||
poller_run (poller);
|
||||
}
|
||||
|
||||
socks_connector_free (connector);
|
||||
poller_free (poller);
|
||||
return data.succeeded;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
static bool
|
||||
irc_connect (struct bot_context *ctx, struct error **e)
|
||||
{
|
||||
const char *irc_host = str_map_find (&ctx->config, "irc_host");
|
||||
const char *irc_port = str_map_find (&ctx->config, "irc_port");
|
||||
|
||||
const char *socks_host = str_map_find (&ctx->config, "socks_host");
|
||||
const char *socks_port = str_map_find (&ctx->config, "socks_port");
|
||||
const char *socks_username = str_map_find (&ctx->config, "socks_username");
|
||||
const char *socks_password = str_map_find (&ctx->config, "socks_password");
|
||||
|
||||
const char *nickname = str_map_find (&ctx->config, "nickname");
|
||||
const char *username = str_map_find (&ctx->config, "username");
|
||||
@@ -1678,26 +1761,11 @@ irc_connect (struct bot_context *ctx, struct error **e)
|
||||
if (!irc_get_boolean_from_config (ctx, "ssl", &use_ssl, e))
|
||||
return false;
|
||||
|
||||
if (socks_host)
|
||||
{
|
||||
char *address = format_host_port_pair (irc_host, irc_port);
|
||||
char *socks_address = format_host_port_pair (socks_host, socks_port);
|
||||
print_status ("connecting to %s via %s...", address, socks_address);
|
||||
free (socks_address);
|
||||
free (address);
|
||||
|
||||
struct error *error = NULL;
|
||||
int fd = socks_connect (socks_host, socks_port, irc_host, irc_port,
|
||||
socks_username, socks_password, &error);
|
||||
if (fd == -1)
|
||||
{
|
||||
error_set (e, "%s: %s", "SOCKS connection failed", error->message);
|
||||
error_free (error);
|
||||
return false;
|
||||
}
|
||||
ctx->irc_fd = fd;
|
||||
}
|
||||
else if (!irc_establish_connection (ctx, irc_host, irc_port, e))
|
||||
bool connected = socks_host
|
||||
? irc_establish_connection_socks (ctx,
|
||||
socks_host, socks_port, irc_host, irc_port, e)
|
||||
: irc_establish_connection (ctx, irc_host, irc_port, e);
|
||||
if (!connected)
|
||||
return false;
|
||||
|
||||
if (use_ssl && !irc_initialize_ssl (ctx, e))
|
||||
|
||||
Reference in New Issue
Block a user