Bump liberty

This commit is contained in:
Přemysl Eric Janouch 2015-08-17 00:04:57 +02:00
parent 4ae95be9db
commit abd892cbd7
4 changed files with 9 additions and 249 deletions

240
common.c
View File

@ -41,12 +41,6 @@
return false; \
BLOCK_END
// A few other debugging shorthands
#define LOG_FUNC_FAILURE(name, desc) \
print_debug ("%s: %s: %s", __func__, (name), (desc))
#define LOG_LIBC_FAILURE(name) \
print_debug ("%s: %s: %s", __func__, (name), strerror (errno))
// --- To be moved to liberty --------------------------------------------------
static void
@ -90,240 +84,6 @@ log_message_syslog (void *user_data, const char *quote, const char *fmt,
syslog (prio, "%s%s", quote, buf);
}
// --- Connector ---------------------------------------------------------------
// This is a helper that tries to establish a connection with any address on
// a given list. Sadly it also introduces a bit of a callback hell.
struct connector_target
{
LIST_HEADER (struct connector_target)
char *hostname; ///< Target hostname or address
char *service; ///< Target service name or port
struct addrinfo *results; ///< Resolved target
struct addrinfo *iter; ///< Current endpoint
};
static struct connector_target *
connector_target_new (void)
{
struct connector_target *self = xmalloc (sizeof *self);
return self;
}
static void
connector_target_destroy (struct connector_target *self)
{
free (self->hostname);
free (self->service);
freeaddrinfo (self->results);
free (self);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct connector
{
int socket; ///< Socket FD for the connection
struct poller_fd connected_event; ///< We've connected or failed
struct connector_target *targets; ///< Targets
struct connector_target *targets_t; ///< Tail of targets
void *user_data; ///< User data for callbacks
// You may destroy the connector object in these two main callbacks:
/// Connection has been successfully established
void (*on_connected) (void *user_data, int socket);
/// Failed to establish a connection to either target
void (*on_failure) (void *user_data);
// Optional:
/// Connecting to a new address
void (*on_connecting) (void *user_data, const char *address);
/// Connecting to the last address has failed
void (*on_error) (void *user_data, const char *error);
};
static void
connector_notify_connecting (struct connector *self,
struct connector_target *target, struct addrinfo *gai_iter)
{
if (!self->on_connecting)
return;
const char *real_host = target->hostname;
// We don't really need this, so we can let it quietly fail
char buf[NI_MAXHOST];
int err = getnameinfo (gai_iter->ai_addr, gai_iter->ai_addrlen,
buf, sizeof buf, NULL, 0, NI_NUMERICHOST);
if (err)
LOG_FUNC_FAILURE ("getnameinfo", gai_strerror (err));
else
real_host = buf;
char *address = format_host_port_pair (real_host, target->service);
self->on_connecting (self->user_data, address);
free (address);
}
static void
connector_notify_error (struct connector *self, const char *error)
{
if (self->on_error)
self->on_error (self->user_data, error);
}
static void
connector_prepare_next (struct connector *self)
{
struct connector_target *target = self->targets;
if (!(target->iter = target->iter->ai_next))
{
LIST_UNLINK_WITH_TAIL (self->targets, self->targets_t, target);
connector_target_destroy (target);
}
}
static void
connector_step (struct connector *self)
{
struct connector_target *target = self->targets;
if (!target)
{
// Total failure, none of the targets has succeeded
self->on_failure (self->user_data);
return;
}
struct addrinfo *gai_iter = target->iter;
hard_assert (gai_iter != NULL);
connector_notify_connecting (self, target, gai_iter);
int fd = socket (gai_iter->ai_family,
gai_iter->ai_socktype, gai_iter->ai_protocol);
if (fd == -1)
{
connector_notify_error (self, strerror (errno));
connector_prepare_next (self);
connector_step (self);
return;
}
set_cloexec (fd);
set_blocking (fd, false);
int yes = 1;
soft_assert (setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE,
&yes, sizeof yes) != -1);
if (!connect (fd, gai_iter->ai_addr, gai_iter->ai_addrlen))
{
set_blocking (fd, true);
self->on_connected (self->user_data, fd);
return;
}
if (errno != EINPROGRESS)
{
connector_notify_error (self, strerror (errno));
xclose (fd);
connector_prepare_next (self);
connector_step (self);
return;
}
self->connected_event.fd = self->socket = fd;
poller_fd_set (&self->connected_event, POLLOUT);
connector_prepare_next (self);
}
static void
connector_on_ready (const struct pollfd *pfd, struct connector *self)
{
// See http://cr.yp.to/docs/connect.html if this doesn't work.
// The second connect() method doesn't work with DragonflyBSD.
int error = 0;
socklen_t error_len = sizeof error;
hard_assert (!getsockopt (pfd->fd,
SOL_SOCKET, SO_ERROR, &error, &error_len));
if (error)
{
connector_notify_error (self, strerror (error));
poller_fd_reset (&self->connected_event);
xclose (self->socket);
self->socket = -1;
connector_step (self);
}
else
{
poller_fd_reset (&self->connected_event);
self->socket = -1;
set_blocking (pfd->fd, true);
self->on_connected (self->user_data, pfd->fd);
}
}
static void
connector_init (struct connector *self, struct poller *poller)
{
memset (self, 0, sizeof *self);
self->socket = -1;
poller_fd_init (&self->connected_event, poller, self->socket);
self->connected_event.user_data = self;
self->connected_event.dispatcher = (poller_fd_fn) connector_on_ready;
}
static void
connector_free (struct connector *self)
{
poller_fd_reset (&self->connected_event);
if (self->socket != -1)
xclose (self->socket);
LIST_FOR_EACH (struct connector_target, iter, self->targets)
connector_target_destroy (iter);
}
static bool
connector_add_target (struct connector *self,
const char *hostname, const char *service, struct error **e)
{
struct addrinfo hints, *results;
memset (&hints, 0, sizeof hints);
hints.ai_socktype = SOCK_STREAM;
// TODO: even this should be done asynchronously, most likely in
// a thread pool, similarly to how libuv does it
int err = getaddrinfo (hostname, service, &hints, &results);
if (err)
{
error_set (e, "%s: %s", "getaddrinfo", gai_strerror (err));
return false;
}
struct connector_target *target = connector_target_new ();
target->hostname = xstrdup (hostname);
target->service = xstrdup (service);
target->results = results;
target->iter = target->results;
LIST_APPEND_WITH_TAIL (self->targets, self->targets_t, target);
return true;
}
// --- SOCKS 5/4a --------------------------------------------------------------
// Asynchronous SOCKS connector. Adds more stuff on top of the regular one.

8
kike.c
View File

@ -34,7 +34,7 @@ enum { PIPE_READ, PIPE_WRITE };
// Just get rid of the crappiest ciphers available by default
#define DEFAULT_CIPHERS "DEFAULT:!MEDIUM:!LOW"
static struct config_item g_config_table[] =
static struct simple_config_item g_config_table[] =
{
{ "pid_file", NULL, "Path or name of the PID file" },
{ "server_name", NULL, "Server name" },
@ -666,7 +666,7 @@ server_context_init (struct server_context *self)
str_map_init (&self->config);
self->config.free = free;
load_config_defaults (&self->config, g_config_table);
simple_config_load_defaults (&self->config, g_config_table);
str_vector_init (&self->motd);
self->catalog = (nl_catd) -1;
@ -3982,7 +3982,7 @@ main (int argc, char *argv[])
printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
exit (EXIT_SUCCESS);
case 'w':
call_write_default_config (optarg, g_config_table);
call_simple_config_write_default (optarg, g_config_table);
exit (EXIT_SUCCESS);
default:
print_error ("wrong options");
@ -4007,7 +4007,7 @@ main (int argc, char *argv[])
irc_register_cap_handlers (&ctx);
struct error *e = NULL;
if (!read_config_file (&ctx.config, &e))
if (!simple_config_update_from_file (&ctx.config, &e))
{
print_error ("error loading configuration: %s", e->message);
error_free (e);

@ -1 +1 @@
Subproject commit 1a305a1c6b1608219334d7512fc09081c9066c9e
Subproject commit 649c351560bf9fea9e7b889c117afa94a44150d6

View File

@ -24,7 +24,7 @@
// --- Configuration (application-specific) ------------------------------------
static struct config_item g_config_table[] =
static struct simple_config_item g_config_table[] =
{
{ "nickname", "ZyklonB", "IRC nickname" },
{ "username", "bot", "IRC user name" },
@ -153,7 +153,7 @@ bot_context_init (struct bot_context *self)
{
str_map_init (&self->config);
self->config.free = free;
load_config_defaults (&self->config, g_config_table);
simple_config_load_defaults (&self->config, g_config_table);
self->admin_re = NULL;
self->irc_fd = -1;
@ -1965,7 +1965,7 @@ main (int argc, char *argv[])
printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
exit (EXIT_SUCCESS);
case 'w':
call_write_default_config (optarg, g_config_table);
call_simple_config_write_default (optarg, g_config_table);
exit (EXIT_SUCCESS);
default:
print_error ("wrong options");
@ -1988,7 +1988,7 @@ main (int argc, char *argv[])
bot_context_init (&ctx);
struct error *e = NULL;
if (!read_config_file (&ctx.config, &e)
if (!simple_config_update_from_file (&ctx.config, &e)
|| !setup_recovery_handler (&ctx, &e))
{
print_error ("%s", e->message);