aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2019-05-12 23:18:03 +0200
committercbdev <cb@cbcdn.com>2019-05-12 23:18:03 +0200
commit10874eb2195d3e6ceed8e8a76aaf4455e41c8683 (patch)
tree1984c7254e1e76ed26e19e757dfd8e6e3f5516de
parenta170ae3ac205675d86f1a564a51c54d0fbc2a380 (diff)
downloadwebsocksy-10874eb2195d3e6ceed8e8a76aaf4455e41c8683.tar.gz
websocksy-10874eb2195d3e6ceed8e8a76aaf4455e41c8683.tar.bz2
websocksy-10874eb2195d3e6ceed8e8a76aaf4455e41c8683.zip
Client handling
-rw-r--r--index.html11
-rw-r--r--websocksy.c98
-rw-r--r--websocksy.h12
3 files changed, 98 insertions, 23 deletions
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..c0af329
--- /dev/null
+++ b/index.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <script type="text/javascript">
+ function init(){
+ var webSocket = new WebSocket("ws://localhost:8001/");
+ }
+ </script>
+ </head>
+ <body onload="init();">
+ </body>
+</html>
diff --git a/websocksy.c b/websocksy.c
index dba8124..cc5b9e0 100644
--- a/websocksy.c
+++ b/websocksy.c
@@ -14,6 +14,7 @@
/* TODO
* - TLS
* - config parsing
+ * - Prevent http overrun
*/
static size_t socks = 0;
@@ -120,13 +121,33 @@ int network_socket(char* host, char* port, int socktype, int listener){
return fd;
}
+int ws_close(websocket* ws){
+ size_t p;
+
+ if(ws->fd >= 0){
+ close(ws->fd);
+ ws->fd = -1;
+ }
+
+ for(p = 0; p < ws->protocols; p++){
+ if(ws->protocol[p].fd >= 0){
+ close(ws->protocol[p].fd);
+ ws->protocol[p].fd = -1;
+ free(ws->protocol[p].name);
+ ws->protocol[p].name = NULL;
+ }
+ }
+
+ ws->read_buffer_offset = 0;
+
+ return 0;
+}
+
int ws_accept(int listen_fd){
size_t n = 0;
- struct sockaddr_storage sa_storage;
- socklen_t sa_length;
websocket ws = {
- .fd = accept(listen_fd, (struct sockaddr*)&sa_storage, &sa_length)
+ .fd = accept(listen_fd, NULL, NULL)
};
//try to find a slot to occupy
@@ -154,34 +175,65 @@ int ws_accept(int listen_fd){
}
int ws_data(websocket* ws){
- //TODO
- return -1;
-}
+ ssize_t bytes_read, u, bytes_left = sizeof(ws->read_buffer) - ws->read_buffer_offset;
-int ws_peer_data(websocket* ws, size_t proto){
- //TODO
- return -1;
-}
-
-int ws_close(websocket* ws){
- size_t p;
-
- if(ws->fd >= 0){
- close(ws->fd);
- ws->fd = -1;
+ bytes_read = recv(ws->fd, ws->read_buffer + ws->read_buffer_offset, bytes_left - 1, 0);
+ if(bytes_read < 0){
+ fprintf(stderr, "Failed to receive from websocket: %s\n", strerror(errno));
+ ws_close(ws);
+ return 0;
+ }
+ else if(bytes_read == 0){
+ //client closed connection
+ ws_close(ws);
+ return 0;
}
- for(p = 0; p < ws->protocols; p++){
- if(ws->protocol[p].fd >= 0){
- close(ws->protocol[p].fd);
- ws->protocol[p].fd = -1;
- free(ws->protocol[p].name);
- }
+ //terminate new data
+ ws->read_buffer[ws->read_buffer_offset + bytes_read] = 0;
+
+ switch(ws->state){
+ case ws_new:
+ case ws_http:
+ //scan for newline, handle line
+ for(u = 0; u < bytes_read - 1; u++){
+ if(!strncmp((char*) ws->read_buffer + ws->read_buffer_offset + u, "\r\n", 2)){
+ //terminate line
+ ws->read_buffer[ws->read_buffer_offset + u] = 0;
+
+ fprintf(stderr, "Line: %s\n", ws->read_buffer);
+
+ //remove from buffer
+ bytes_read -= (u + 2);
+ memmove(ws->read_buffer, ws->read_buffer + ws->read_buffer_offset + u + 2, bytes_read);
+ ws->read_buffer_offset = 0;
+
+ //restart from the beginning
+ u = -1;
+ }
+ }
+ break;
+ //case ws_rfc6455:
+ //TODO parse websocket encap, forward to peer
}
+ //update read buffer offset
+ ws->read_buffer_offset = bytes_read;
+
+ //disconnect spammy clients
+ if(sizeof(ws->read_buffer) - ws->read_buffer_offset < 2){
+ fprintf(stderr, "Disconnecting misbehaving client\n");
+ ws_close(ws);
+ return 0;
+ }
return 0;
}
+int ws_peer_data(websocket* ws, size_t proto){
+ //TODO
+ return -1;
+}
+
int main(int argc, char** argv){
fd_set read_fds;
size_t n, p;
diff --git a/websocksy.h b/websocksy.h
index 36a713d..0fc9538 100644
--- a/websocksy.h
+++ b/websocksy.h
@@ -1,6 +1,14 @@
#include <stdint.h>
#include <stdlib.h>
+#define WS_MAX_LINE 16384
+
+typedef enum {
+ ws_new = 0,
+ ws_http,
+ ws_rfc6455
+} ws_state;
+
struct {
char* host;
char* port;
@@ -19,6 +27,10 @@ typedef struct {
} ws_proto;
typedef struct /*_web_socket*/ {
+ uint8_t read_buffer[WS_MAX_LINE];
+ size_t read_buffer_offset;
+ ws_state state;
+
int fd;
size_t protocols;
ws_proto* protocol;