Files
Volodymyr FialkoandBIAGINI Nathan 15d823dab6 Enable build flags and fix compilation warnings (gcc 14.1.0) (#66)
* Fix rpc build with other examples

CPP_COMPILE is an option, a cache variable, thus regular unset() is not
working for it since it tries to unset the scope variable.

This causing cmake to skip compilation of rpc.
Unset CPP_COMPILE from CACHE to make it work as intended.

* Fix compiler flags with build targets

Currently tests, soak and examples are build without extra flags,
because add_compile_options is specified after defining build targets.

From add_compile_options() docs:
Adds options to the compiler command line for targets in the current
directory and below that are added *after* this command is invoked.

* Pass debug callbacks as struct

Fixes:
warning: ISO C forbids conversion of function pointer to object pointer
type

* Move global variables under NBNET_IMPL

Nb net could be included multiple times, to prevent creation of global
variables in each file move them under NBNET_IMPL.

Also use designated initializer to initiate a driver structure to
remove warnings about partial initialization. Designated initializer
would initialize other members to zero.

* Resolve unused variables warnings.

Cast unused function arguments to (void) to suspend warnings.

* Resolve signed vs unsigned warnings

Remove unnecessary lt 0 checks and sync types to remove signed vs
unsigned warnings.

* Resolve string related warnings

Fixes:
nbnet/tests/string_tests.c:18:9: error: ‘strncpy’
output truncated before terminating nul copying 5 bytes from a string of
the same length
[-Werror=stringop-truncation]
   18 |         strncpy(res + pos, b, len_b);
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

nbnet/tests/string_tests.c:24:9: error: ‘strncpy’
specified bound depends on the length of the source argument
[-Werror=stringop-truncation]

* Resolve function defined but not used warnings

Mark GameServer_GetClientCount() as inline.

* Attempt to fix warning in ASSERT_VALUE_IN_RANGE

In case when value in unsigned type and min is 0, this commit just
obfuscates types, maybe there's better solution.

Fixes:
warning: comparison of unsigned expression in ‘>= 0’ is always true
[-Wtype-limits]

* Ensure that read len is less than word size

In release mode(-DCMAKE_BUILD_TYPE=Release) tests returning following
error:
nbnet/tests/../nbnet.h:2272:9: error: ‘memcpy’ forming offset [4, 7] is
out of the bound s [0, 4] of object ‘word’ with type ‘Word’ {aka
‘unsigned int’} [-Werror=array-bounds=]
 2272 |         memcpy(bytes, &word, length); |
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

Add check to verify that length is less than Word size.

* add -Wno-unknown-pragmas flag

* fix examples compilation on windows

* fix examples compilation on windows

* fix examples compilation on windows

* fix unit tests compilation on windows

* fix soak test compilation on windows

* fix unit tests compilation on windows

* fix unit tests compilation on windows

---------

Co-authored-by: BIAGINI Nathan <nath.biagini@gmail.com>
2024-08-10 12:02:42 +02:00

221 lines
6.1 KiB
C

/*
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.
*/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
// Has to be defined in exactly *one* source file before including the nbnet header
#define NBNET_IMPL
#include "shared.h"
static NBN_ConnectionHandle client = 0;
// Echo the received message
static int EchoReceivedMessage(void)
{
// Get info about the received message
NBN_MessageInfo msg_info = NBN_GameServer_GetMessageInfo();
assert(msg_info.sender == client);
assert(msg_info.type == ECHO_MESSAGE_TYPE);
// Retrieve the received message
EchoMessage *msg = (EchoMessage *)msg_info.data;
// Create an echo message
EchoMessage *echo = EchoMessage_Create();
// Fill it with the received message data and length
memcpy(echo->data, msg->data, msg->length);
echo->length = msg->length;
// Reliably send it to the client
// If the send fails the client will be disconnected and a NBN_CLIENT_DISCONNECTED event
// will be received (see event polling in main)
NBN_GameServer_SendReliableMessageTo(client, ECHO_MESSAGE_TYPE, echo);
EchoMessage_Destroy(msg); // Destroy the received echo message
return 0;
}
static bool error = false;
int main(int argc, const char **argv)
{
#ifdef __EMSCRIPTEN__
// Register the WebRTC driver
#ifdef NBN_TLS
if (argc != 3)
{
printf("Usage: server CERT_PATH KEY_PATH\n");
return 1;
}
const char *cert_path = argv[1];
const char *key_path = argv[2];
NBN_WebRTC_Register((NBN_WebRTC_Config){.enable_tls = true, .cert_path = cert_path, .key_path = key_path});
#else
NBN_WebRTC_Register((NBN_WebRTC_Config){.enable_tls = false});
#endif // NBN_TLS
#endif // __EMSCRIPTEN__
#ifdef NBN_WEBRTC_NATIVE
// Register native WebRTC driver
#ifdef NBN_TLS
bool enable_tls = true;
#else
bool enable_tls = false;
#endif // NBN_TLS
const char *ice_servers[] = { "stun:stun01.sipphone.com" };
NBN_WebRTC_C_Config cfg = {
.ice_servers = ice_servers,
.ice_servers_count = 1,
.enable_tls = enable_tls,
.cert_path = NULL,
.key_path = NULL,
.passphrase = NULL,
.log_level = RTC_LOG_VERBOSE};
NBN_WebRTC_C_Register(cfg);
#endif // NBN_WEBRTC_NATIVE
#if !defined(__EMSCRIPTEN__) && !defined(NBN_WEBRTC_NATIVE)
NBN_UDP_Register(); // Register the UDP driver
#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) < 0)
{
Log(LOG_ERROR, "Failed to start the server");
// Error, quit the server application
#ifdef __EMSCRIPTEN__
emscripten_force_exit(1);
#else
return 1;
#endif
}
(void) argc;
(void) argv;
// Registering messages, have to be done after NBN_GameServer_StartEx
NBN_GameServer_RegisterMessage(ECHO_MESSAGE_TYPE,
(NBN_MessageBuilder)EchoMessage_Create,
(NBN_MessageDestructor)EchoMessage_Destroy,
(NBN_MessageSerializer)EchoMessage_Serialize);
// Number of seconds between server ticks
double dt = 1.0 / ECHO_TICK_RATE;
while (true)
{
int ev;
// Poll for server events
while ((ev = NBN_GameServer_Poll()) != NBN_NO_EVENT)
{
if (ev < 0)
{
Log(LOG_ERROR, "Something went wrong");
// Error, quit the server application
error = true;
break;
}
switch (ev)
{
// New connection request...
case NBN_NEW_CONNECTION:
// Echo server work with one single client at a time
if (client)
{
NBN_GameServer_RejectIncomingConnectionWithCode(ECHO_SERVER_BUSY_CODE);
}
else
{
NBN_GameServer_AcceptIncomingConnection();
client = NBN_GameServer_GetIncomingConnection();
}
break;
// The client has disconnected
case NBN_CLIENT_DISCONNECTED:
assert(NBN_GameServer_GetDisconnectedClient() == client);
client = 0;
break;
// A message has been received from the client
case NBN_CLIENT_MESSAGE_RECEIVED:
if (EchoReceivedMessage() < 0)
{
Log(LOG_ERROR, "Failed to echo received message");
// Error, quit the server application
error = true;
}
break;
}
}
// Pack all enqueued messages as packets and send them
if (NBN_GameServer_SendPackets() < 0)
{
Log(LOG_ERROR, "Failed to send packets");
// Error, quit the server application
error = true;
break;
}
// Cap the server tick rate
EchoSleep(dt);
}
// Stop the server
NBN_GameServer_Stop();
#ifdef NBN_WEBRTC_NATIVE
NBN_WebRTC_C_Unregister();
#endif
int ret = error ? 1 : 0;
#ifdef __EMSCRIPTEN__
emscripten_force_exit(ret);
#else
return ret;
#endif
}