stream: add support for UNIX streams
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user