mirror of
https://github.com/bdnugget/nbnet.git
synced 2026-11-07 05:27:27 +00:00
remove encryption support from core library (#59)
remove encryption support from the core library
This commit is contained in:
1 parent
ac9405445d
commit
32b1b62781
16 files changed
+66
-2714
No files matched your search
@@ -24,21 +24,14 @@ If you want to discuss the library or need help, join the [nbnet's discord serve
|
||||
|
||||
- Connection management
|
||||
- Sending/Receiving both reliable ordered and unreliable ordered messages
|
||||
- Sending/Receiving messages larger than the MTU (using nbnet's message fragmentation)
|
||||
- Sending/Receiving messages larger than the MTU through nbnet's message fragmentation system
|
||||
- Bit-level serialization (for bandwidth optimization): integers (signed and unsigned), floats, booleans, and byte arrays
|
||||
- Network conditions simulation: ping, jitter, packet loss, packet duplication, and out-of-order packets)
|
||||
- Network statistics: ping, bandwidth (upload and download) and packet loss
|
||||
- Web (WebRTC) support (both natively and through WASM using [emscripten](https://emscripten.org/docs/introducing_emscripten/about_emscripten.html))
|
||||
- Encrypted and authenticated packets
|
||||
|
||||
## Thanks
|
||||
|
||||
nbnet encryption and packet authentication use the following open-source libraries:
|
||||
|
||||
- [tiny-ECDH](https://github.com/kokke/tiny-ECDH-c)
|
||||
- [tiny-AES](https://github.com/kokke/tiny-AES-c)
|
||||
- [poly1305-donna](https://github.com/floodyberry/poly1305-donna)
|
||||
|
||||
the native WebRTC driver relies on:
|
||||
|
||||
- [libdatachannel](https://github.com/paullouisageneau/libdatachannel)
|
||||
@@ -85,7 +78,7 @@ A driver is a set of function definitions that live outside the nbnet header and
|
||||
nbnet comes with three ready-to-use drivers:
|
||||
|
||||
- UDP: works with a single UDP socket, designed for desktop games
|
||||
- WebRTC (WASM): works with a single unreliable/unordered data channel, implemented in JS using emscripten API
|
||||
- WebRTC (WASM): works with a single unreliable/unordered data channel, implemented in JS using the emscripten API
|
||||
- WebRTC (Native): works the same way as the WASM WebRTC driver but can be natively compiled
|
||||
|
||||
## How to use
|
||||
|
||||
@@ -157,15 +157,10 @@ int main(int argc, char *argv[])
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
// Initialize the client
|
||||
#ifdef NBN_ENCRYPTION
|
||||
bool enable_encryption = true;
|
||||
#else
|
||||
bool enable_encryption = false;
|
||||
#endif
|
||||
|
||||
// Start the client with a protocol name (must be the same than the one used by the server)
|
||||
// the server host and port and with packet encryption on or off
|
||||
if (NBN_GameClient_StartEx(ECHO_PROTOCOL_NAME, "127.0.0.1", ECHO_EXAMPLE_PORT, enable_encryption, NULL, 0) < 0)
|
||||
if (NBN_GameClient_StartEx(ECHO_PROTOCOL_NAME, "127.0.0.1", ECHO_EXAMPLE_PORT, NULL, 0) < 0)
|
||||
{
|
||||
Log(LOG_ERROR, "Failed to start client");
|
||||
|
||||
|
||||
@@ -112,14 +112,8 @@ int main(int argc, const char **argv)
|
||||
NBN_UDP_Register(); // Register the UDP driver
|
||||
#endif
|
||||
|
||||
#ifdef NBN_ENCRYPTION
|
||||
bool enable_encryption = true;
|
||||
#else
|
||||
bool enable_encryption = false;
|
||||
#endif
|
||||
|
||||
// Start the server with a protocol name, a port, and with packet encryption on or off
|
||||
if (NBN_GameServer_StartEx(ECHO_PROTOCOL_NAME, ECHO_EXAMPLE_PORT, enable_encryption) < 0)
|
||||
if (NBN_GameServer_StartEx(ECHO_PROTOCOL_NAME, ECHO_EXAMPLE_PORT) < 0)
|
||||
{
|
||||
Log(LOG_ERROR, "Failed to start the server");
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ add_compile_options(-Wall -Wextra -Wpedantic)
|
||||
target_compile_definitions(echo_bytes_client PUBLIC NBN_DEBUG)
|
||||
target_compile_definitions(echo_bytes_server PUBLIC NBN_DEBUG)
|
||||
|
||||
option(ENCRYPTION_ENABLED OFF)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(echo_bytes_client wsock32 ws2_32)
|
||||
target_link_libraries(echo_bytes_server wsock32 ws2_32)
|
||||
|
||||
@@ -64,7 +64,7 @@ int main(void)
|
||||
NBN_UDP_Register(); // Register the UDP driver
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
// Start the server with a protocol name, a port, and with packet encryption on or off
|
||||
// Start the server with a protocol name and a port
|
||||
if (NBN_GameServer_Start(ECHO_PROTOCOL_NAME, ECHO_EXAMPLE_PORT) < 0)
|
||||
{
|
||||
Log(LOG_ERROR, "Failed to start the server");
|
||||
|
||||
@@ -31,15 +31,6 @@ target_compile_definitions(raylib_client PUBLIC NBN_DEBUG)
|
||||
target_compile_definitions(raylib_server PUBLIC NBN_DEBUG)
|
||||
target_compile_definitions(raylib_server PUBLIC NBN_RAYLIB_SERVER)
|
||||
|
||||
if (ENCRYPTION_ENABLED)
|
||||
message("Encryption enabled")
|
||||
|
||||
target_compile_definitions(raylib_client PUBLIC EXAMPLE_ENCRYPTION)
|
||||
target_compile_definitions(raylib_server PUBLIC EXAMPLE_ENCRYPTION)
|
||||
endif(ENCRYPTION_ENABLED)
|
||||
|
||||
unset(ENCRYPTION_ENABLED)
|
||||
|
||||
# compile with C WebRTC driver
|
||||
if (WEBRTC_C_DRIVER)
|
||||
# can't compile WebRTC native driver with emscripten
|
||||
|
||||
@@ -517,15 +517,10 @@ int main(int argc, char *argv[])
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
// Initialize the client with a protocol name (must be the same than the one used by the server), the server ip address and port
|
||||
#ifdef EXAMPLE_ENCRYPTION
|
||||
bool enable_encryption = true;
|
||||
#else
|
||||
bool enable_encryption = false;
|
||||
#endif
|
||||
|
||||
// Start the client with a protocol name (must be the same than the one used by the server)
|
||||
// the server host and port and with packet encryption on or off
|
||||
if (NBN_GameClient_StartEx(RAYLIB_EXAMPLE_PROTOCOL_NAME, "127.0.0.1", RAYLIB_EXAMPLE_PORT, enable_encryption, NULL, 0) < 0)
|
||||
// the server host and port
|
||||
if (NBN_GameClient_StartEx(RAYLIB_EXAMPLE_PROTOCOL_NAME, "127.0.0.1", RAYLIB_EXAMPLE_PORT, NULL, 0) < 0)
|
||||
{
|
||||
TraceLog(LOG_WARNING, "Game client failed to start. Exit");
|
||||
|
||||
|
||||
@@ -322,14 +322,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
#ifdef EXAMPLE_ENCRYPTION
|
||||
bool enable_encryption = true;
|
||||
#else
|
||||
bool enable_encryption = false;
|
||||
#endif
|
||||
|
||||
// Start the server with a protocol name, a port, and with packet encryption on or off
|
||||
if (NBN_GameServer_StartEx(RAYLIB_EXAMPLE_PROTOCOL_NAME, RAYLIB_EXAMPLE_PORT, enable_encryption) < 0)
|
||||
// Start the server with a protocol name and a port
|
||||
if (NBN_GameServer_StartEx(RAYLIB_EXAMPLE_PROTOCOL_NAME, RAYLIB_EXAMPLE_PORT) < 0)
|
||||
{
|
||||
TraceLog(LOG_ERROR, "Game server failed to start. Exit");
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ add_compile_options(-Wall -Wextra -Wpedantic)
|
||||
target_compile_definitions(rpc_client PUBLIC NBN_DEBUG)
|
||||
target_compile_definitions(rpc_server PUBLIC NBN_DEBUG)
|
||||
|
||||
option(ENCRYPTION_ENABLED OFF)
|
||||
option(WEBRTC_DRIVER_C OFF)
|
||||
|
||||
if(WIN32)
|
||||
|
||||
@@ -69,13 +69,8 @@ int main(int argc, char *argv[])
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
// Initialize the client with a protocol name (must be the same than the one used by the server), the server ip address and port
|
||||
#ifdef NBN_ENCRYPTION
|
||||
bool enable_encryption = true;
|
||||
#else
|
||||
bool enable_encryption = false;
|
||||
#endif
|
||||
|
||||
if (NBN_GameClient_StartEx(RPC_PROTOCOL_NAME, "127.0.0.1", RPC_EXAMPLE_PORT, enable_encryption, NULL, 0) < 0)
|
||||
if (NBN_GameClient_StartEx(RPC_PROTOCOL_NAME, "127.0.0.1", RPC_EXAMPLE_PORT, NULL, 0) < 0)
|
||||
{
|
||||
Log(LOG_ERROR, "Failed to start client");
|
||||
|
||||
|
||||
@@ -55,13 +55,7 @@ int main(void)
|
||||
NBN_UDP_Register(); // Register the UDP driver
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
#ifdef NBN_ENCRYPTION
|
||||
bool enable_encryption = true;
|
||||
#else
|
||||
bool enable_encryption = false;
|
||||
#endif
|
||||
|
||||
if (NBN_GameServer_StartEx(RPC_PROTOCOL_NAME, RPC_EXAMPLE_PORT, enable_encryption) < 0)
|
||||
if (NBN_GameServer_StartEx(RPC_PROTOCOL_NAME, RPC_EXAMPLE_PORT) < 0)
|
||||
{
|
||||
Log(LOG_ERROR, "Failed to start the server");
|
||||
|
||||
|
||||
@@ -1,488 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2024 BIAGINI Nathan
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
--- NBNET IPC DRIVER ---
|
||||
|
||||
IPC driver for the nbnet library.
|
||||
|
||||
IMPORTANT: This driver uses UNXI domain sockets for inter processes communication and therefore is not portable.
|
||||
|
||||
How to use:
|
||||
|
||||
1. Include this header *once* after the nbnet header in the same file where you defined the NBNET_IMPL macro
|
||||
2. Call NBN_IPC_Register in both your client and server code before calling NBN_GameClient_Start or NBN_GameServer_Start
|
||||
*/
|
||||
|
||||
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
|
||||
!(defined(__APPLE__) && defined(__MACH__))
|
||||
#error "The IPC driver can only be used on UNIX systems"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Register the driver to nbnet.
|
||||
*
|
||||
* @param sock_path Path of the UNIX socket
|
||||
*/
|
||||
void NBN_IPC_Register(const char *sock_path);
|
||||
|
||||
#ifdef NBNET_IMPL
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define NBN_IPC_DRIVER_ID 2
|
||||
#define NBN_IPC_DRIVER_NAME "IPC"
|
||||
// IPC messages have a 4 bytes header to store the connection id
|
||||
#define NBN_IPC_HEADER_SIZE 4
|
||||
#define NBN_IPC_BUFFER_SIZE NBN_IPC_HEADER_SIZE + NBN_PACKET_MAX_SIZE
|
||||
|
||||
#pragma region Hashtable
|
||||
|
||||
#define HTABLE_DEFAULT_INITIAL_CAPACITY 32
|
||||
#define HTABLE_LOAD_FACTOR_THRESHOLD 0.75
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t id;
|
||||
NBN_Connection *conn;
|
||||
} NBN_IPC_Connection;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t conn_id;
|
||||
unsigned int slot;
|
||||
NBN_IPC_Connection *conn;
|
||||
} NBN_IPC_HTableEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NBN_IPC_HTableEntry **internal_array;
|
||||
unsigned int capacity;
|
||||
unsigned int count;
|
||||
float load_factor;
|
||||
} NBN_IPC_HTable;
|
||||
|
||||
static NBN_IPC_HTable *NBN_IPC_HTable_Create(void);
|
||||
static NBN_IPC_HTable *NBN_IPC_HTable_CreateWithCapacity(unsigned int);
|
||||
static void NBN_IPC_HTable_Destroy(NBN_IPC_HTable *);
|
||||
static void NBN_IPC_HTable_Add(NBN_IPC_HTable *, uint32_t, NBN_IPC_Connection *);
|
||||
static NBN_IPC_Connection *NBN_IPC_HTable_Get(NBN_IPC_HTable *, uint32_t);
|
||||
static NBN_IPC_Connection *NBN_IPC_HTable_Remove(NBN_IPC_HTable *, uint32_t);
|
||||
static void NBN_IPC_HTable_InsertEntry(NBN_IPC_HTable *, NBN_IPC_HTableEntry *);
|
||||
static void NBN_IPC_HTable_RemoveEntry(NBN_IPC_HTable *, NBN_IPC_HTableEntry *);
|
||||
static unsigned int NBN_IPC_HTable_FindFreeSlot(NBN_IPC_HTable *, NBN_IPC_HTableEntry *, bool *);
|
||||
static NBN_IPC_HTableEntry *NBN_IPC_HTable_FindEntry(NBN_IPC_HTable *, uint32_t);
|
||||
static void NBN_IPC_HTable_Grow(NBN_IPC_HTable *);
|
||||
|
||||
static NBN_IPC_HTable *NBN_IPC_HTable_Create()
|
||||
{
|
||||
return NBN_IPC_HTable_CreateWithCapacity(HTABLE_DEFAULT_INITIAL_CAPACITY);
|
||||
}
|
||||
|
||||
static NBN_IPC_HTable *NBN_IPC_HTable_CreateWithCapacity(unsigned int capacity)
|
||||
{
|
||||
NBN_IPC_HTable *htable = NBN_Allocator(sizeof(NBN_IPC_HTable));
|
||||
|
||||
htable->internal_array = NBN_Allocator(sizeof(NBN_IPC_HTableEntry *) * capacity);
|
||||
htable->capacity = capacity;
|
||||
htable->count = 0;
|
||||
htable->load_factor = 0;
|
||||
|
||||
for (unsigned int i = 0; i < htable->capacity; i++)
|
||||
htable->internal_array[i] = NULL;
|
||||
|
||||
return htable;
|
||||
}
|
||||
|
||||
static void NBN_IPC_HTable_Destroy(NBN_IPC_HTable *htable)
|
||||
{
|
||||
for (unsigned int i = 0; i < htable->capacity; i++)
|
||||
{
|
||||
NBN_IPC_HTableEntry *entry = htable->internal_array[i];
|
||||
|
||||
if (entry)
|
||||
NBN_Deallocator(entry);
|
||||
}
|
||||
|
||||
NBN_Deallocator(htable->internal_array);
|
||||
NBN_Deallocator(htable);
|
||||
}
|
||||
|
||||
static void NBN_IPC_HTable_Add(NBN_IPC_HTable *htable, uint32_t conn_id, NBN_IPC_Connection *conn)
|
||||
{
|
||||
NBN_IPC_HTableEntry *entry = NBN_Allocator(sizeof(NBN_IPC_HTableEntry));
|
||||
|
||||
entry->conn_id = conn_id;
|
||||
entry->conn = conn;
|
||||
|
||||
NBN_IPC_HTable_InsertEntry(htable, entry);
|
||||
|
||||
if (htable->load_factor >= HTABLE_LOAD_FACTOR_THRESHOLD)
|
||||
NBN_IPC_HTable_Grow(htable);
|
||||
}
|
||||
|
||||
static NBN_IPC_Connection *NBN_IPC_HTable_Get(NBN_IPC_HTable *htable, uint32_t conn_id)
|
||||
{
|
||||
NBN_IPC_HTableEntry *entry = NBN_IPC_HTable_FindEntry(htable, conn_id);
|
||||
|
||||
return entry ? entry->conn : NULL;
|
||||
}
|
||||
|
||||
static NBN_IPC_Connection *NBN_IPC_HTable_Remove(NBN_IPC_HTable *htable, uint32_t conn_id)
|
||||
{
|
||||
NBN_IPC_HTableEntry *entry = NBN_IPC_HTable_FindEntry(htable, conn_id);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
NBN_IPC_HTable_RemoveEntry(htable, entry);
|
||||
|
||||
return entry->conn;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void NBN_IPC_HTable_InsertEntry(NBN_IPC_HTable *htable, NBN_IPC_HTableEntry *entry)
|
||||
{
|
||||
bool use_existing_slot = false;
|
||||
unsigned int slot = NBN_IPC_HTable_FindFreeSlot(htable, entry, &use_existing_slot);
|
||||
|
||||
entry->slot = slot;
|
||||
htable->internal_array[slot] = entry;
|
||||
|
||||
if (!use_existing_slot)
|
||||
{
|
||||
htable->count++;
|
||||
htable->load_factor = (float)htable->count / htable->capacity;
|
||||
}
|
||||
}
|
||||
|
||||
static void NBN_IPC_HTable_RemoveEntry(NBN_IPC_HTable *htable, NBN_IPC_HTableEntry *entry)
|
||||
{
|
||||
htable->internal_array[entry->slot] = NULL;
|
||||
|
||||
NBN_Deallocator(entry);
|
||||
|
||||
htable->count--;
|
||||
htable->load_factor = htable->count / htable->capacity;
|
||||
}
|
||||
|
||||
static unsigned int NBN_IPC_HTable_FindFreeSlot(NBN_IPC_HTable *htable, NBN_IPC_HTableEntry *entry, bool *use_existing_slot)
|
||||
{
|
||||
unsigned long hash = entry->conn_id;
|
||||
unsigned int slot;
|
||||
|
||||
// quadratic probing
|
||||
|
||||
NBN_IPC_HTableEntry *current_entry;
|
||||
unsigned int i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
slot = (hash + (int)pow(i, 2)) % htable->capacity;
|
||||
current_entry = htable->internal_array[slot];
|
||||
|
||||
i++;
|
||||
} while (current_entry != NULL && current_entry->conn_id != entry->conn_id);
|
||||
|
||||
if (current_entry != NULL) // it means the current entry as the same key as the inserted entry
|
||||
{
|
||||
*use_existing_slot = true;
|
||||
|
||||
NBN_Deallocator(current_entry);
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
static NBN_IPC_HTableEntry *NBN_IPC_HTable_FindEntry(NBN_IPC_HTable *htable, uint32_t conn_id)
|
||||
{
|
||||
unsigned long hash = conn_id;
|
||||
unsigned int slot;
|
||||
|
||||
//quadratic probing
|
||||
|
||||
NBN_IPC_HTableEntry *current_entry;
|
||||
unsigned int i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
slot = (hash + (int)pow(i, 2)) % htable->capacity;
|
||||
current_entry = htable->internal_array[slot];
|
||||
|
||||
if (current_entry != NULL && current_entry->conn_id == conn_id)
|
||||
{
|
||||
return current_entry;
|
||||
}
|
||||
|
||||
i++;
|
||||
} while (i < htable->capacity);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void NBN_IPC_HTable_Grow(NBN_IPC_HTable *htable)
|
||||
{
|
||||
unsigned int old_capacity = htable->capacity;
|
||||
unsigned int new_capacity = old_capacity * 2;
|
||||
NBN_IPC_HTableEntry** old_internal_array = htable->internal_array;
|
||||
NBN_IPC_HTableEntry** new_internal_array = NBN_Allocator(sizeof(NBN_IPC_HTableEntry*) * new_capacity);
|
||||
|
||||
for (unsigned int i = 0; i < new_capacity; i++)
|
||||
{
|
||||
new_internal_array[i] = NULL;
|
||||
}
|
||||
|
||||
htable->internal_array = new_internal_array;
|
||||
htable->capacity = new_capacity;
|
||||
htable->count = 0;
|
||||
htable->load_factor = 0;
|
||||
|
||||
// rehash
|
||||
|
||||
for (unsigned int i = 0; i < old_capacity; i++)
|
||||
{
|
||||
if (old_internal_array[i])
|
||||
NBN_IPC_HTable_InsertEntry(htable, old_internal_array[i]);
|
||||
}
|
||||
|
||||
NBN_Deallocator(old_internal_array);
|
||||
}
|
||||
|
||||
#pragma endregion // Hashtable
|
||||
|
||||
#pragma region Game server
|
||||
|
||||
static int unix_sock, unix_sock2;
|
||||
static struct sockaddr_un unix_sock_addr;
|
||||
static const char *unix_sock_path;
|
||||
static NBN_IPC_HTable *nbn_fifo_connections = NULL;
|
||||
|
||||
static NBN_Connection *FindOrCreateClientConnectionById(uint32_t id);
|
||||
|
||||
static int NBN_IPC_ServStart(uint32_t proto_id, uint16_t port)
|
||||
{
|
||||
if ((unix_sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
NBN_LogError("socket() faied: %s", strerror(errno));
|
||||
return NBN_ERROR;
|
||||
}
|
||||
|
||||
if ((unix_sock2 = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
NBN_LogError("socket() faied: %s", strerror(errno));
|
||||
return NBN_ERROR;
|
||||
}
|
||||
|
||||
memset(&unix_sock_addr, 0, sizeof(unix_sock_addr));
|
||||
unix_sock_addr.sun_family = AF_UNIX;
|
||||
strncpy(unix_sock_addr.sun_path, unix_sock_path, sizeof(unix_sock_addr.sun_path) - 1);
|
||||
unlink(unix_sock_path);
|
||||
|
||||
if (bind(unix_sock, (SOCKADDR *)&unix_sock_addr, sizeof(unix_sock_addr)) < 0)
|
||||
{
|
||||
NBN_LogError("bind() failed: %s", strerror(errno));
|
||||
return NBN_ERROR;
|
||||
}
|
||||
|
||||
if (fcntl(unix_sock, F_SETFL, O_NONBLOCK, 1) < 0)
|
||||
{
|
||||
NBN_LogError("fcntl() failed: %s", strerror(errno));
|
||||
return NBN_ERROR;
|
||||
}
|
||||
|
||||
if (fcntl(unix_sock2, F_SETFL, O_NONBLOCK, 1) < 0)
|
||||
{
|
||||
NBN_LogError("fcntl() failed: %s", strerror(errno));
|
||||
return NBN_ERROR;
|
||||
}
|
||||
|
||||
protocol_id = proto_id;
|
||||
nbn_fifo_connections = NBN_IPC_HTable_Create();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void NBN_IPC_ServStop(void)
|
||||
{
|
||||
close(unix_sock);
|
||||
NBN_IPC_HTable_Destroy(nbn_fifo_connections);
|
||||
}
|
||||
|
||||
static int NBN_IPC_ServRecvPackets(void)
|
||||
{
|
||||
uint8_t buffer[NBN_IPC_BUFFER_SIZE] = {0};
|
||||
|
||||
while (true)
|
||||
{
|
||||
int bytes = recvfrom(unix_sock, (char *)buffer, sizeof(buffer), 0, NULL, NULL);
|
||||
|
||||
if (bytes <= 0)
|
||||
break;
|
||||
|
||||
// datagrams should have a valid header followed by the nbnet packet data
|
||||
if (bytes <= NBN_IPC_HEADER_SIZE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start by reading the connection id from the IPC message header
|
||||
uint32_t conn_id =
|
||||
((uint32_t)buffer[0] << 24) +
|
||||
((uint32_t)buffer[1] << 16) +
|
||||
((uint32_t)buffer[2] << 8) +
|
||||
(uint32_t)buffer[3];
|
||||
|
||||
// Then read and process the actual nbnet packet
|
||||
uint8_t *packet_buffer = buffer + NBN_IPC_HEADER_SIZE;
|
||||
unsigned int packet_bytes = bytes - NBN_IPC_HEADER_SIZE;
|
||||
|
||||
if (NBN_Packet_ReadProtocolId(packet_buffer, packet_bytes) != protocol_id)
|
||||
continue; // not matching the protocol of the receiver
|
||||
|
||||
NBN_Connection *conn = FindOrCreateClientConnectionById(conn_id);
|
||||
|
||||
if (conn == NULL)
|
||||
continue; // skip the connection
|
||||
|
||||
NBN_Packet packet;
|
||||
|
||||
if (NBN_Packet_InitRead(&packet, conn, packet_buffer, packet_bytes) < 0)
|
||||
continue; /* not a valid packet */
|
||||
|
||||
if (NBN_Driver_RaiseEvent(NBN_DRIVER_SERV_CLIENT_PACKET_RECEIVED, &packet) < 0)
|
||||
{
|
||||
NBN_LogError("Failed to raise game server event");
|
||||
|
||||
return NBN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void NBN_IPC_ServRemoveClientConnection(NBN_Connection *connection)
|
||||
{
|
||||
assert(connection != NULL);
|
||||
|
||||
NBN_IPC_Connection *fifo_conn = NBN_IPC_HTable_Remove(nbn_fifo_connections, ((NBN_IPC_Connection *)connection->driver_data)->id);
|
||||
|
||||
if (fifo_conn)
|
||||
{
|
||||
NBN_LogDebug("Destroyed IPC connection %d", connection->id);
|
||||
|
||||
NBN_Deallocator(fifo_conn);
|
||||
|
||||
// TODO: notify removed connection to other service
|
||||
}
|
||||
}
|
||||
|
||||
static int NBN_IPC_ServSendPacketTo(NBN_Packet *packet, NBN_Connection *connection)
|
||||
{
|
||||
NBN_IPC_Connection *fifo_conn = (NBN_IPC_Connection *)connection->driver_data;
|
||||
uint8_t buffer[NBN_IPC_BUFFER_SIZE];
|
||||
unsigned int bytes = 0;
|
||||
|
||||
memcpy(buffer, &fifo_conn->id, NBN_IPC_HEADER_SIZE);
|
||||
bytes += NBN_IPC_HEADER_SIZE;
|
||||
memcpy(buffer + NBN_IPC_HEADER_SIZE, packet->buffer, packet->size);
|
||||
bytes += packet->size;
|
||||
|
||||
NBN_LogDebug("SEND: %s", unix_sock_addr.sun_path);
|
||||
if (sendto(unix_sock2, (const char *)buffer, bytes, 0, (SOCKADDR *)&unix_sock_addr, sizeof(unix_sock_addr)) == SOCKET_ERROR)
|
||||
{
|
||||
NBN_LogError("sendto() failed: %s", strerror(errno));
|
||||
|
||||
return NBN_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NBN_Connection *FindOrCreateClientConnectionById(uint32_t id)
|
||||
{
|
||||
NBN_IPC_Connection *fifo_conn = NBN_IPC_HTable_Get(nbn_fifo_connections, id);
|
||||
|
||||
if (fifo_conn == NULL)
|
||||
{
|
||||
/* this is a new connection */
|
||||
|
||||
if (GameServer_GetClientCount() >= NBN_MAX_CLIENTS)
|
||||
return NULL;
|
||||
|
||||
fifo_conn = (NBN_IPC_Connection *)NBN_Allocator(sizeof(NBN_IPC_Connection));
|
||||
|
||||
fifo_conn->id = id;
|
||||
fifo_conn->conn = NBN_GameServer_CreateClientConnection(fifo_conn->id, NBN_IPC_DRIVER_ID, fifo_conn, id);
|
||||
|
||||
NBN_IPC_HTable_Add(nbn_fifo_connections, id, fifo_conn);
|
||||
|
||||
NBN_LogDebug("New UDP connection (id: %d)", fifo_conn->id);
|
||||
|
||||
if (NBN_Driver_RaiseEvent(NBN_DRIVER_SERV_CLIENT_CONNECTED, fifo_conn->conn) < 0)
|
||||
{
|
||||
NBN_LogError("Failed to raise game server event");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return fifo_conn->conn;
|
||||
}
|
||||
|
||||
#pragma endregion /* Game server */
|
||||
|
||||
#pragma region Driver registering
|
||||
|
||||
void NBN_IPC_Register(const char *sock_path)
|
||||
{
|
||||
unix_sock_path = sock_path;
|
||||
|
||||
NBN_Driver_Register(
|
||||
NBN_IPC_DRIVER_ID,
|
||||
NBN_IPC_DRIVER_NAME,
|
||||
(NBN_DriverImplementation){
|
||||
// No client implementation
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
// Server implementation
|
||||
NBN_IPC_ServStart,
|
||||
NBN_IPC_ServStop,
|
||||
NBN_IPC_ServRecvPackets,
|
||||
NBN_IPC_ServSendPacketTo,
|
||||
NBN_IPC_ServRemoveClientConnection
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#pragma endregion /* Driver registering */
|
||||
|
||||
#endif /* NBNET_IMPL */
|
||||
+8
-9
@@ -223,7 +223,7 @@ static void NBN_UDP_HTable_RemoveEntry(NBN_UDP_HTable *htable, NBN_UDP_HTableEnt
|
||||
NBN_Deallocator(entry);
|
||||
|
||||
htable->count--;
|
||||
htable->load_factor = htable->count / htable->capacity;
|
||||
htable->load_factor = (float)htable->count / htable->capacity;
|
||||
}
|
||||
|
||||
static unsigned int NBN_UDP_HTable_FindFreeSlot(NBN_UDP_HTable *htable, NBN_UDP_HTableEntry *entry, bool *use_existing_slot)
|
||||
@@ -405,6 +405,7 @@ static int ResolveIpAddress(const char *host, uint16_t port, NBN_IPAddress *addr
|
||||
{
|
||||
char *s;
|
||||
|
||||
// TODO: replace strtok with strsep
|
||||
if ((s = strtok(i == 0 ? dup_host : NULL, ".")) == NULL)
|
||||
return NBN_ERROR;
|
||||
|
||||
@@ -428,7 +429,7 @@ static int ResolveIpAddress(const char *host, uint16_t port, NBN_IPAddress *addr
|
||||
static char *GetLastErrorMessage(void)
|
||||
{
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
sprintf(err_msg, "%d", WSAGetLastError());
|
||||
snprintf(err_msg, sizeof(err_msg), "%d", WSAGetLastError());
|
||||
|
||||
return err_msg;
|
||||
#else
|
||||
@@ -445,17 +446,15 @@ typedef struct NBN_UDP_Server
|
||||
NBN_UDP_HTable *connections;
|
||||
uint32_t next_conn_id; // nbnet connection ids start at 1
|
||||
uint32_t protocol_id;
|
||||
bool is_encrypted;
|
||||
} NBN_UDP_Server;
|
||||
|
||||
static NBN_UDP_Server nbn_udp_serv = {NULL, 1, 0, false};
|
||||
static NBN_UDP_Server nbn_udp_serv = {NULL, 1, 0};
|
||||
|
||||
static NBN_Connection *FindOrCreateClientConnectionByAddress(NBN_IPAddress);
|
||||
|
||||
static int NBN_UDP_ServStart(uint32_t protocol_id, uint16_t port, bool enable_encryption)
|
||||
static int NBN_UDP_ServStart(uint32_t protocol_id, uint16_t port)
|
||||
{
|
||||
nbn_udp_serv.protocol_id = protocol_id;
|
||||
nbn_udp_serv.is_encrypted = enable_encryption;
|
||||
nbn_udp_serv.connections = NBN_UDP_HTable_Create();
|
||||
|
||||
if (InitSocket() < 0)
|
||||
@@ -563,7 +562,7 @@ static NBN_Connection *FindOrCreateClientConnectionByAddress(NBN_IPAddress addre
|
||||
|
||||
udp_conn->id = nbn_udp_serv.next_conn_id++;
|
||||
udp_conn->address = address;
|
||||
udp_conn->conn = NBN_GameServer_CreateClientConnection(NBN_UDP_DRIVER_ID, udp_conn, nbn_udp_serv.protocol_id, udp_conn->id, nbn_udp_serv.is_encrypted);
|
||||
udp_conn->conn = NBN_GameServer_CreateClientConnection(NBN_UDP_DRIVER_ID, udp_conn, nbn_udp_serv.protocol_id, udp_conn->id);
|
||||
|
||||
NBN_UDP_HTable_Add(nbn_udp_serv.connections, address, udp_conn);
|
||||
|
||||
@@ -599,7 +598,7 @@ static NBN_UDP_Client nbn_udp_cli = {NULL, 0};
|
||||
|
||||
static int ResolveIpAddress(const char *, uint16_t, NBN_IPAddress *);
|
||||
|
||||
static int NBN_UDP_CliStart(uint32_t protocol_id, const char *host, uint16_t port, bool enable_encryption)
|
||||
static int NBN_UDP_CliStart(uint32_t protocol_id, const char *host, uint16_t port)
|
||||
{
|
||||
NBN_UDP_Connection *udp_conn = (NBN_UDP_Connection *)NBN_Allocator(sizeof(NBN_Connection));
|
||||
|
||||
@@ -618,7 +617,7 @@ static int NBN_UDP_CliStart(uint32_t protocol_id, const char *host, uint16_t por
|
||||
if (BindSocket(0) < 0)
|
||||
return NBN_ERROR;
|
||||
|
||||
nbn_udp_cli.server_conn = NBN_GameClient_CreateServerConnection(NBN_UDP_DRIVER_ID, udp_conn, protocol_id, enable_encryption);
|
||||
nbn_udp_cli.server_conn = NBN_GameClient_CreateServerConnection(NBN_UDP_DRIVER_ID, udp_conn, protocol_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -290,13 +290,12 @@ typedef struct NBN_WebRTC_Server
|
||||
NBN_WebRTC_HTable *peers;
|
||||
uint8_t packet_buffer[NBN_PACKET_MAX_SIZE];
|
||||
uint32_t protocol_id;
|
||||
bool is_encrypted;
|
||||
} NBN_WebRTC_Server;
|
||||
|
||||
static NBN_WebRTC_Server nbn_wrtc_serv = {NULL, {0}, 0, false};
|
||||
static NBN_WebRTC_Config nbn_wrtc_cfg;
|
||||
|
||||
static int NBN_WebRTC_ServStart(uint32_t protocol_id, uint16_t port, bool enable_encryption)
|
||||
static int NBN_WebRTC_ServStart(uint32_t protocol_id, uint16_t port)
|
||||
{
|
||||
__js_game_server_init(protocol_id, nbn_wrtc_cfg.enable_tls, nbn_wrtc_cfg.key_path, nbn_wrtc_cfg.cert_path);
|
||||
|
||||
@@ -304,7 +303,6 @@ static int NBN_WebRTC_ServStart(uint32_t protocol_id, uint16_t port, bool enable
|
||||
return -1;
|
||||
|
||||
nbn_wrtc_serv.peers = NBN_WebRTC_HTable_Create();
|
||||
nbn_wrtc_serv.is_encrypted = enable_encryption;
|
||||
nbn_wrtc_serv.protocol_id = protocol_id;
|
||||
|
||||
return 0;
|
||||
@@ -341,8 +339,7 @@ static int NBN_WebRTC_ServRecvPackets(void)
|
||||
NBN_WEBRTC_DRIVER_ID,
|
||||
peer,
|
||||
nbn_wrtc_serv.protocol_id,
|
||||
peer_id,
|
||||
nbn_wrtc_serv.is_encrypted);
|
||||
peer_id);
|
||||
|
||||
NBN_WebRTC_HTable_Add(nbn_wrtc_serv.peers, peer_id, peer);
|
||||
|
||||
@@ -402,11 +399,11 @@ typedef struct NBN_WebRTC_Client
|
||||
|
||||
static NBN_WebRTC_Client nbn_wrtc_cli = {NULL};
|
||||
|
||||
static int NBN_WebRTC_CliStart(uint32_t protocol_id, const char *host, uint16_t port, bool enable_encryption)
|
||||
static int NBN_WebRTC_CliStart(uint32_t protocol_id, const char *host, uint16_t port)
|
||||
{
|
||||
__js_game_client_init(protocol_id, nbn_wrtc_cfg.enable_tls);
|
||||
|
||||
nbn_wrtc_cli.server_conn = NBN_GameClient_CreateServerConnection(NBN_WEBRTC_DRIVER_ID, NULL, protocol_id, enable_encryption);
|
||||
nbn_wrtc_cli.server_conn = NBN_GameClient_CreateServerConnection(NBN_WEBRTC_DRIVER_ID, NULL, protocol_id);
|
||||
|
||||
int res;
|
||||
|
||||
|
||||
@@ -556,7 +556,6 @@ typedef struct NBN_WebRTC_C_Server
|
||||
{
|
||||
int wsserver;
|
||||
NBN_WebRTC_C_HTable *peers;
|
||||
bool is_encrypted;
|
||||
uint16_t ws_port;
|
||||
uint32_t protocol_id;
|
||||
char packet_buffer[NBN_PACKET_MAX_SIZE];
|
||||
@@ -606,8 +605,7 @@ static void NBN_WebRTC_C_Serv_OnWsOpen(int ws, void *user_ptr)
|
||||
NBN_WEBRTC_C_DRIVER_ID,
|
||||
peer,
|
||||
nbn_wrtc_c_serv.protocol_id,
|
||||
peer->id,
|
||||
nbn_wrtc_c_serv.is_encrypted);
|
||||
peer->id);
|
||||
NBN_WebRTC_C_HTable_Add(nbn_wrtc_c_serv.peers, peer->id, peer);
|
||||
}
|
||||
|
||||
@@ -641,11 +639,10 @@ static void NBN_WebRTC_C_Serv_OnWsConnection(int wsserver, int ws, void *user_pt
|
||||
rtcSetMessageCallback(ws, NBN_WebRTC_C_Serv_OnWsMessage);
|
||||
}
|
||||
|
||||
static int NBN_WebRTC_C_ServStart(uint32_t protocol_id, uint16_t port, bool enable_encryption)
|
||||
static int NBN_WebRTC_C_ServStart(uint32_t protocol_id, uint16_t port)
|
||||
{
|
||||
nbn_wrtc_c_serv.ws_port = port;
|
||||
nbn_wrtc_c_serv.peers = NBN_WebRTC_C_HTable_Create();
|
||||
nbn_wrtc_c_serv.is_encrypted = enable_encryption;
|
||||
nbn_wrtc_c_serv.protocol_id = protocol_id;
|
||||
nbn_wrtc_c_serv.wsserver = -1;
|
||||
|
||||
@@ -742,7 +739,6 @@ static int NBN_WebRTC_C_ServSendPacketTo(NBN_Packet *packet, NBN_Connection *con
|
||||
typedef struct NBN_WebRTC_C_Client
|
||||
{
|
||||
uint32_t protocol_id;
|
||||
bool is_encrypyed;
|
||||
bool is_connected;
|
||||
NBN_WebRTC_C_Peer *peer;
|
||||
char packet_buffer[NBN_PACKET_MAX_SIZE];
|
||||
@@ -790,7 +786,7 @@ static void NBN_WebRTC_C_Cli_OnWsOpen(int ws, void *user_ptr)
|
||||
|
||||
NBN_LogDebug("Successfully created peer: %d", peer->id);
|
||||
|
||||
peer->conn = NBN_GameClient_CreateServerConnection(NBN_WEBRTC_C_DRIVER_ID, peer, nbn_wrtc_c_cli.protocol_id, nbn_wrtc_c_cli.is_encrypyed);
|
||||
peer->conn = NBN_GameClient_CreateServerConnection(NBN_WEBRTC_C_DRIVER_ID, peer, nbn_wrtc_c_cli.protocol_id);
|
||||
nbn_wrtc_c_cli.peer = peer;
|
||||
}
|
||||
|
||||
@@ -850,7 +846,7 @@ static int AttemptConnection(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int NBN_WebRTC_C_CliStart(uint32_t protocol_id, const char *host, uint16_t port, bool enable_encryption)
|
||||
static int NBN_WebRTC_C_CliStart(uint32_t protocol_id, const char *host, uint16_t port)
|
||||
{
|
||||
rtcInitLogger(nbn_wrtc_c_cfg.log_level, NBN_WebRTC_C_Log);
|
||||
rtcPreload();
|
||||
@@ -868,7 +864,6 @@ static int NBN_WebRTC_C_CliStart(uint32_t protocol_id, const char *host, uint16_
|
||||
}
|
||||
|
||||
nbn_wrtc_c_cli.protocol_id = protocol_id;
|
||||
nbn_wrtc_c_cli.is_encrypyed = enable_encryption;
|
||||
|
||||
NBN_LogDebug("Successfully created client WS: %d", cli_ws);
|
||||
|
||||
|
||||
Reference in new issue
Block a user