diff options
Diffstat (limited to 'src/libstrongswan')
-rw-r--r-- | src/libstrongswan/Android.mk | 1 | ||||
-rw-r--r-- | src/libstrongswan/Makefile.am | 2 | ||||
-rw-r--r-- | src/libstrongswan/networking/streams/stream_service.c | 157 | ||||
-rw-r--r-- | src/libstrongswan/networking/streams/stream_service.h | 78 |
4 files changed, 238 insertions, 0 deletions
diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index e95a6d479..790105f41 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -27,6 +27,7 @@ database/database_factory.c fetcher/fetcher.c fetcher/fetcher_manager.c eap/eap. ipsec/ipsec_types.c \ networking/host.c networking/host_resolver.c networking/packet.c \ networking/tun_device.c networking/streams/stream.c \ +networking/streams/stream_service.c \ pen/pen.c plugins/plugin_loader.c plugins/plugin_feature.c processing/jobs/job.c \ processing/jobs/callback_job.c processing/processor.c processing/scheduler.c \ processing/watcher.c resolver/resolver_manager.c resolver/rr_set.c \ diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 9f3c3ed2c..1edd3ffa4 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -25,6 +25,7 @@ database/database_factory.c fetcher/fetcher.c fetcher/fetcher_manager.c eap/eap. ipsec/ipsec_types.c \ networking/host.c networking/host_resolver.c networking/packet.c \ networking/tun_device.c networking/streams/stream.c \ +networking/streams/stream_service.c \ pen/pen.c plugins/plugin_loader.c plugins/plugin_feature.c processing/jobs/job.c \ processing/jobs/callback_job.c processing/processor.c processing/scheduler.c \ processing/watcher.c resolver/resolver_manager.c resolver/rr_set.c \ @@ -66,6 +67,7 @@ database/database.h database/database_factory.h fetcher/fetcher.h \ fetcher/fetcher_manager.h eap/eap.h pen/pen.h ipsec/ipsec_types.h \ networking/host.h networking/host_resolver.h networking/packet.h \ networking/tun_device.h networking/streams/stream.h \ +networking/streams/stream_service.h \ resolver/resolver.h resolver/resolver_response.h resolver/rr_set.h \ resolver/rr.h resolver/resolver_manager.h \ plugins/plugin_loader.h plugins/plugin.h plugins/plugin_feature.h \ diff --git a/src/libstrongswan/networking/streams/stream_service.c b/src/libstrongswan/networking/streams/stream_service.c new file mode 100644 index 000000000..4979ed60f --- /dev/null +++ b/src/libstrongswan/networking/streams/stream_service.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2013 Martin Willi + * Copyright (C) 2013 revosec AG + * + * 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 "stream_service.h" + +#include <threading/thread.h> +#include <processing/jobs/callback_job.h> + +#include <unistd.h> + +typedef struct private_stream_service_t private_stream_service_t; + +/** + * Private data of an stream_service_t object. + */ +struct private_stream_service_t { + + /** + * Public stream_service_t interface. + */ + stream_service_t public; + + /** + * Underlying socket + */ + int fd; + + /** + * Accept callback + */ + stream_service_cb_t cb; + + /** + * Accept callback data + */ + void *data; +}; + +/** + * Data to pass to async accept job + */ +typedef struct { + /** callback function */ + stream_service_cb_t cb; + /** callback data */ + void *data; + /** accepted connection */ + int fd; +} async_data_t; + +/** + * Clean up accept data + */ +static void destroy_async_data(async_data_t *data) +{ + close(data->fd); + free(data); +} + +/** + * Async processing of accepted connection + */ +static job_requeue_t accept_async(async_data_t *data) +{ + stream_t *stream; + + stream = stream_create_from_fd(data->fd); + if (stream) + { + thread_cleanup_push((void*)stream->destroy, stream); + data->cb(data->data, stream); + thread_cleanup_pop(TRUE); + } + return JOB_REQUEUE_NONE; +} + +/** + * Watcher callback function + */ +static bool watch(private_stream_service_t *this, int fd, watcher_event_t event) +{ + async_data_t *data; + + INIT(data, + .cb = this->cb, + .data = this->data, + .fd = accept(fd, NULL, NULL), + ); + + if (data->fd != -1) + { + lib->processor->queue_job(lib->processor, + (job_t*)callback_job_create_with_prio((void*)accept_async, data, + (void*)destroy_async_data, NULL, JOB_PRIO_HIGH)); + } + else + { + free(data); + } + return TRUE; +} + +METHOD(stream_service_t, on_accept, void, + private_stream_service_t *this, stream_service_cb_t cb, void *data) +{ + if (this->cb) + { + lib->watcher->remove(lib->watcher, this->fd); + } + + this->cb = cb; + this->data = data; + + if (this->cb) + { + lib->watcher->add(lib->watcher, this->fd, + WATCHER_READ, (watcher_cb_t)watch, this); + } +} + +METHOD(stream_service_t, destroy, void, + private_stream_service_t *this) +{ + on_accept(this, NULL, NULL); + close(this->fd); + free(this); +} + +/** + * See header + */ +stream_service_t *stream_service_create_from_fd(int fd) +{ + private_stream_service_t *this; + + INIT(this, + .public = { + .on_accept = _on_accept, + .destroy = _destroy, + }, + .fd = fd, + ); + + return &this->public; +} diff --git a/src/libstrongswan/networking/streams/stream_service.h b/src/libstrongswan/networking/streams/stream_service.h new file mode 100644 index 000000000..f5da92ee7 --- /dev/null +++ b/src/libstrongswan/networking/streams/stream_service.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2013 Martin Willi + * Copyright (C) 2013 revosec AG + * + * 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. + */ + +/** + * @defgroup stream_service stream_service + * @{ @ingroup streams + */ + +#ifndef STREAM_SERVICE_H_ +#define STREAM_SERVICE_H_ + +typedef struct stream_service_t stream_service_t; + +#include <networking/streams/stream.h> + +/** + * Constructor function prototype for stream_servicet. + * + * @param uri URI to create a stream for + * @return stream instance, NULL on error + */ +typedef stream_service_t*(*stream_service_constructor_t)(char *uri); + +/** + * Service callback routine for accepting client connections. + * + * The passed stream_service gets closed/destroyed by the callback caller. + * + * @param data user data, as passed during registration + * @param stream accept()ed client connection + */ +typedef void (*stream_service_cb_t)(void *data, stream_t *stream); + +/** + * A service accepting client connection streams. + */ +struct stream_service_t { + + /** + * Start accepting client connections on this stream service. + * + * To stop accepting connections, pass a NULL callback function. + * + * @param cb callback function to call for accepted client streams + * @param data data to pass to callback function + */ + void (*on_accept)(stream_service_t *this, + stream_service_cb_t cb, void *data); + + /** + * Destroy a stream_service_t. + */ + void (*destroy)(stream_service_t *this); +}; + +/** + * Create a service from a file descriptor. + * + * The file descriptor MUST be a socket. + * + * @param fd file descriptor to wrap into a stream_service_t + * @return stream_service instance + */ +stream_service_t *stream_service_create_from_fd(int fd); + +#endif /** STREAM_SERVICE_H_ @}*/ |