Rewrite socks to async

Not quite working yet, however it's a massive and important change.
This commit is contained in:
2015-07-20 23:31:26 +02:00
parent b750590f18
commit 318b7400d1
3 changed files with 769 additions and 362 deletions

114
zyklonb.c
View File

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