aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtins.c8
-rw-r--r--websocksy.c114
-rw-r--r--websocksy.h13
3 files changed, 98 insertions, 37 deletions
diff --git a/builtins.c b/builtins.c
index d5b081f..3461521 100644
--- a/builtins.c
+++ b/builtins.c
@@ -21,9 +21,9 @@ static char* default_peer_proto = NULL;
*/
uint64_t backend_defaultpeer_init(){
ws_peer_info startup_peer = {
- .transport = peer_tcp_client,
- .host = strdup("localhost"),
- .port = strdup("5900")
+ .transport = peer_transport_detect,
+ .host = (default_peer.host) ? default_peer.host : strdup("tcp://localhost"),
+ .port = (default_peer.port) ? default_peer.port : strdup("5900")
};
default_peer = startup_peer;
@@ -35,9 +35,9 @@ uint64_t backend_defaultpeer_init(){
*/
uint64_t backend_defaultpeer_configure(char* key, char* value){
if(!strcmp(key, "host")){
- //TODO extract peer protocol
free(default_peer.host);
default_peer.host = strdup(value);
+ default_peer.transport = peer_transport_detect;
}
else if(!strcmp(key, "port")){
free(default_peer.port);
diff --git a/websocksy.c b/websocksy.c
index aa0cf77..55a6d6a 100644
--- a/websocksy.c
+++ b/websocksy.c
@@ -15,12 +15,11 @@
#include "network.h"
#include "websocket.h"
+#define DEFAULT_HOST "::"
+#define DEFAULT_PORT "8001"
+
/* TODO
* - TLS
- * - config parsing
- * - backend config
- * - framing config / per peer?
- * - per-connection framing state
* - framing function discovery / registry
*/
@@ -46,8 +45,8 @@ static struct {
char* port;
ws_backend backend;
} config = {
- .host = "::",
- .port = "8001",
+ .host = DEFAULT_HOST,
+ .port = DEFAULT_PORT,
/* Assign the built-in defaultpeer backend by default */
.backend.init = backend_defaultpeer_init,
.backend.config = backend_defaultpeer_configure,
@@ -93,10 +92,34 @@ void client_cleanup(){
socks = 0;
}
+static peer_transport client_detect_transport(char* host){
+ if(!strncmp(host, "tcp://", 6)){
+ memmove(host, host + 6, strlen(host) - 5);
+ return peer_tcp_client;
+ }
+ else if(!strncmp(host, "udp://", 6)){
+ memmove(host, host + 6, strlen(host) - 5);
+ return peer_udp_client;
+ }
+ else if(!strncmp(host, "fifotx://", 9)){
+ memmove(host, host + 9, strlen(host) - 8);
+ return peer_fifo_tx;
+ }
+ else if(!strncmp(host, "fiforx://", 9)){
+ memmove(host, host + 9, strlen(host) - 8);
+ return peer_fifo_rx;
+ }
+ else if(!strncmp(host, "unix://", 8)){
+ memmove(host, host + 8, strlen(host) - 7);
+ return peer_unix;
+ }
+
+ fprintf(stderr, "Peer address %s does not include any known protocol identifier, guessing tcp_client\n", host);
+ return peer_tcp_client;
+}
+
/* Establish peer connection for negotiated websocket */
int client_connect(websocket* ws){
- int rv = 1;
-
ws->peer = config.backend.query(ws->request_path, ws->protocols, ws->protocol, ws->headers, ws->header, ws);
if(!ws->peer.host || !ws->peer.port){
//no peer provided
@@ -108,6 +131,11 @@ int client_connect(websocket* ws){
ws->peer.framing = framing_auto;
}
+ //if required scan the hostname for a protocol
+ if(ws->peer.transport == peer_transport_detect){
+ ws->peer.transport = client_detect_transport(ws->peer.host);
+ }
+
//TODO connection establishment should be async in the future
switch(ws->peer.transport){
case peer_tcp_client:
@@ -119,44 +147,82 @@ int client_connect(websocket* ws){
case peer_tcp_server:
//TODO implement tcp server mode
fprintf(stderr, "TCP Server mode not yet implemented\n");
- rv = 1;
- break;
+ 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:
- default:
//TODO implement other peer modes
fprintf(stderr, "Peer connection mode not yet implemented\n");
- rv = 1;
- break;
+ return 1;
+ default:
+ fprintf(stderr, "Invalid peer transport selected\n");
+ return 1;
}
- rv = (ws->peer_fd == -1) ? 1 : 0;
- return rv;
+ return (ws->peer_fd == -1) ? 1 : 0;
}
-/*
- * Signal handler, attached to SIGINT
- */
+/* Signal handler, attached to SIGINT */
static void signal_handler(int signum){
shutdown_requested = 1;
}
-/*
- * Usage info
- */
+/* Usage info */
static int usage(char* fn){
fprintf(stderr, "\nwebsocksy v%s - Proxy between websockets and 'real' sockets\n", WEBSOCKSY_VERSION);
fprintf(stderr, "Usage:\n");
- fprintf(stderr, "\t%s [-p <port>] [-l <listen address>] [-b <targeting backend>]\n", fn);
+ fprintf(stderr, "\t%s [-p <port>] [-l <listen address>] [-b <discovery backend>] [-c <option>=<value>]\n", fn);
+ fprintf(stderr, "Arguments:\n");
+ fprintf(stderr, "\t-p <port>\t\tWebSocket listen port (Current: %s, Default: %s)\n", config.port, DEFAULT_PORT);
+ fprintf(stderr, "\t-l <address>\t\tWebSocket listen address (Current: %s, Default: %s)\n", config.host, DEFAULT_HOST);
+ fprintf(stderr, "\t-b <backend>\t\tPeer discovery backend (Default: built-in 'defaultpeer')\n");
+ fprintf(stderr, "\t-c <option>=<value>\tPass configuration options to the peer discovery backend\n");
return EXIT_FAILURE;
}
-int args_parse(int argc, char** argv){
- //TODO
+static int args_parse(int argc, char** argv){
+ size_t u;
+ char* option = NULL, *value = NULL;
+
+ if(argc % 2){
+ return 1;
+ }
+
+ for(u = 0; u < argc; u += 2){
+ if(argv[u][0] != '-'){
+ return 1;
+ }
+ switch(argv[u][1]){
+ case 'p':
+ config.port = argv[u + 1];
+ break;
+ case 'l':
+ config.host = argv[u + 1];
+ break;
+ case 'b':
+ //TODO load peer discovery plugin
+ break;
+ case 'c':
+ if(!strchr(argv[u + 1], '=')){
+ return 1;
+ }
+ if(!config.backend.config){
+ continue;
+ }
+ option = strdup(argv[u + 1]);
+ value = strchr(option, '=');
+ *value = 0;
+ value++;
+ config.backend.config(option, value);
+ free(option);
+ option = NULL;
+ value = NULL;
+ break;
+ }
+ }
return 0;
}
diff --git a/websocksy.h b/websocksy.h
index f50bb46..c7311ca 100644
--- a/websocksy.h
+++ b/websocksy.h
@@ -87,10 +87,9 @@ typedef struct /*_ws_http_header*/ {
*/
typedef int64_t (*ws_framing)(uint8_t* data, size_t length, size_t last_read, ws_operation* opcode, void** framing_data, char* config);
-/*
- * Modes of peer connection establishment
- */
+/* Peer connection modes */
typedef enum {
+ peer_transport_detect,
peer_tcp_client,
peer_udp_client,
peer_tcp_server,
@@ -100,9 +99,7 @@ typedef enum {
peer_unix
} peer_transport;
-/*
- * Peer connection model
- */
+/* Peer address model */
typedef struct /*_ws_peer_info*/ {
/* Peer protocol data */
peer_transport transport;
@@ -117,9 +114,7 @@ typedef struct /*_ws_peer_info*/ {
size_t protocol;
} ws_peer_info;
-/*
- * Core connection model
- */
+/* Core connection model */
typedef struct /*_web_socket*/ {
/* WebSocket state & data */
int ws_fd;