Support UNIX sockets
Adds support for UNIX domain sockets with `nvnc_open_unix()` function. Closes #1.pull/54/head
parent
019d6eda36
commit
b320723049
|
@ -54,6 +54,7 @@ typedef void (*nvnc_cut_text_fn)(struct nvnc*, const char* text, uint32_t len);
|
||||||
extern const char nvnc_version[];
|
extern const char nvnc_version[];
|
||||||
|
|
||||||
struct nvnc* nvnc_open(const char* addr, uint16_t port);
|
struct nvnc* nvnc_open(const char* addr, uint16_t port);
|
||||||
|
struct nvnc* nvnc_open_unix(const char *addr);
|
||||||
void nvnc_close(struct nvnc* self);
|
void nvnc_close(struct nvnc* self);
|
||||||
|
|
||||||
void nvnc_add_display(struct nvnc*, struct nvnc_display*);
|
void nvnc_add_display(struct nvnc*, struct nvnc_display*);
|
||||||
|
|
90
src/server.c
90
src/server.c
|
@ -42,6 +42,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
#ifdef ENABLE_TLS
|
#ifdef ENABLE_TLS
|
||||||
|
@ -69,6 +70,11 @@ struct fb_update_work {
|
||||||
struct nvnc_fb* fb;
|
struct nvnc_fb* fb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum addrtype {
|
||||||
|
ADDRTYPE_TCP,
|
||||||
|
ADDRTYPE_UNIX,
|
||||||
|
};
|
||||||
|
|
||||||
int schedule_client_update_fb(struct nvnc_client* client,
|
int schedule_client_update_fb(struct nvnc_client* client,
|
||||||
struct pixman_region16* damage);
|
struct pixman_region16* damage);
|
||||||
static int send_desktop_resize(struct nvnc_client* client, struct nvnc_fb* fb);
|
static int send_desktop_resize(struct nvnc_client* client, struct nvnc_fb* fb);
|
||||||
|
@ -1009,7 +1015,7 @@ accept_failure:
|
||||||
free(client);
|
free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bind_address(const char* name, int port)
|
static int bind_address_tcp(const char* name, int port)
|
||||||
{
|
{
|
||||||
struct addrinfo hints = {
|
struct addrinfo hints = {
|
||||||
.ai_socktype = SOCK_STREAM,
|
.ai_socktype = SOCK_STREAM,
|
||||||
|
@ -1048,6 +1054,43 @@ failure:
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bind_address_unix(const char* name)
|
||||||
|
{
|
||||||
|
struct sockaddr_un addr = {
|
||||||
|
.sun_family = AF_UNIX,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (strlen(name) >= sizeof(addr.sun_path)) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(addr.sun_path, name);
|
||||||
|
|
||||||
|
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bind_address(const char* name, uint16_t port, enum addrtype type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case ADDRTYPE_TCP:
|
||||||
|
return bind_address_tcp(name, port);
|
||||||
|
case ADDRTYPE_UNIX:
|
||||||
|
return bind_address_unix(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error("unknown socket address type");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
static bool nvnc__is_damaged(struct nvnc* self)
|
static bool nvnc__is_damaged(struct nvnc* self)
|
||||||
{
|
{
|
||||||
struct nvnc_client* client;
|
struct nvnc_client* client;
|
||||||
|
@ -1081,8 +1124,7 @@ static void on_main_dispatch(void* aml_obj)
|
||||||
process_fb_update_requests(client);
|
process_fb_update_requests(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT
|
static struct nvnc* open_common(const char* address, uint16_t port, enum addrtype type)
|
||||||
struct nvnc* nvnc_open(const char* address, uint16_t port)
|
|
||||||
{
|
{
|
||||||
aml_require_workers(aml_get_default(), -1);
|
aml_require_workers(aml_get_default(), -1);
|
||||||
|
|
||||||
|
@ -1094,16 +1136,16 @@ struct nvnc* nvnc_open(const char* address, uint16_t port)
|
||||||
|
|
||||||
LIST_INIT(&self->clients);
|
LIST_INIT(&self->clients);
|
||||||
|
|
||||||
self->fd = bind_address(address, port);
|
self->fd = bind_address(address, port, type);
|
||||||
if (self->fd < 0)
|
if (self->fd < 0)
|
||||||
goto failure;
|
goto bind_failure;
|
||||||
|
|
||||||
if (listen(self->fd, 16) < 0)
|
if (listen(self->fd, 16) < 0)
|
||||||
goto failure;
|
goto listen_failure;
|
||||||
|
|
||||||
self->poll_handle = aml_handler_new(self->fd, on_connection, self, NULL);
|
self->poll_handle = aml_handler_new(self->fd, on_connection, self, NULL);
|
||||||
if (!self->poll_handle)
|
if (!self->poll_handle)
|
||||||
goto failure;
|
goto handle_failure;
|
||||||
|
|
||||||
if (aml_start(aml_get_default(), self->poll_handle) < 0)
|
if (aml_start(aml_get_default(), self->poll_handle) < 0)
|
||||||
goto poll_start_failure;
|
goto poll_start_failure;
|
||||||
|
@ -1123,11 +1165,42 @@ new_idle_failure:
|
||||||
aml_stop(aml_get_default(), self->poll_handle);
|
aml_stop(aml_get_default(), self->poll_handle);
|
||||||
poll_start_failure:
|
poll_start_failure:
|
||||||
aml_unref(self->poll_handle);
|
aml_unref(self->poll_handle);
|
||||||
failure:
|
handle_failure:
|
||||||
|
listen_failure:
|
||||||
close(self->fd);
|
close(self->fd);
|
||||||
|
if (type == ADDRTYPE_UNIX) {
|
||||||
|
unlink(address);
|
||||||
|
}
|
||||||
|
bind_failure:
|
||||||
|
free(self);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT
|
||||||
|
struct nvnc* nvnc_open(const char* address, uint16_t port)
|
||||||
|
{
|
||||||
|
return open_common(address, port, ADDRTYPE_TCP);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT
|
||||||
|
struct nvnc* nvnc_open_unix(const char* address)
|
||||||
|
{
|
||||||
|
return open_common(address, 0, ADDRTYPE_UNIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unlink_fd_path(int fd)
|
||||||
|
{
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
socklen_t addr_len = sizeof(addr);
|
||||||
|
|
||||||
|
if (getsockname(fd, (struct sockaddr*)&addr, &addr_len) == 0) {
|
||||||
|
if (addr.sun_family == AF_UNIX) {
|
||||||
|
unlink(addr.sun_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EXPORT
|
EXPORT
|
||||||
void nvnc_close(struct nvnc* self)
|
void nvnc_close(struct nvnc* self)
|
||||||
{
|
{
|
||||||
|
@ -1142,6 +1215,7 @@ void nvnc_close(struct nvnc* self)
|
||||||
|
|
||||||
aml_stop(aml_get_default(), self->dispatch_handler);
|
aml_stop(aml_get_default(), self->dispatch_handler);
|
||||||
aml_stop(aml_get_default(), self->poll_handle);
|
aml_stop(aml_get_default(), self->poll_handle);
|
||||||
|
unlink_fd_path(self->fd);
|
||||||
close(self->fd);
|
close(self->fd);
|
||||||
|
|
||||||
#ifdef ENABLE_TLS
|
#ifdef ENABLE_TLS
|
||||||
|
|
Loading…
Reference in New Issue