diff options
-rw-r--r-- | network.c | 58 | ||||
-rw-r--r-- | network.h | 1 | ||||
-rw-r--r-- | plugin.c | 4 | ||||
-rw-r--r-- | websocksy.c | 23 | ||||
-rw-r--r-- | websocksy.h | 5 |
5 files changed, 74 insertions, 17 deletions
@@ -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 */ @@ -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); @@ -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 */ |