From c1cf00d86a4a3f5de170f968077f5b1e80b6b482 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Mon, 22 Jan 2018 10:25:54 +0100 Subject: [PATCH] qcommon: Add Ouroboros support (experimental) This adds support for the Ouroboros IPC subsystem. This patch was written by Dimitri Staessens Sander Vrijders Addy Bombeke --- Makefile | 6 ++ code/client/cl_main.c | 6 +- code/qcommon/net_chan.c | 6 ++ code/qcommon/net_ip.c | 27 +++++++- code/qcommon/net_ouroboros.c | 144 +++++++++++++++++++++++++++++++++++++++++++ code/qcommon/net_ouroboros.h | 46 ++++++++++++++ code/qcommon/qcommon.h | 4 +- 7 files changed, 234 insertions(+), 5 deletions(-) create mode 100644 code/qcommon/net_ouroboros.c create mode 100644 code/qcommon/net_ouroboros.h diff --git a/Makefile b/Makefile index 4aa9f519..12da9fde 100644 --- a/Makefile +++ b/Makefile @@ -1645,6 +1645,7 @@ Q3OBJ = \ $(B)/client/msg.o \ $(B)/client/net_chan.o \ $(B)/client/net_ip.o \ + $(B)/client/net_ouroboros.o \ $(B)/client/huffman.o \ \ $(B)/client/snd_adpcm.o \ @@ -2209,6 +2210,7 @@ Q3DOBJ = \ $(B)/ded/msg.o \ $(B)/ded/net_chan.o \ $(B)/ded/net_ip.o \ + $(B)/ded/net_ouroboros.o \ $(B)/ded/huffman.o \ \ $(B)/ded/q_math.o \ @@ -2943,3 +2945,7 @@ endif ifneq ($(findstring clean, $(MAKECMDGOALS)),) .NOTPARALLEL: endif + +#Ouroboros support +LIBS+="-louroboros-dev" +LIBS+="-lpthread" diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 82d0edfb..33a85f83 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -1697,7 +1697,7 @@ void CL_Connect_f( void ) { netadrtype_t family = NA_UNSPEC; if ( argc != 2 && argc != 3 ) { - Com_Printf( "usage: connect [-4|-6] server\n"); + Com_Printf( "usage: connect [-4|-6|-O] server\n"); return; } @@ -1709,8 +1709,10 @@ void CL_Connect_f( void ) { family = NA_IP; else if(!strcmp(Cmd_Argv(1), "-6")) family = NA_IP6; + else if(!strcmp(Cmd_Argv(1), "-O")) + family = NA_OUROBOROS; else - Com_Printf( "warning: only -4 or -6 as address type understood.\n"); + Com_Printf( "warning: only -4, -6 or -O as address type understood.\n"); Q_strncpyz( server, Cmd_Argv(2), sizeof( server ) ); } diff --git a/code/qcommon/net_chan.c b/code/qcommon/net_chan.c index 9e7d9b87..b0103cc3 100644 --- a/code/qcommon/net_chan.c +++ b/code/qcommon/net_chan.c @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "q_shared.h" #include "qcommon.h" +#include "net_ouroboros.h" /* @@ -638,6 +639,11 @@ int NET_StringToAdr( const char *s, netadr_t *a, netadrtype_t family ) return 1; } + if(family == NA_OUROBOROS) { + OUROBOROS_Resolve(s, a); + return 1; + } + Q_strncpyz( base, s, sizeof( base ) ); if(*base == '[' || Q_CountChar(base, ':') > 1) diff --git a/code/qcommon/net_ip.c b/code/qcommon/net_ip.c index bcccda20..1bcce311 100644 --- a/code/qcommon/net_ip.c +++ b/code/qcommon/net_ip.c @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "../qcommon/q_shared.h" #include "../qcommon/qcommon.h" +#include "net_ouroboros.h" #ifdef _WIN32 # include @@ -392,6 +393,9 @@ qboolean NET_CompareBaseAdrMask(netadr_t a, netadr_t b, int netmask) byte cmpmask, *addra, *addrb; int curbyte; + if (a.type == NA_OUROBOROS && b.type == NA_OUROBOROS) + return a.fd == b.fd ? qtrue : qfalse; + if (a.type != b.type) return qfalse; @@ -495,6 +499,9 @@ qboolean NET_CompareAdr (netadr_t a, netadr_t b) if(!NET_CompareBaseAdr(a, b)) return qfalse; + if (a.type == NA_OUROBOROS && b.type == NA_OUROBOROS) + return a.fd == b.fd ? qtrue :qfalse; + if (a.type == NA_IP || a.type == NA_IP6) { if (a.port == b.port) @@ -627,6 +634,9 @@ qboolean NET_GetPacket(netadr_t *net_from, msg_t *net_message, fd_set *fdr) } } + ret = OUROBOROS_Recvfrom(net_message, net_from); + if (ret > 0) + return qtrue; return qfalse; } @@ -644,6 +654,11 @@ void Sys_SendPacket( int length, const void *data, netadr_t to ) { int ret = SOCKET_ERROR; struct sockaddr_storage addr; + if (to.type == NA_OUROBOROS) { + OUROBOROS_Sendto(length, data, &to); + return; + } + if( to.type != NA_BROADCAST && to.type != NA_IP && to.type != NA_IP6 && to.type != NA_MULTICAST6) { Com_Error( ERR_FATAL, "Sys_SendPacket: bad address type" ); @@ -1585,8 +1600,14 @@ void NET_Init( void ) { #endif NET_Config( qtrue ); - + Cmd_AddCommand ("net_restart", NET_Restart_f); + +#ifdef DEDICATED + OUROBOROS_Init(1); +#else + OUROBOROS_Init(0); +#endif } @@ -1602,6 +1623,8 @@ void NET_Shutdown( void ) { NET_Config( qfalse ); + OUROBOROS_Fini(); + #ifdef _WIN32 WSACleanup(); winsockInitialized = qfalse; @@ -1694,7 +1717,7 @@ void NET_Sleep(int msec) if(retval == SOCKET_ERROR) Com_Printf("Warning: select() syscall failed: %s\n", NET_ErrorString()); - else if(retval > 0) + else NET_Event(&fdr); } diff --git a/code/qcommon/net_ouroboros.c b/code/qcommon/net_ouroboros.c new file mode 100644 index 00000000..ee98a2e0 --- /dev/null +++ b/code/qcommon/net_ouroboros.c @@ -0,0 +1,144 @@ +/* + * Ouroboros calls for ioq3 + * + * Addy Bombeke + * Sander Vrijders + * Dimitri Staessens + * + * Copyright (C) 2015 - 2018 + * + * Modified from software originally written as part of the MSc + * thesis in electrical engineering, + * + * "Comparing RINA to TCP/IP for latency-constrained applications", + * + * at Ghent University, Academic Year 2014-2015 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "net_ouroboros.h" + +#include +#include +#include +#include + +#include +#include + +fset_t * flows; +fqueue_t * fq; + +void OUROBOROS_Resolve(const char * s, netadr_t * a) +{ + int fd; + + a->type = NA_OUROBOROS; + + fd = flow_alloc(s, NULL, NULL); + if (fd < 0) { + printf("Failed to allocate flow.\n"); + return; + } + + fset_add(flows, fd); + + a->fd = fd; +} + +void OUROBOROS_Sendto(int length, const void * data, netadr_t * to) +{ + flow_write(to->fd, (void *) data, length); +} + +int OUROBOROS_Recvfrom(msg_t * msg, netadr_t * from) +{ + int fd; + ssize_t count = 0; + struct timespec timeout = {0, 0}; + + fevent(flows, fq, &timeout); + + if ((fd = fqueue_next(fq)) >= 0) { + count = flow_read(fd, msg->data, msg->maxsize); + if (count < 0) + return 0; + + if (count > msg->maxsize) { + printf("Oversized packet received.\n"); + return 0; + } + + from->type = NA_OUROBOROS; + from->fd = fd; + msg->cursize = count; + msg->readcount = 0; + + return count; + } + + return 0; +} + +static void * OUROBOROS_Server_Accept(void * o) +{ + int fd; + + (void) o; + + for (;;) { + fd = flow_accept(NULL, NULL); + if (fd < 0) { + printf("Failed to accept flow.\n"); + continue; + } + + fset_add(flows, fd); + } + + return (void *) 0; +} + +void OUROBOROS_Init(int server) +{ + pthread_t accept_thread; + + flows = fset_create(); + if (flows == NULL) { + printf("Failed to create flow set.\n"); + return; + } + + fq = fqueue_create(); + if (fq == NULL) { + printf("Failed to create flow queue.\n"); + return; + } + + if (server) { + pthread_create(&accept_thread, + NULL, + OUROBOROS_Server_Accept, + NULL); + pthread_detach(accept_thread); + } +} + +void OUROBOROS_Fini(void) +{ + fqueue_destroy(fq); + fset_destroy(flows); +} diff --git a/code/qcommon/net_ouroboros.h b/code/qcommon/net_ouroboros.h new file mode 100644 index 00000000..5f85987e --- /dev/null +++ b/code/qcommon/net_ouroboros.h @@ -0,0 +1,46 @@ +/* + * Ouroboros calls for ioq3 + * + * Addy Bombeke + * Sander Vrijders + * Dimitri Staessens + * + * Copyright (C) 2015 - 2018 + * + * Modified from software originally written as part of the MSc + * thesis in electrical engineering, + * + * "Comparing RINA to TCP/IP for latency-constrained applications", + * + * at Ghent University, Academic Year 2014-2015 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef NET_OUROBOROS_H +#define NET_OUROBOROS_H + +#include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" + +void OUROBOROS_Init(int server); +void OUROBOROS_Fini(void); + +void OUROBOROS_Resolve(const char * s, netadr_t * a); + +int OUROBOROS_Recvfrom(msg_t * msg, netadr_t * from); +void OUROBOROS_Sendto(int length, const void * data, netadr_t * to); + +#endif /*NET_OUROBOROS_H */ diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index 4471198c..eff5472f 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -147,7 +147,8 @@ typedef enum { NA_IP, NA_IP6, NA_MULTICAST6, - NA_UNSPEC + NA_UNSPEC, + NA_OUROBOROS } netadrtype_t; typedef enum { @@ -164,6 +165,7 @@ typedef struct { unsigned short port; unsigned long scope_id; // Needed for IPv6 link-local addresses + int fd; // Needed for Ouroboros support } netadr_t; void NET_Init( void ); -- 2.16.0