stream: add support for UNIX streams

This commit is contained in:
Martin Willi
2013-07-18 16:00:28 +02:00
parent c1fd8c22ce
commit b785cfe05b
3 changed files with 77 additions and 0 deletions
@@ -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);
}
@@ -25,6 +25,8 @@ typedef struct stream_t stream_t;
#include <library.h>
#include <sys/un.h>
/**
* Constructor function prototype for stream_t.
*
@@ -121,6 +123,28 @@ struct stream_t {
void (*destroy)(stream_t *this);
};
/**
* 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.
*
@@ -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;
}