diff options
author | Martin Willi <martin@revosec.ch> | 2013-06-26 17:08:14 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2013-07-18 16:00:28 +0200 |
commit | b785cfe05beaa35be96d57a4f1dcc748b91e50b6 (patch) | |
tree | 2e9df1389c2143fc3d37aa3a43c82c25528560dd | |
parent | c1fd8c22ce26b0204d979352e292815d6361c8b4 (diff) | |
download | strongswan-b785cfe05beaa35be96d57a4f1dcc748b91e50b6.tar.bz2 strongswan-b785cfe05beaa35be96d57a4f1dcc748b91e50b6.tar.xz |
stream: add support for UNIX streams
-rw-r--r-- | src/libstrongswan/networking/streams/stream.c | 49 | ||||
-rw-r--r-- | src/libstrongswan/networking/streams/stream.h | 24 | ||||
-rw-r--r-- | src/libstrongswan/networking/streams/stream_manager.c | 4 |
3 files changed, 77 insertions, 0 deletions
diff --git a/src/libstrongswan/networking/streams/stream.c b/src/libstrongswan/networking/streams/stream.c index d3b67761e..3c782cce0 100644 --- a/src/libstrongswan/networking/streams/stream.c +++ b/src/libstrongswan/networking/streams/stream.c @@ -16,6 +16,8 @@ #include <library.h> #include <errno.h> #include <unistd.h> +#include <sys/socket.h> +#include <sys/un.h> 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 4e0a67a07..842ad8e67 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 <library.h> +#include <sys/un.h> + /** * 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 d28cb70e2..38aaf9af9 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; } |