/*
 * Copyright (C) 2011-2013 Tobias Brunner
 * Copyright (C) 2008 Martin Willi
 * HSR Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include "stroke_socket.h"

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>

#include <daemon.h>

#include "stroke_config.h"
#include "stroke_control.h"
#include "stroke_cred.h"
#include "stroke_ca.h"
#include "stroke_attribute.h"
#include "stroke_handler.h"
#include "stroke_list.h"
#include "stroke_counter.h"

/**
 * To avoid clogging the thread pool with (blocking) jobs, we limit the number
 * of concurrently handled stroke commands.
 */
#define MAX_CONCURRENT_DEFAULT 4

typedef struct stroke_job_context_t stroke_job_context_t;
typedef struct private_stroke_socket_t private_stroke_socket_t;

/**
 * private data of stroke_socket
 */
struct private_stroke_socket_t {

	/**
	 * public functions
	 */
	stroke_socket_t public;

	/**
	 * Service accepting stroke connections
	 */
	stream_service_t *service;

	/**
	 * configuration backend
	 */
	stroke_config_t *config;

	/**
	 * attribute provider
	 */
	stroke_attribute_t *attribute;

	/**
	 * attribute handler (requests only)
	 */
	stroke_handler_t *handler;

	/**
	 * controller to control daemon
	 */
	stroke_control_t *control;

	/**
	 * credential set
	 */
	stroke_cred_t *cred;

	/**
	 * CA sections
	 */
	stroke_ca_t *ca;

	/**
	 * status information logging
	 */
	stroke_list_t *list;

	/**
	 * Counter values for IKE events
	 */
	stroke_counter_t *counter;

	/**
	 * TRUE if log level changes are not allowed
	 */
	bool prevent_loglevel_changes;
};

/**
 * Helper macro to log configuration options, but only if they are defined.
 */
#define DBG_OPT(...) VA_ARGS_DISPATCH(DBG_OPT, __VA_ARGS__)(__VA_ARGS__)
#define DBG_OPT2(fmt, val) ({ \
	typeof(val) _val = val; \
	if (_val) { DBG2(DBG_CFG, fmt, _val); } \
})
#define DBG_OPT3(fmt, label, val) ({ \
	typeof(val) _val = val; \
	if (_val) { DBG2(DBG_CFG, fmt, label, _val); } \
})

/**
 * Helper function which corrects the string pointers
 * in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
 * contains RELATIVE addresses (relative to the beginning of the
 * stroke_msg). They must be corrected if they reach our address
 * space...
 */
static void pop_string(stroke_msg_t *msg, char **string)
{
	if (*string == NULL)
	{
		return;
	}

	/* check for sanity of string pointer and string */
	if (string < (char**)msg ||
		string > (char**)((char*)msg + sizeof(stroke_msg_t)) ||
		(unsigned long)*string < (unsigned long)((char*)msg->buffer - (char*)msg) ||
		(unsigned long)*string > msg->length)
	{
		*string = "(invalid pointer in stroke msg)";
	}
	else
	{
		*string = (char*)msg + (unsigned long)*string;
	}
}

/**
 * Pop the strings of a stroke_end_t struct and log them for debugging purposes
 */
static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
{
	pop_string(msg, &end->address);
	pop_string(msg, &end->subnets);
	pop_string(msg, &end->sourceip);
	pop_string(msg, &end->dns);
	pop_string(msg, &end->auth);
	pop_string(msg, &end->auth2);
	pop_string(msg, &end->id);
	pop_string(msg, &end->id2);
	pop_string(msg, &end->rsakey);
	pop_string(msg, &end->cert);
	pop_string(msg, &end->cert2);
	pop_string(msg, &end->ca);
	pop_string(msg, &end->ca2);
	pop_string(msg, &end->groups);
	pop_string(msg, &end->groups2);
	pop_string(msg, &end->cert_policy);
	pop_string(msg, &end->updown);

	DBG_OPT("  %s=%s", label, end->address);
	DBG_OPT("  %ssubnet=%s", label, end->subnets);
	DBG_OPT("  %ssourceip=%s", label, end->sourceip);
	DBG_OPT("  %sdns=%s", label, end->dns);
	DBG_OPT("  %sauth=%s", label, end->auth);
	DBG_OPT("  %sauth2=%s", label, end->auth2);
	DBG_OPT("  %sid=%s", label, end->id);
	DBG_OPT("  %sid2=%s", label, end->id2);
	DBG_OPT("  %srsakey=%s", label, end->rsakey);
	DBG_OPT("  %scert=%s", label, end->cert);
	DBG_OPT("  %scert2=%s", label, end->cert2);
	DBG_OPT("  %sca=%s", label, end->ca);
	DBG_OPT("  %sca2=%s", label, end->ca2);
	DBG_OPT("  %sgroups=%s", label, end->groups);
	DBG_OPT("  %sgroups2=%s", label, end->groups2);
	DBG_OPT("  %supdown=%s", label, end->updown);
}

/**
 * Add a connection to the configuration list
 */
static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
{
	pop_string(msg, &msg->add_conn.name);
	DBG1(DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);

	DBG2(DBG_CFG, "conn %s", msg->add_conn.name);
	pop_end(msg, "left", &msg->add_conn.me);
	pop_end(msg, "right", &msg->add_conn.other);
	pop_string(msg, &msg->add_conn.eap_identity);
	pop_string(msg, &msg->add_conn.aaa_identity);
	pop_string(msg, &msg->add_conn.xauth_identity);
	pop_string(msg, &msg->add_conn.algorithms.ike);
	pop_string(msg, &msg->add_conn.algorithms.esp);
	pop_string(msg, &msg->add_conn.algorithms.ah);
	pop_string(msg, &msg->add_conn.ikeme.mediated_by);
	pop_string(msg, &msg->add_conn.ikeme.peerid);
	DBG_OPT("  eap_identity=%s", msg->add_conn.eap_identity);
	DBG_OPT("  aaa_identity=%s", msg->add_conn.aaa_identity);
	DBG_OPT("  xauth_identity=%s", msg->add_conn.xauth_identity);
	DBG_OPT("  ike=%s", msg->add_conn.algorithms.ike);
	DBG_OPT("  esp=%s", msg->add_conn.algorithms.esp);
	DBG_OPT("  ah=%s", msg->add_conn.algorithms.ah);
	DBG_OPT("  dpddelay=%d", msg->add_conn.dpd.delay);
	DBG_OPT("  dpdtimeout=%d", msg->add_conn.dpd.timeout);
	DBG_OPT("  dpdaction=%d", msg->add_conn.dpd.action);
	DBG_OPT("  closeaction=%d", msg->add_conn.close_action);
	DBG_OPT("  sha256_96=%s", msg->add_conn.sha256_96 ? "yes" : "no");
	DBG_OPT("  mediation=%s", msg->add_conn.ikeme.mediation ? "yes" : "no");
	DBG_OPT("  mediated_by=%s", msg->add_conn.ikeme.mediated_by);
	DBG_OPT("  me_peerid=%s", msg->add_conn.ikeme.peerid);
	DBG_OPT("  keyexchange=ikev%u", msg->add_conn.version);

	this->config->add(this->config, msg);
	this->attribute->add_dns(this->attribute, msg);
	this->handler->add_attributes(this->handler, msg);
}

/**
 * Delete a connection from the list
 */
static void stroke_del_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
{
	pop_string(msg, &msg->del_conn.name);
	DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name);

	this->config->del(this->config, msg);
	this->attribute->del_dns(this->attribute, msg);
	this->handler->del_attributes(this->handler, msg);
}

/**
 * initiate a connection by name
 */
static void stroke_initiate(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->initiate.name);
	DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);

	this->control->initiate(this->control, msg, out);
}

/**
 * terminate a connection by name
 */
static void stroke_terminate(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->terminate.name);
	DBG1(DBG_CFG, "received stroke: terminate '%s'", msg->terminate.name);

	this->control->terminate(this->control, msg, out);
}

/**
 * terminate a connection by peers virtual IP
 */
static void stroke_terminate_srcip(private_stroke_socket_t *this,
								   stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->terminate_srcip.start);
	pop_string(msg, &msg->terminate_srcip.end);
	DBG1(DBG_CFG, "received stroke: terminate-srcip %s-%s",
		 msg->terminate_srcip.start, msg->terminate_srcip.end);

	this->control->terminate_srcip(this->control, msg, out);
}

/**
 * rekey a connection by name/id
 */
static void stroke_rekey(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->terminate.name);
	DBG1(DBG_CFG, "received stroke: rekey '%s'", msg->rekey.name);

	this->control->rekey(this->control, msg, out);
}

/**
 * route a policy (install SPD entries)
 */
static void stroke_route(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->route.name);
	DBG1(DBG_CFG, "received stroke: route '%s'", msg->route.name);

	this->control->route(this->control, msg, out);
}

/**
 * unroute a policy
 */
static void stroke_unroute(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->terminate.name);
	DBG1(DBG_CFG, "received stroke: unroute '%s'", msg->route.name);

	this->control->unroute(this->control, msg, out);
}

/**
 * Add a ca information record to the cainfo list
 */
static void stroke_add_ca(private_stroke_socket_t *this,
						  stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->add_ca.name);
	DBG1(DBG_CFG, "received stroke: add ca '%s'", msg->add_ca.name);

	pop_string(msg, &msg->add_ca.cacert);
	pop_string(msg, &msg->add_ca.crluri);
	pop_string(msg, &msg->add_ca.crluri2);
	pop_string(msg, &msg->add_ca.ocspuri);
	pop_string(msg, &msg->add_ca.ocspuri2);
	pop_string(msg, &msg->add_ca.certuribase);
	DBG2(DBG_CFG, "ca %s", msg->add_ca.name);
	DBG_OPT("  cacert=%s", msg->add_ca.cacert);
	DBG_OPT("  crluri=%s", msg->add_ca.crluri);
	DBG_OPT("  crluri2=%s", msg->add_ca.crluri2);
	DBG_OPT("  ocspuri=%s", msg->add_ca.ocspuri);
	DBG_OPT("  ocspuri2=%s", msg->add_ca.ocspuri2);
	DBG_OPT("  certuribase=%s", msg->add_ca.certuribase);

	this->ca->add(this->ca, msg);
}

/**
 * Delete a ca information record from the cainfo list
 */
static void stroke_del_ca(private_stroke_socket_t *this,
						  stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->del_ca.name);
	DBG1(DBG_CFG, "received stroke: delete ca '%s'", msg->del_ca.name);

	this->ca->del(this->ca, msg);
}


/**
 * show status of daemon
 */
static void stroke_status(private_stroke_socket_t *this,
						  stroke_msg_t *msg, FILE *out, bool all, bool wait)
{
	pop_string(msg, &(msg->status.name));

	this->list->status(this->list, msg, out, all, wait);
}

/**
 * list various information
 */
static void stroke_list(private_stroke_socket_t *this, stroke_msg_t *msg,
						FILE *out)
{
	if (msg->list.flags & LIST_CAINFOS)
	{
		this->ca->list(this->ca, msg, out);
	}
	this->list->list(this->list, msg, out);
}

/**
 * reread various information
 */
static void stroke_reread(private_stroke_socket_t *this,
						  stroke_msg_t *msg, FILE *out)
{
	this->cred->reread(this->cred, msg, out);
}

/**
 * purge various information
 */
static void stroke_purge(private_stroke_socket_t *this,
						 stroke_msg_t *msg, FILE *out)
{
	if (msg->purge.flags & PURGE_OCSP)
	{
		lib->credmgr->flush_cache(lib->credmgr, CERT_X509_OCSP_RESPONSE);
	}
	if (msg->purge.flags & PURGE_CRLS)
	{
		lib->credmgr->flush_cache(lib->credmgr, CERT_X509_CRL);
	}
	if (msg->purge.flags & PURGE_CERTS)
	{
		lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
	}
	if (msg->purge.flags & PURGE_IKE)
	{
		this->control->purge_ike(this->control, msg, out);
	}
}

/**
 * Print a certificate in PEM to out
 */
static void print_pem_cert(FILE *out, certificate_t *cert)
{
	chunk_t encoded;

	if (cert->get_encoding(cert, CERT_PEM, &encoded))
	{
		fprintf(out, "%.*s", (int)encoded.len, encoded.ptr);
		free(encoded.ptr);
	}
}

/**
 * Export in-memory credentials
 */
static void stroke_export(private_stroke_socket_t *this,
						  stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->export.selector);

	if (msg->export.flags & EXPORT_X509)
	{
		enumerator_t *enumerator;
		identification_t *id;
		certificate_t *cert;

		id = identification_create_from_string(msg->export.selector);
		enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
												CERT_X509, KEY_ANY, id, FALSE);
		while (enumerator->enumerate(enumerator, &cert))
		{
			print_pem_cert(out, cert);
		}
		enumerator->destroy(enumerator);
		id->destroy(id);
	}

	if (msg->export.flags & (EXPORT_CONN_CERT | EXPORT_CONN_CHAIN))
	{
		enumerator_t *sas, *auths, *certs;
		ike_sa_t *ike_sa;
		auth_cfg_t *auth;
		certificate_t *cert;
		auth_rule_t rule;

		sas = charon->ike_sa_manager->create_enumerator(
												charon->ike_sa_manager, TRUE);
		while (sas->enumerate(sas, &ike_sa))
		{
			if (streq(msg->export.selector, ike_sa->get_name(ike_sa)))
			{
				auths = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
				while (auths->enumerate(auths, &auth))
				{
					bool got_subject = FALSE;

					certs = auth->create_enumerator(auth);
					while (certs->enumerate(certs, &rule, &cert))
					{
						switch (rule)
						{
							case AUTH_RULE_CA_CERT:
							case AUTH_RULE_IM_CERT:
								if (msg->export.flags & EXPORT_CONN_CHAIN)
								{
									print_pem_cert(out, cert);
								}
								break;
							case AUTH_RULE_SUBJECT_CERT:
								if (!got_subject)
								{
									print_pem_cert(out, cert);
									got_subject = TRUE;
								}
								break;
							default:
								break;
						}
					}
					certs->destroy(certs);
				}
				auths->destroy(auths);
			}
		}
		sas->destroy(sas);
	}
}

/**
 * list pool leases
 */
static void stroke_leases(private_stroke_socket_t *this,
						  stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->leases.pool);
	pop_string(msg, &msg->leases.address);

	this->list->leases(this->list, msg, out);
}

/**
 * Callback function for usage report
 */
static void report_usage(FILE *out, int count, size_t bytes,
						 backtrace_t *bt, bool detailed)
{
	fprintf(out, "%zu bytes total, %d allocations, %zu bytes average:\n",
			bytes, count, bytes / count);
	bt->log(bt, out, detailed);
}

/**
 * Callback function for memusage summary
 */
static void sum_usage(FILE *out, int count, size_t bytes, int whitelisted)
{
	fprintf(out, "Total memory usage: %zu\n", bytes);
}

/**
 * Show memory usage
 */
static void stroke_memusage(private_stroke_socket_t *this,
							stroke_msg_t *msg, FILE *out)
{
	if (lib->leak_detective)
	{
		lib->leak_detective->usage(lib->leak_detective,
								   (leak_detective_report_cb_t)report_usage,
								   (leak_detective_summary_cb_t)sum_usage, out);
	}
}

/**
 * Set username and password for a connection
 */
static void stroke_user_creds(private_stroke_socket_t *this,
							  stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->user_creds.name);
	pop_string(msg, &msg->user_creds.username);
	pop_string(msg, &msg->user_creds.password);

	DBG1(DBG_CFG, "received stroke: user-creds '%s'", msg->user_creds.name);

	this->config->set_user_credentials(this->config, msg, out);
}

/**
 * Print stroke counter values
 */
static void stroke_counters(private_stroke_socket_t *this,
							  stroke_msg_t *msg, FILE *out)
{
	pop_string(msg, &msg->counters.name);

	if (msg->counters.reset)
	{
		this->counter->reset(this->counter, msg->counters.name);
	}
	else
	{
		this->counter->print(this->counter, out, msg->counters.name);
	}
}

/**
 * set the verbosity debug output
 */
static void stroke_loglevel(private_stroke_socket_t *this,
							stroke_msg_t *msg, FILE *out)
{
	debug_t group;

	pop_string(msg, &(msg->loglevel.type));
	DBG1(DBG_CFG, "received stroke: loglevel %d for %s",
		 msg->loglevel.level, msg->loglevel.type);

	if (this->prevent_loglevel_changes)
	{
		DBG1(DBG_CFG, "prevented log level change");
		fprintf(out, "command not allowed!\n");
		return;
	}
	if (!enum_from_name(debug_names, msg->loglevel.type, &group))
	{
		fprintf(out, "unknown type '%s'!\n", msg->loglevel.type);
		return;
	}
	charon->set_level(charon, group, msg->loglevel.level);
}

/**
 * set various config options
 */
static void stroke_config(private_stroke_socket_t *this,
						  stroke_msg_t *msg, FILE *out)
{
	this->cred->cachecrl(this->cred, msg->config.cachecrl);
}

/**
 * process a stroke request
 */
static bool on_accept(private_stroke_socket_t *this, stream_t *stream)
{
	stroke_msg_t *msg;
	uint16_t len;
	FILE *out;

	/* read length */
	if (!stream->read_all(stream, &len, sizeof(len)))
	{
		if (errno != EWOULDBLOCK)
		{
			DBG1(DBG_CFG, "reading length of stroke message failed: %s",
				 strerror(errno));
		}
		return FALSE;
	}
	if (len < offsetof(stroke_msg_t, buffer))
	{
		DBG1(DBG_CFG, "invalid stroke message length %d", len);
		return FALSE;
	}

	/* read message (we need an additional byte to terminate the buffer) */
	msg = malloc(len + 1);
	msg->length = len;
	if (!stream->read_all(stream, (char*)msg + sizeof(len), len - sizeof(len)))
	{
		if (errno != EWOULDBLOCK)
		{
			DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
		}
		free(msg);
		return FALSE;
	}
	/* make sure even incorrectly unterminated strings don't extend over the
	 * message boundaries */
	((char*)msg)[len] = '\0';

	DBG3(DBG_CFG, "stroke message %b", (void*)msg, len);

	out = stream->get_file(stream);
	if (!out)
	{
		DBG1(DBG_CFG, "creating stroke output stream failed");
		free(msg);
		return FALSE;
	}
	switch (msg->type)
	{
		case STR_INITIATE:
			stroke_initiate(this, msg, out);
			break;
		case STR_ROUTE:
			stroke_route(this, msg, out);
			break;
		case STR_UNROUTE:
			stroke_unroute(this, msg, out);
			break;
		case STR_TERMINATE:
			stroke_terminate(this, msg, out);
			break;
		case STR_TERMINATE_SRCIP:
			stroke_terminate_srcip(this, msg, out);
			break;
		case STR_REKEY:
			stroke_rekey(this, msg, out);
			break;
		case STR_STATUS:
			stroke_status(this, msg, out, FALSE, TRUE);
			break;
		case STR_STATUS_ALL:
			stroke_status(this, msg, out, TRUE, TRUE);
			break;
		case STR_STATUS_ALL_NOBLK:
			stroke_status(this, msg, out, TRUE, FALSE);
			break;
		case STR_ADD_CONN:
			stroke_add_conn(this, msg);
			break;
		case STR_DEL_CONN:
			stroke_del_conn(this, msg);
			break;
		case STR_ADD_CA:
			stroke_add_ca(this, msg, out);
			break;
		case STR_DEL_CA:
			stroke_del_ca(this, msg, out);
			break;
		case STR_LOGLEVEL:
			stroke_loglevel(this, msg, out);
			break;
		case STR_CONFIG:
			stroke_config(this, msg, out);
			break;
		case STR_LIST:
			stroke_list(this, msg, out);
			break;
		case STR_REREAD:
			stroke_reread(this, msg, out);
			break;
		case STR_PURGE:
			stroke_purge(this, msg, out);
			break;
		case STR_EXPORT:
			stroke_export(this, msg, out);
			break;
		case STR_LEASES:
			stroke_leases(this, msg, out);
			break;
		case STR_MEMUSAGE:
			stroke_memusage(this, msg, out);
			break;
		case STR_USER_CREDS:
			stroke_user_creds(this, msg, out);
			break;
		case STR_COUNTERS:
			stroke_counters(this, msg, out);
			break;
		default:
			DBG1(DBG_CFG, "received unknown stroke");
			break;
	}
	free(msg);
	fclose(out);
	return FALSE;
}

METHOD(stroke_socket_t, destroy, void,
	private_stroke_socket_t *this)
{
	DESTROY_IF(this->service);
	lib->credmgr->remove_set(lib->credmgr, &this->ca->set);
	lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
	charon->backends->remove_backend(charon->backends, &this->config->backend);
	charon->attributes->remove_provider(charon->attributes,
										&this->attribute->provider);
	charon->attributes->remove_handler(charon->attributes,
									   &this->handler->handler);
	this->cred->destroy(this->cred);
	this->ca->destroy(this->ca);
	this->config->destroy(this->config);
	this->attribute->destroy(this->attribute);
	this->handler->destroy(this->handler);
	this->control->destroy(this->control);
	this->list->destroy(this->list);
	this->counter->destroy(this->counter);
	free(this);
}

/*
 * see header file
 */
stroke_socket_t *stroke_socket_create()
{
	private_stroke_socket_t *this;
	int max_concurrent;
	char *uri;

	INIT(this,
		.public = {
			.destroy = _destroy,
		},
		.prevent_loglevel_changes = lib->settings->get_bool(lib->settings,
				"%s.plugins.stroke.prevent_loglevel_changes", FALSE, lib->ns),
	);

	this->ca = stroke_ca_create();
	this->cred = stroke_cred_create(this->ca);
	this->attribute = stroke_attribute_create();
	this->handler = stroke_handler_create();
	this->config = stroke_config_create(this->ca, this->cred, this->attribute);
	this->control = stroke_control_create();
	this->list = stroke_list_create(this->attribute);
	this->counter = stroke_counter_create();

	lib->credmgr->add_set(lib->credmgr, &this->ca->set);
	lib->credmgr->add_set(lib->credmgr, &this->cred->set);
	charon->backends->add_backend(charon->backends, &this->config->backend);
	charon->attributes->add_provider(charon->attributes,
									 &this->attribute->provider);
	charon->attributes->add_handler(charon->attributes,
									&this->handler->handler);


	max_concurrent = lib->settings->get_int(lib->settings,
				"%s.plugins.stroke.max_concurrent", MAX_CONCURRENT_DEFAULT,
				lib->ns);
	uri = lib->settings->get_str(lib->settings,
				"%s.plugins.stroke.socket", "unix://" STROKE_SOCKET, lib->ns);
	this->service = lib->streams->create_service(lib->streams, uri, 10);
	if (!this->service)
	{
		DBG1(DBG_CFG, "creating stroke socket failed");
		destroy(this);
		return NULL;
	}
	this->service->on_accept(this->service, (stream_service_cb_t)on_accept,
							 this, JOB_PRIO_CRITICAL, max_concurrent);

	return &this->public;
}
