stream: Add basic stream service for systemd sockets

This allows systemd socket activation by passing URIs such as systemd://foo
to plugins such as VICI.

For example setting charon.plugins.vici.socket = systemd://vici, a
systemd socket file descriptor with the name "vici" will be picked up.

So these would be the corresponding unit options:

  [Socket]
  FileDescriptorName=vici
  Service=strongswan.service

  ListenStream=/run/charon.vici

The implementation currently is very basic and right now only the first
file descriptor for a particular identifier is picked up if there are
multiple socket units with the same FileDescriptorName.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>

Closes strongswan/strongswan#79.
This commit is contained in:
aszlig 2017-08-30 02:36:34 +02:00 committed by Tobias Brunner
parent ea613d5d27
commit 59db98fb94
4 changed files with 118 additions and 0 deletions

View File

@ -96,6 +96,7 @@ 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_unix.h networking/streams/stream_service_unix.h \
networking/streams/stream_service_systemd.h \
networking/streams/stream_tcp.h networking/streams/stream_service_tcp.h \
networking/streams/stream_service.h networking/streams/stream_manager.h \
resolver/resolver.h resolver/resolver_response.h resolver/rr_set.h \
@ -192,6 +193,12 @@ if USE_LIBCAP
libstrongswan_la_LIBADD += -lcap
endif
if USE_SYSTEMD
AM_CPPFLAGS += $(systemd_CFLAGS) -DUSE_SYSTEMD
libstrongswan_la_SOURCES += networking/streams/stream_service_systemd.c
libstrongswan_la_LIBADD += $(systemd_LIBS)
endif
EXTRA_DIST = \
asn1/oid.txt asn1/oid.pl \
crypto/proposal/proposal_keywords_static.txt \

View File

@ -21,6 +21,9 @@
# include "stream_unix.h"
# include "stream_service_unix.h"
#endif
#ifdef USE_SYSTEMD
# include "stream_service_systemd.h"
#endif
#include <threading/rwlock.h>
@ -241,6 +244,9 @@ stream_manager_t *stream_manager_create()
add_stream(this, "unix://", stream_create_unix);
add_service(this, "unix://", stream_service_create_unix);
#endif
#ifdef USE_SYSTEMD
add_service(this, "systemd://", stream_service_create_systemd);
#endif
return &this->public;
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2017 aszlig
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <systemd/sd-daemon.h>
#include <library.h>
/**
* See header
*/
stream_service_t *stream_service_create_systemd(char *uri, int backlog)
{
int i, num_fds, fd;
char **fdmap;
if (!strpfx(uri, "systemd://"))
{
DBG1(DBG_NET, "invalid stream URI: '%s'", uri);
return NULL;
}
uri += strlen("systemd://");
num_fds = sd_listen_fds_with_names(0, &fdmap);
if (num_fds <= 0)
{
DBG1(DBG_NET, "no systemd sockets for '%s'", uri);
return NULL;
}
for (i = 0, fd = -1; i < num_fds; i++)
{
if (fd == -1 && streq(fdmap[i], uri))
{
fd = SD_LISTEN_FDS_START + i;
}
free(fdmap[i]);
}
free(fdmap);
if (fd == -1)
{
DBG1(DBG_NET, "unable to find systemd FD for '%s'", uri);
return NULL;
}
return stream_service_create_from_fd(fd);
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2017 aszlig
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/**
* @defgroup stream_service_systemd stream_service_systemd
* @{ @ingroup stream
*/
#ifndef STREAM_SERVICE_SYSTEMD_H_
#define STREAM_SERVICE_SYSTEMD_H_
/**
* Create a service instance for systemd sockets.
*
* @param uri URI with FD identifier, must start with "systemd://"
* @param backlog size of the backlog queue (ignored)
* @return stream_service instance, NULL on failure
*/
stream_service_t *stream_service_create_systemd(char *uri, int backlog);
#endif /** STREAM_SERVICE_SYSTEMD_H_ @}*/