about summary refs log tree commit diff
path: root/src/base/system.c
diff options
context:
space:
mode:
authoreeeee <eeeee@qwe123.info>2015-02-07 14:15:58 -0800
committerdef <dennis@felsin9.de>2015-04-19 16:05:39 +0200
commited763c52869ed05f326edf73c79a8ac8a6e35980 (patch)
tree2f81c70e8c74ed37e7efb17a8c5fd884ed50706e /src/base/system.c
parent424ce4987ced7deda3e355b7b6373680bf506646 (diff)
downloadzcatch-ed763c52869ed05f326edf73c79a8ac8a6e35980.tar.gz
zcatch-ed763c52869ed05f326edf73c79a8ac8a6e35980.zip
websockets support in server
Conflicts:
	bam.lua
Diffstat (limited to 'src/base/system.c')
-rw-r--r--src/base/system.c73
1 files changed, 71 insertions, 2 deletions
diff --git a/src/base/system.c b/src/base/system.c
index 5c6762ef..bc0c261d 100644
--- a/src/base/system.c
+++ b/src/base/system.c
@@ -9,6 +9,10 @@
 
 #include "system.h"
 
+#if defined(WEBSOCKETS)
+	#include "engine/shared/websockets.h"
+#endif
+
 #if defined(CONF_FAMILY_UNIX)
 	#include <sys/time.h>
 	#include <unistd.h>
@@ -64,6 +68,8 @@ static MEMSTATS memory_stats = {0};
 
 static NETSOCKET invalid_socket = {NETTYPE_INVALID, -1, -1};
 
+#define AF_WEBSOCKET_INET (0xee)
+
 void dbg_logger(DBG_LOGGER logger)
 {
 	loggers[num_loggers++] = logger;
@@ -561,7 +567,7 @@ int64 time_freq()
 static void netaddr_to_sockaddr_in(const NETADDR *src, struct sockaddr_in *dest)
 {
 	mem_zero(dest, sizeof(struct sockaddr_in));
-	if(src->type != NETTYPE_IPV4)
+	if(src->type != NETTYPE_IPV4 && src->type != NETTYPE_WEBSOCKET_IPV4)
 	{
 		dbg_msg("system", "couldn't convert NETADDR of type %d to ipv4", src->type);
 		return;
@@ -595,6 +601,13 @@ static void sockaddr_to_netaddr(const struct sockaddr *src, NETADDR *dst)
 		dst->port = htons(((struct sockaddr_in*)src)->sin_port);
 		mem_copy(dst->ip, &((struct sockaddr_in*)src)->sin_addr.s_addr, 4);
 	}
+	else if(src->sa_family == AF_WEBSOCKET_INET)
+	{
+		mem_zero(dst, sizeof(NETADDR));
+		dst->type = NETTYPE_WEBSOCKET_IPV4;
+		dst->port = htons(((struct sockaddr_in*)src)->sin_port);
+		mem_copy(dst->ip, &((struct sockaddr_in*)src)->sin_addr.s_addr, 4);
+	}
 	else if(src->sa_family == AF_INET6)
 	{
 		mem_zero(dst, sizeof(NETADDR));
@@ -616,7 +629,7 @@ int net_addr_comp(const NETADDR *a, const NETADDR *b)
 
 void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port)
 {
-	if(addr->type == NETTYPE_IPV4)
+	if(addr->type == NETTYPE_IPV4 || addr->type == NETTYPE_WEBSOCKET_IPV4)
 	{
 		if(add_port != 0)
 			str_format(string, max_length, "%d.%d.%d.%d:%d", addr->ip[0], addr->ip[1], addr->ip[2], addr->ip[3], addr->port);
@@ -842,6 +855,16 @@ static int priv_net_close_all_sockets(NETSOCKET sock)
 		sock.type &= ~NETTYPE_IPV4;
 	}
 
+#if defined(WEBSOCKETS)
+	/* close down websocket_ipv4 */
+	if(sock.web_ipv4sock >= 0)
+	{
+		websocket_destroy(sock.web_ipv4sock);
+		sock.web_ipv4sock = -1;
+		sock.type &= ~NETTYPE_WEBSOCKET_IPV4;
+	}
+#endif
+
 	/* close down ipv6 */
 	if(sock.ipv6sock >= 0)
 	{
@@ -931,6 +954,25 @@ NETSOCKET net_udp_create(NETADDR bindaddr)
 		}
 	}
 
+#if defined(WEBSOCKETS)
+	if(bindaddr.type&NETTYPE_WEBSOCKET_IPV4)
+	{
+		int socket = -1;
+
+		/* bind, we should check for error */
+		tmpbindaddr.type = NETTYPE_WEBSOCKET_IPV4;
+
+		char addr_str[NETADDR_MAXSTRSIZE];
+		net_addr_str(&tmpbindaddr, addr_str, sizeof(addr_str), 0);
+		socket = websocket_create(addr_str, tmpbindaddr.port);
+
+		if (socket >= 0) {
+			sock.type |= NETTYPE_WEBSOCKET_IPV4;
+			sock.web_ipv4sock = socket;
+		}
+	}
+#endif
+
 	if(bindaddr.type&NETTYPE_IPV6)
 	{
 		struct sockaddr_in6 addr;
@@ -985,6 +1027,16 @@ int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size
 			dbg_msg("net", "can't sent ipv4 traffic to this socket");
 	}
 
+#if defined(WEBSOCKETS)
+	if(addr->type&NETTYPE_WEBSOCKET_IPV4)
+	{
+		if(sock.web_ipv4sock >= 0)
+			d = websocket_send(sock.web_ipv4sock, (const unsigned char*)data, size, addr->port);
+		else
+			dbg_msg("net", "can't sent websocket_ipv4 traffic to this socket");
+	}
+#endif
+
 	if(addr->type&NETTYPE_IPV6)
 	{
 		if(sock.ipv6sock >= 0)
@@ -1046,6 +1098,15 @@ int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize)
 		bytes = recvfrom(sock.ipv6sock, (char*)data, maxsize, 0, (struct sockaddr *)&sockaddrbuf, &fromlen);
 	}
 
+#if defined(WEBSOCKETS)
+	if(bytes <= 0 && sock.web_ipv4sock >= 0)
+	{
+		fromlen = sizeof(struct sockaddr);
+		bytes = websocket_recv(sock.web_ipv4sock, data, maxsize, (struct sockaddr_in *)&sockaddrbuf, fromlen);
+		((struct sockaddr_in *)&sockaddrbuf)->sin_family = AF_WEBSOCKET_INET;
+	}
+#endif
+
 	if(bytes > 0)
 	{
 		sockaddr_to_netaddr((struct sockaddr *)&sockaddrbuf, addr);
@@ -1520,6 +1581,14 @@ int net_socket_read_wait(NETSOCKET sock, int time)
 		if(sock.ipv6sock > sockid)
 			sockid = sock.ipv6sock;
 	}
+#if defined(WEBSOCKETS)
+	if(sock.web_ipv4sock >= 0)
+	{
+		int maxfd = websocket_fd_set(sock.web_ipv4sock, &readfds);
+		if (maxfd > sockid)
+			sockid = maxfd;
+	}
+#endif
 
 	/* don't care about writefds and exceptfds */
 	select(sockid+1, &readfds, NULL, NULL, &tv);