From b785cfe05beaa35be96d57a4f1dcc748b91e50b6 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 26 Jun 2013 17:08:14 +0200 Subject: [PATCH] stream: add support for UNIX streams --- src/libstrongswan/networking/streams/stream.c | 49 ++++++++++++++++++++++ src/libstrongswan/networking/streams/stream.h | 24 +++++++++++ .../networking/streams/stream_manager.c | 4 ++ 3 files changed, 77 insertions(+) diff --git a/src/libstrongswan/networking/streams/stream.c b/src/libstrongswan/networking/streams/stream.c index d3b6776..3c782cc 100644 --- a/src/libstrongswan/networking/streams/stream.c +++ b/src/libstrongswan/networking/streams/stream.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include typedef struct private_stream_t private_stream_t; @@ -266,3 +268,50 @@ stream_t *stream_create_from_fd(int fd) return &this->public; } + +/** + * See header + */ +int stream_parse_uri_unix(char *uri, struct sockaddr_un *addr) +{ + if (!strpfx(uri, "unix://")) + { + return -1; + } + uri += strlen("unix://"); + + memset(addr, 0, sizeof(*addr)); + addr->sun_family = AF_UNIX; + strncpy(addr->sun_path, uri, sizeof(addr->sun_path)); + + return offsetof(struct sockaddr_un, sun_path) + strlen(addr->sun_path); +} + +/** + * See header + */ +stream_t *stream_create_unix(char *uri) +{ + struct sockaddr_un addr; + int len, fd; + + len = stream_parse_uri_unix(uri, &addr); + if (len == -1) + { + DBG1(DBG_NET, "invalid stream URI: '%s'", uri); + return NULL; + } + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + { + DBG1(DBG_NET, "opening socket '%s' failed: %s", uri, strerror(errno)); + return NULL; + } + if (connect(fd, (struct sockaddr*)&addr, len) < 0) + { + DBG1(DBG_NET, "connecting to '%s' failed: %s", uri, strerror(errno)); + close(fd); + return NULL; + } + return stream_create_from_fd(fd); +} diff --git a/src/libstrongswan/networking/streams/stream.h b/src/libstrongswan/networking/streams/stream.h index 4e0a67a..842ad8e 100644 --- a/src/libstrongswan/networking/streams/stream.h +++ b/src/libstrongswan/networking/streams/stream.h @@ -25,6 +25,8 @@ typedef struct stream_t stream_t; #include +#include + /** * Constructor function prototype for stream_t. * @@ -122,6 +124,28 @@ struct stream_t { }; /** + * Create a stream for UNIX sockets. + * + * UNIX URIs start with unix://, followed by the socket path. For absolute + * paths, an URI looks something like: + * + * unix:///path/to/socket + * + * @param uri UNIX socket specific URI, must start with "unix://" + * @return stream instance, NULL on failure + */ +stream_t *stream_create_unix(char *uri); + +/** + * Helper function to parse a unix:// URI to a sockaddr + * + * @param uri URI + * @param addr sockaddr + * @return length of sockaddr, -1 on error + */ +int stream_parse_uri_unix(char *uri, struct sockaddr_un *addr); + +/** * Create a stream from a file descriptor. * * The file descriptor MUST be a socket for non-blocking operation. diff --git a/src/libstrongswan/networking/streams/stream_manager.c b/src/libstrongswan/networking/streams/stream_manager.c index d28cb70..38aaf9a 100644 --- a/src/libstrongswan/networking/streams/stream_manager.c +++ b/src/libstrongswan/networking/streams/stream_manager.c @@ -247,6 +247,8 @@ METHOD(stream_manager_t, remove_service, void, METHOD(stream_manager_t, destroy, void, private_stream_manager_t *this) { + remove_stream(this, stream_create_unix); + this->streams->destroy(this->streams); this->services->destroy(this->services); this->running->destroy(this->running); @@ -278,5 +280,7 @@ stream_manager_t *stream_manager_create() .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); + add_stream(this, "unix://", stream_create_unix); + return &this->public; } -- 2.7.4