File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / networking / streams / stream_manager.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 3 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /*
    2:  * Copyright (C) 2013 Martin Willi
    3:  * Copyright (C) 2013 revosec AG
    4:  *
    5:  * This program is free software; you can redistribute it and/or modify it
    6:  * under the terms of the GNU General Public License as published by the
    7:  * Free Software Foundation; either version 2 of the License, or (at your
    8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
    9:  *
   10:  * This program is distributed in the hope that it will be useful, but
   11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13:  * for more details.
   14:  */
   15: 
   16: #include "stream_manager.h"
   17: 
   18: #include "stream_tcp.h"
   19: #include "stream_service_tcp.h"
   20: #ifndef WIN32
   21: # include "stream_unix.h"
   22: # include "stream_service_unix.h"
   23: #endif
   24: #ifdef USE_SYSTEMD
   25: # include "stream_service_systemd.h"
   26: #endif
   27: 
   28: #include <threading/rwlock.h>
   29: 
   30: typedef struct private_stream_manager_t private_stream_manager_t;
   31: 
   32: /**
   33:  * Private data of an stream_manager_t object.
   34:  */
   35: struct private_stream_manager_t {
   36: 
   37: 	/**
   38: 	 * Public stream_manager_t interface.
   39: 	 */
   40: 	stream_manager_t public;
   41: 
   42: 	/**
   43: 	 * List of registered stream constructors, as stream_entry_t
   44: 	 */
   45: 	linked_list_t *streams;
   46: 
   47: 	/**
   48: 	 * List of registered service constructors, as service_entry_t
   49: 	 */
   50: 	linked_list_t *services;
   51: 
   52: 	/**
   53: 	 * Lock for all lists
   54: 	 */
   55: 	rwlock_t *lock;
   56: };
   57: 
   58: /**
   59:  * Registered stream backend
   60:  */
   61: typedef struct {
   62: 	/** URI prefix */
   63: 	char *prefix;
   64: 	/** constructor function */
   65: 	stream_constructor_t create;
   66: } stream_entry_t;
   67: 
   68: /**
   69:  * Registered service backend
   70:  */
   71: typedef struct {
   72: 	/** URI prefix */
   73: 	char *prefix;
   74: 	/** constructor function */
   75: 	stream_service_constructor_t create;
   76: } service_entry_t;
   77: 
   78: METHOD(stream_manager_t, connect_, stream_t*,
   79: 	private_stream_manager_t *this, char *uri)
   80: {
   81: 	enumerator_t *enumerator;
   82: 	stream_entry_t *entry;
   83: 	stream_t *stream = NULL;
   84: 
   85: 	this->lock->read_lock(this->lock);
   86: 	enumerator = this->streams->create_enumerator(this->streams);
   87: 	while (enumerator->enumerate(enumerator, &entry))
   88: 	{
   89: 		if (strpfx(uri, entry->prefix))
   90: 		{
   91: 			stream = entry->create(uri);
   92: 			if (stream)
   93: 			{
   94: 				break;
   95: 			}
   96: 		}
   97: 	}
   98: 	enumerator->destroy(enumerator);
   99: 	this->lock->unlock(this->lock);
  100: 
  101: 	return stream;
  102: }
  103: 
  104: METHOD(stream_manager_t, create_service, stream_service_t*,
  105: 	private_stream_manager_t *this, char *uri, int backlog)
  106: {
  107: 	enumerator_t *enumerator;
  108: 	service_entry_t *entry;
  109: 	stream_service_t *service = NULL;
  110: 
  111: 	this->lock->read_lock(this->lock);
  112: 	enumerator = this->services->create_enumerator(this->services);
  113: 	while (enumerator->enumerate(enumerator, &entry))
  114: 	{
  115: 		if (strpfx(uri, entry->prefix))
  116: 		{
  117: 			service = entry->create(uri, backlog);
  118: 			if (service)
  119: 			{
  120: 				break;
  121: 			}
  122: 		}
  123: 	}
  124: 	enumerator->destroy(enumerator);
  125: 	this->lock->unlock(this->lock);
  126: 
  127: 	return service;
  128: }
  129: 
  130: METHOD(stream_manager_t, add_stream, void,
  131: 	private_stream_manager_t *this, char *prefix, stream_constructor_t create)
  132: {
  133: 	stream_entry_t *entry;
  134: 
  135: 	INIT(entry,
  136: 		.prefix = strdup(prefix),
  137: 		.create = create,
  138: 	);
  139: 
  140: 	this->lock->write_lock(this->lock);
  141: 	this->streams->insert_last(this->streams, entry);
  142: 	this->lock->unlock(this->lock);
  143: }
  144: 
  145: METHOD(stream_manager_t, remove_stream, void,
  146: 	private_stream_manager_t *this, stream_constructor_t create)
  147: {
  148: 	enumerator_t *enumerator;
  149: 	stream_entry_t *entry;
  150: 
  151: 	this->lock->write_lock(this->lock);
  152: 	enumerator = this->streams->create_enumerator(this->streams);
  153: 	while (enumerator->enumerate(enumerator, &entry))
  154: 	{
  155: 		if (entry->create == create)
  156: 		{
  157: 			this->streams->remove_at(this->streams, enumerator);
  158: 			free(entry->prefix);
  159: 			free(entry);
  160: 		}
  161: 	}
  162: 	enumerator->destroy(enumerator);
  163: 	this->lock->unlock(this->lock);
  164: }
  165: 
  166: METHOD(stream_manager_t, add_service, void,
  167: 	private_stream_manager_t *this, char *prefix,
  168: 	stream_service_constructor_t create)
  169: {
  170: 	service_entry_t *entry;
  171: 
  172: 	INIT(entry,
  173: 		.prefix = strdup(prefix),
  174: 		.create = create,
  175: 	);
  176: 
  177: 	this->lock->write_lock(this->lock);
  178: 	this->services->insert_last(this->services, entry);
  179: 	this->lock->unlock(this->lock);
  180: }
  181: 
  182: METHOD(stream_manager_t, remove_service, void,
  183: 	private_stream_manager_t *this, stream_service_constructor_t create)
  184: {
  185: 	enumerator_t *enumerator;
  186: 	service_entry_t *entry;
  187: 
  188: 	this->lock->write_lock(this->lock);
  189: 	enumerator = this->services->create_enumerator(this->services);
  190: 	while (enumerator->enumerate(enumerator, &entry))
  191: 	{
  192: 		if (entry->create == create)
  193: 		{
  194: 			this->services->remove_at(this->services, enumerator);
  195: 			free(entry->prefix);
  196: 			free(entry);
  197: 		}
  198: 	}
  199: 	enumerator->destroy(enumerator);
  200: 	this->lock->unlock(this->lock);
  201: }
  202: 
  203: METHOD(stream_manager_t, destroy, void,
  204: 	private_stream_manager_t *this)
  205: {
  206: 	remove_stream(this, stream_create_tcp);
  207: 	remove_service(this, stream_service_create_tcp);
  208: #ifndef WIN32
  209: 	remove_stream(this, stream_create_unix);
  210: 	remove_service(this, stream_service_create_unix);
  211: #endif
  212: #ifdef USE_SYSTEMD
  213: 	remove_service(this, stream_service_create_systemd);
  214: #endif
  215: 
  216: 	this->streams->destroy(this->streams);
  217: 	this->services->destroy(this->services);
  218: 	this->lock->destroy(this->lock);
  219: 	free(this);
  220: }
  221: 
  222: /**
  223:  * See header
  224:  */
  225: stream_manager_t *stream_manager_create()
  226: {
  227: 	private_stream_manager_t *this;
  228: 
  229: 	INIT(this,
  230: 		.public = {
  231: 			.connect = _connect_,
  232: 			.create_service = _create_service,
  233: 			.add_stream = _add_stream,
  234: 			.remove_stream = _remove_stream,
  235: 			.add_service = _add_service,
  236: 			.remove_service = _remove_service,
  237: 			.destroy = _destroy,
  238: 		},
  239: 		.streams = linked_list_create(),
  240: 		.services = linked_list_create(),
  241: 		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
  242: 	);
  243: 
  244: 	add_stream(this, "tcp://", stream_create_tcp);
  245: 	add_service(this, "tcp://", stream_service_create_tcp);
  246: #ifndef WIN32
  247: 	add_stream(this, "unix://", stream_create_unix);
  248: 	add_service(this, "unix://", stream_service_create_unix);
  249: #endif
  250: #ifdef USE_SYSTEMD
  251: 	add_service(this, "systemd://", stream_service_create_systemd);
  252: #endif
  253: 
  254: 	return &this->public;
  255: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>