aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2019-05-31 22:10:15 +0200
committercbdev <cb@cbcdn.com>2019-05-31 22:10:15 +0200
commite16f061a715eb0d49a4872f7cc8c7bb58bb6e888 (patch)
tree848baadc27ef987eefd7370b2349d743c8e97467
parenta8233d97936eeed545ea763c0ace1eb4f87219f9 (diff)
downloadwebsocksy-e16f061a715eb0d49a4872f7cc8c7bb58bb6e888.tar.gz
websocksy-e16f061a715eb0d49a4872f7cc8c7bb58bb6e888.tar.bz2
websocksy-e16f061a715eb0d49a4872f7cc8c7bb58bb6e888.zip
Unix socket peer connection
-rw-r--r--network.c58
-rw-r--r--network.h1
-rw-r--r--plugin.c4
-rw-r--r--websocksy.c23
-rw-r--r--websocksy.h5
5 files changed, 74 insertions, 17 deletions
diff --git a/network.c b/network.c
index 2ecee4b..34baf8a 100644
--- a/network.c
+++ b/network.c
@@ -2,6 +2,7 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
@@ -10,8 +11,8 @@
#include <unistd.h>
/*
- * Create a file descriptor connected to a socket peer.
- * Client sockets will be connected, listening sockets will be bound.
+ * Create a file descriptor connected to a network socket peer.
+ * Client sockets will be connected, listening sockets will be bound/listened.
* Returns -1 in case of failure, a valid fd otherwise.
*/
int network_socket(char* host, char* port, int socktype, int listener){
@@ -98,6 +99,59 @@ int network_socket(char* host, char* port, int socktype, int listener){
}
/*
+ * Create a file descriptor connected to a unix socket peer.
+ * Client sockets will be connected, listening sockets will be bound.
+ * Returns -1 in case of failure, a valid fd otherwise.
+ */
+int network_socket_unix(char* path, int socktype, int listener){
+ struct sockaddr_un addr = {
+ .sun_family = AF_UNIX,
+ };
+ int fd = socket(AF_UNIX, socktype, 0), flags;
+
+ if(fd < 0){
+ fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
+ return -1;
+ }
+
+ //set nonblocking
+ flags = fcntl(fd, F_GETFL, 0);
+ if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0){
+ fprintf(stderr, "Failed to set socket nonblocking: %s\n", strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ strncpy(addr.sun_path, path, (strlen(path) < (sizeof(addr.sun_path) - 1)) ? strlen(path) : (sizeof(addr.sun_path) - 1));
+
+ if(listener){
+ unlink(path);
+ if(bind(fd, (struct sockaddr*) &addr, sizeof(addr))){
+ fprintf(stderr, "Failed to bind: %s\n", strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ if(listen(fd, SOMAXCONN)){
+ fprintf(stderr, "Failed to listen: %s\n", strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+ }
+
+ //connect clients
+ if(connect(fd, (struct sockaddr*) &addr, sizeof(addr))){
+ fprintf(stderr, "Failed to connect: %s\n", strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+/*
* Send arbitrary data over multiple writes if necessary.
* Returns 0 on success
*/
diff --git a/network.h b/network.h
index 50c8e18..9a1cfee 100644
--- a/network.h
+++ b/network.h
@@ -3,5 +3,6 @@
/* Socket interface convenience functions */
int network_socket(char* host, char* port, int socktype, int listener);
+int network_socket_unix(char* path, int socktype, int listener);
int network_send(int fd, uint8_t* data, size_t length);
int network_send_str(int fd, char* data);
diff --git a/plugin.c b/plugin.c
index 8b61ec3..87c9bde 100644
--- a/plugin.c
+++ b/plugin.c
@@ -10,12 +10,12 @@ static char** framing_function_name = NULL;
int plugin_framing_load(char* path){
//TODO load plugins
- return 1;
+ return 0;
}
int plugin_backend_load(char* backend_requested, ws_backend* backend){
//TODO load backend
- return 1;
+ return 0;
}
int plugin_register_framing(char* name, ws_framing func){
diff --git a/websocksy.c b/websocksy.c
index 4846945..1bd1abf 100644
--- a/websocksy.c
+++ b/websocksy.c
@@ -113,7 +113,11 @@ static peer_transport client_detect_transport(char* host){
}
else if(!strncmp(host, "unix://", 8)){
memmove(host, host + 8, strlen(host) - 7);
- return peer_unix;
+ return peer_unix_stream;
+ }
+ else if(!strncmp(host, "unix-dgram://", 13)){
+ memmove(host, host + 13, strlen(host) - 12);
+ return peer_unix_dgram;
}
fprintf(stderr, "Peer address %s does not include any known protocol identifier, guessing tcp_client\n", host);
@@ -123,7 +127,8 @@ static peer_transport client_detect_transport(char* host){
/* Establish peer connection for negotiated websocket */
int client_connect(websocket* ws){
ws->peer = config.backend.query(ws->request_path, ws->protocols, ws->protocol, ws->headers, ws->header, ws);
- if(!ws->peer.host || !ws->peer.port){
+ if(!ws->peer.host){
+ //TODO check port if network socket
//no peer provided
return 1;
}
@@ -146,19 +151,17 @@ int client_connect(websocket* ws){
case peer_udp_client:
ws->peer_fd = network_socket(ws->peer.host, ws->peer.port, SOCK_DGRAM, 0);
break;
- case peer_tcp_server:
- //TODO implement tcp server mode
- fprintf(stderr, "TCP Server mode not yet implemented\n");
- return 1;
- case peer_udp_server:
- ws->peer_fd = network_socket(ws->peer.host, ws->peer.port, SOCK_DGRAM, 1);
- break;
case peer_fifo_tx:
case peer_fifo_rx:
- case peer_unix:
//TODO implement other peer modes
fprintf(stderr, "Peer connection mode not yet implemented\n");
return 1;
+ case peer_unix_stream:
+ ws->peer_fd = network_socket_unix(ws->peer.host, SOCK_STREAM, 0);
+ break;
+ case peer_unix_dgram:
+ ws->peer_fd = network_socket_unix(ws->peer.host, SOCK_DGRAM, 0);
+ break;
default:
fprintf(stderr, "Invalid peer transport selected\n");
return 1;
diff --git a/websocksy.h b/websocksy.h
index 9cf1588..8b85719 100644
--- a/websocksy.h
+++ b/websocksy.h
@@ -92,11 +92,10 @@ typedef enum {
peer_transport_detect,
peer_tcp_client,
peer_udp_client,
- peer_tcp_server,
- peer_udp_server,
peer_fifo_tx,
peer_fifo_rx,
- peer_unix
+ peer_unix_stream,
+ peer_unix_dgram
} peer_transport;
/* Peer address model */