Skip to content
Snippets Groups Projects
Commit 3eb8564b authored by rswindell's avatar rswindell
Browse files

Initial support for UDP services.

parent 791db64f
No related branches found
No related tags found
No related merge requests found
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
#define MAX_SERVICES 128 #define MAX_SERVICES 128
#define TIMEOUT_THREAD_WAIT 60 /* Seconds */ #define TIMEOUT_THREAD_WAIT 60 /* Seconds */
#define MAX_UDP_BUF_LEN 8192 /* 8K */
static services_startup_t* startup=NULL; static services_startup_t* startup=NULL;
static scfg_t scfg; static scfg_t scfg;
...@@ -101,6 +102,9 @@ typedef struct { ...@@ -101,6 +102,9 @@ typedef struct {
client_t* client; client_t* client;
service_t* service; service_t* service;
ulong js_loop; ulong js_loop;
/* Initial UDP datagram */
BYTE* udp_buf;
int udp_len;
} service_client_t; } service_client_t;
static service_t *service; static service_t *service;
...@@ -580,6 +584,7 @@ static void js_service_thread(void* arg) ...@@ -580,6 +584,7 @@ static void js_service_thread(void* arg)
int argc=0; int argc=0;
JSString* arg_str; JSString* arg_str;
JSObject* argv; JSObject* argv;
JSString* datagram;
JSObject* js_glob; JSObject* js_glob;
JSScript* js_script; JSScript* js_script;
JSRuntime* js_runtime; JSRuntime* js_runtime;
...@@ -708,6 +713,16 @@ static void js_service_thread(void* arg) ...@@ -708,6 +713,16 @@ static void js_service_thread(void* arg)
val = BOOLEAN_TO_JSVAL(JS_FALSE); val = BOOLEAN_TO_JSVAL(JS_FALSE);
JS_SetProperty(js_cx, js_glob, "logged_in", &val); JS_SetProperty(js_cx, js_glob, "logged_in", &val);
if(service->options&SERVICE_OPT_UDP
&& service_client.udp_buf != NULL
&& service_client.udp_len > 0) {
datagram = JS_NewStringCopyN(js_cx, service_client.udp_buf, service_client.udp_len);
val = STRING_TO_JSVAL(datagram);
} else
val = JSVAL_VOID;
JS_SetProperty(js_cx, js_glob, "datagram", &val);
FREE_AND_NULL(service_client.udp_buf);
js_script=JS_CompileFile(js_cx, js_glob, spath); js_script=JS_CompileFile(js_cx, js_glob, spath);
if(js_script==NULL) if(js_script==NULL)
...@@ -979,6 +994,8 @@ void DLLCALL services_thread(void* arg) ...@@ -979,6 +994,8 @@ void DLLCALL services_thread(void* arg)
socklen_t client_addr_len; socklen_t client_addr_len;
SOCKET socket; SOCKET socket;
SOCKET client_socket; SOCKET client_socket;
BYTE* udp_buf = NULL;
int udp_len;
int i; int i;
int result; int result;
ulong total_clients; ulong total_clients;
...@@ -1093,7 +1110,9 @@ void DLLCALL services_thread(void* arg) ...@@ -1093,7 +1110,9 @@ void DLLCALL services_thread(void* arg)
service[i].socket=INVALID_SOCKET; service[i].socket=INVALID_SOCKET;
if((socket = open_socket(SOCK_STREAM))==INVALID_SOCKET) { if((socket = open_socket(
(service[i].options&SERVICE_OPT_UDP) ? SOCK_DGRAM : SOCK_STREAM))
==INVALID_SOCKET) {
lprintf("!ERROR %d opening socket", ERROR_VALUE); lprintf("!ERROR %d opening socket", ERROR_VALUE);
cleanup(1); cleanup(1);
return; return;
...@@ -1117,14 +1136,18 @@ void DLLCALL services_thread(void* arg) ...@@ -1117,14 +1136,18 @@ void DLLCALL services_thread(void* arg)
continue; continue;
} }
lprintf("%04d %s socket bound to port %u" lprintf("%04d %s socket bound to %s port %u"
,socket, service[i].protocol, service[i].port); ,socket, service[i].protocol
,service[i].options&SERVICE_OPT_UDP ? "UDP" : "TCP"
,service[i].port);
if(listen(socket,10)!=0) { if(!(service[i].options&SERVICE_OPT_UDP)) {
lprintf("%04d !ERROR %d listening on %s socket" if(listen(socket,10)!=0) {
,socket, ERROR_VALUE, service[i].protocol); lprintf("%04d !ERROR %d listening on %s socket"
close_socket(socket); ,socket, ERROR_VALUE, service[i].protocol);
continue; close_socket(socket);
continue;
}
} }
service[i].socket=socket; service[i].socket=socket;
total_sockets++; total_sockets++;
...@@ -1205,15 +1228,61 @@ void DLLCALL services_thread(void* arg) ...@@ -1205,15 +1228,61 @@ void DLLCALL services_thread(void* arg)
continue; continue;
client_addr_len = sizeof(client_addr); client_addr_len = sizeof(client_addr);
if((client_socket=accept(service[i].socket,
(struct sockaddr *)&client_addr,&client_addr_len))==INVALID_SOCKET) { if(service[i].options&SERVICE_OPT_UDP) {
if(ERROR_VALUE == ENOTSOCK) /* UDP */
lprintf("%04d %s socket closed while listening" if((udp_buf = (BYTE*)calloc(1, MAX_UDP_BUF_LEN)) == NULL) {
,service[i].socket, service[i].protocol); lprintf("%04d %s !ERROR %d allocating UDP buffer"
else ,service[i].socket, service[i].protocol, errno);
lprintf("%04d %s !ERROR %d accept failed", break;
service[i].socket, service[i].protocol, ERROR_VALUE); }
break;
udp_len = recvfrom(service[i].socket
,udp_buf, MAX_UDP_BUF_LEN, 0 /* flags */
,(struct sockaddr *)&client_addr, &client_addr_len);
if(udp_len<1) {
FREE_AND_NULL(udp_buf);
lprintf("%04d %s !ERROR %d recvfrom failed"
,service[i].socket, service[i].protocol, ERROR_VALUE);
break;
}
if((client_socket = open_socket(SOCK_DGRAM))
==INVALID_SOCKET) {
FREE_AND_NULL(udp_buf);
lprintf("%04d %s !ERROR %d opening socket"
,service[i].socket, service[i].protocol, ERROR_VALUE);
break;
}
/* Set client address as default addres for send/recv */
if(connect(client_socket
,(struct sockaddr *)&client_addr, client_addr_len)!=0) {
FREE_AND_NULL(udp_buf);
lprintf("%04d %s !ERROR %d connect failed"
,client_socket, service[i].protocol, ERROR_VALUE);
break;
}
#if 0
if(send(client_socket,"test\r\n",6,0)!=6) {
FREE_AND_NULL(udp_buf);
lprintf("%04d %s !SEND TEST ERROR %d"
,client_socket, service[i].protocol, ERROR_VALUE);
break;
}
#endif
} else {
/* TCP */
if((client_socket=accept(service[i].socket
,(struct sockaddr *)&client_addr, &client_addr_len))==INVALID_SOCKET) {
if(ERROR_VALUE == ENOTSOCK)
lprintf("%04d %s socket closed while listening"
,service[i].socket, service[i].protocol);
else
lprintf("%04d %s !ERROR %d accept failed"
,service[i].socket, service[i].protocol, ERROR_VALUE);
break;
}
} }
strcpy(host_ip,inet_ntoa(client_addr.sin_addr)); strcpy(host_ip,inet_ntoa(client_addr.sin_addr));
...@@ -1236,6 +1305,7 @@ void DLLCALL services_thread(void* arg) ...@@ -1236,6 +1305,7 @@ void DLLCALL services_thread(void* arg)
#endif #endif
if(trashcan(&scfg,host_ip,"ip")) { if(trashcan(&scfg,host_ip,"ip")) {
FREE_AND_NULL(udp_buf);
lprintf("%04d !%s CLIENT BLOCKED in ip.can: %s" lprintf("%04d !%s CLIENT BLOCKED in ip.can: %s"
,client_socket, service[i].protocol, host_ip); ,client_socket, service[i].protocol, host_ip);
mswait(3000); mswait(3000);
...@@ -1244,6 +1314,7 @@ void DLLCALL services_thread(void* arg) ...@@ -1244,6 +1314,7 @@ void DLLCALL services_thread(void* arg)
} }
if((client=malloc(sizeof(service_client_t)))==NULL) { if((client=malloc(sizeof(service_client_t)))==NULL) {
FREE_AND_NULL(udp_buf);
lprintf("%04d !%s ERROR allocating %u bytes of memory for service_client" lprintf("%04d !%s ERROR allocating %u bytes of memory for service_client"
,client_socket, service[i].protocol, sizeof(service_client_t)); ,client_socket, service[i].protocol, sizeof(service_client_t));
mswait(3000); mswait(3000);
...@@ -1259,6 +1330,10 @@ void DLLCALL services_thread(void* arg) ...@@ -1259,6 +1330,10 @@ void DLLCALL services_thread(void* arg)
client->addr=client_addr; client->addr=client_addr;
client->service=&service[i]; client->service=&service[i];
client->service->clients++; /* this should be mutually exclusive */ client->service->clients++; /* this should be mutually exclusive */
client->udp_buf=udp_buf;
client->udp_len=udp_len;
udp_buf = NULL;
SAFECOPY(cmd,service[i].cmd); SAFECOPY(cmd,service[i].cmd);
strlwr(cmd); strlwr(cmd);
......
...@@ -81,6 +81,9 @@ typedef struct { ...@@ -81,6 +81,9 @@ typedef struct {
} services_startup_t; } services_startup_t;
/* Option bit definitions */
#define SERVICE_OPT_UDP (1<<0) /* UDP Socket */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment