Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver*
return SolidSyslogNullSender_Get();
}

underlyingStream = SolidSyslogFreeRtosTcpStream_Create();
underlyingStream = SolidSyslogFreeRtosTcpStream_Create(NULL);

static struct SolidSyslogMbedTlsStreamConfig tlsStreamConfig;
tlsStreamConfig = (struct SolidSyslogMbedTlsStreamConfig) {0};
Expand Down
3 changes: 2 additions & 1 deletion Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_PosixTcp.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdbool.h>
#include <stddef.h>

#include "BddTargetMtlsConfig.h"
#include "BddTargetTlsConfig.h"
Expand All @@ -19,7 +20,7 @@ static struct SolidSyslogSender* sender;

struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* resolver, bool mtls)
{
underlyingStream = SolidSyslogPosixTcpStream_Create();
underlyingStream = SolidSyslogPosixTcpStream_Create(NULL);

static struct SolidSyslogTlsStreamConfig tlsStreamConfig;
tlsStreamConfig = (struct SolidSyslogTlsStreamConfig) {0};
Expand Down
2 changes: 1 addition & 1 deletion Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_WinsockTcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static struct SolidSyslogSender* sender;

struct SolidSyslogSender* BddTargetTlsSender_Create(struct SolidSyslogResolver* resolver, bool mtls)
{
underlyingStream = SolidSyslogWinsockTcpStream_Create();
underlyingStream = SolidSyslogWinsockTcpStream_Create(NULL);

static struct SolidSyslogTlsStreamConfig tlsStreamConfig;
tlsStreamConfig = (struct SolidSyslogTlsStreamConfig) {0};
Expand Down
2 changes: 1 addition & 1 deletion Bdd/Targets/FreeRtos/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ static void InteractiveTask(void* argument)
* UDP endpoint callbacks because the BDD oracle (syslog-ng) listens on the
* same host:port for both transports — the syslog-ng config in
* Bdd/syslog-ng/syslog-ng.conf has a TCP listener on 5514 alongside UDP. */
tcpStream = SolidSyslogFreeRtosTcpStream_Create();
tcpStream = SolidSyslogFreeRtosTcpStream_Create(NULL);
tcpAddress = SolidSyslogFreeRtosAddress_Create();
struct SolidSyslogStreamSenderConfig tcpConfig = {
.Resolver = resolver,
Expand Down
2 changes: 1 addition & 1 deletion Bdd/Targets/Linux/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static struct SolidSyslogSender* CreateSender(const struct BddTargetOptions* opt
udpConfig.EndpointVersion = BddTargetUdpConfig_GetEndpointVersion;
udpSender = SolidSyslogUdpSender_Create(&udpConfig);

plainTcpStream = SolidSyslogPosixTcpStream_Create();
plainTcpStream = SolidSyslogPosixTcpStream_Create(NULL);
plainTcpAddress = SolidSyslogPosixAddress_Create();
static struct SolidSyslogStreamSenderConfig tcpConfig = {0};
tcpConfig.Resolver = resolver;
Expand Down
2 changes: 1 addition & 1 deletion Bdd/Targets/Windows/BddTargetWindows.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ static struct SolidSyslogSender* CreateSender(const struct BddTargetWindowsOptio
udpConfig.EndpointVersion = GetEndpointVersion;
udpSender = SolidSyslogUdpSender_Create(&udpConfig);

plainTcpStream = SolidSyslogWinsockTcpStream_Create();
plainTcpStream = SolidSyslogWinsockTcpStream_Create(NULL);
plainTcpAddress = SolidSyslogWinsockAddress_Create();
static struct SolidSyslogStreamSenderConfig tcpConfig = {0};
tcpConfig.Resolver = resolver;
Expand Down
20 changes: 20 additions & 0 deletions Core/Interface/SolidSyslogTcpConnectTimeoutFunction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef SOLIDSYSLOGTCPCONNECTTIMEOUTFUNCTION_H
#define SOLIDSYSLOGTCPCONNECTTIMEOUTFUNCTION_H

#include <stdint.h>

#include "ExternC.h"

EXTERN_C_BEGIN

/* Returns the bounded-connect deadline in milliseconds. Called at the
start of every connect attempt so a runtime-tunable value (e.g.
commissioning-time NVRAM read, live web-UI override) takes effect on
the next reconnect without rebuilding or destroying the stream.
The void* context is passed through unchanged from the config slot
the integrator installed it on. */
typedef uint32_t (*SolidSyslogTcpConnectTimeoutFunction)(void* context);

EXTERN_C_END

#endif /* SOLIDSYSLOGTCPCONNECTTIMEOUTFUNCTION_H */
20 changes: 20 additions & 0 deletions Core/Interface/SolidSyslogTlsHandshakeTimeoutFunction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef SOLIDSYSLOGTLSHANDSHAKETIMEOUTFUNCTION_H
#define SOLIDSYSLOGTLSHANDSHAKETIMEOUTFUNCTION_H

#include <stdint.h>

#include "ExternC.h"

EXTERN_C_BEGIN

/* Returns the bounded-handshake deadline in milliseconds. Called at the
start of every TLS handshake attempt so a runtime-tunable value (e.g.
commissioning-time NVRAM read, live web-UI override) takes effect on
the next reconnect without rebuilding or destroying the stream.
The void* context is passed through unchanged from the config slot
the integrator installed it on. */
typedef uint32_t (*SolidSyslogTlsHandshakeTimeoutFunction)(void* context);

EXTERN_C_END

#endif /* SOLIDSYSLOGTLSHANDSHAKETIMEOUTFUNCTION_H */
44 changes: 44 additions & 0 deletions Core/Interface/SolidSyslogTunablesDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -696,4 +696,48 @@
#error "SOLIDSYSLOG_ADDRESS_POOL_SIZE must be >= 1"
#endif

/*
* Default bounded-connect deadline applied by every TCP Stream backend
* (POSIX, Winsock, FreeRTOS) when the integrator does not install a
* SolidSyslogTcpConnectTimeoutFunction on the config struct. 200 ms is
* comfortable for loopback / LAN and short enough that ten failing attempts
* cost 2 s; raise it for WAN deployments behind a high-RTT link.
*
* Runtime override: install GetConnectTimeoutMs on the per-Stream config —
* the getter is invoked on every connect attempt so live tuning takes effect
* without rebuilding or recreating the stream.
*
* Floor: 1 ms. Sub-floor values rejected at compile time.
*/
#ifndef SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS
/* NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -- macro form required for preprocessor visibility (floor #if) and C array-size const-expr. */
#define SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS 200U
#endif

#if SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS < 1
#error "SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS must be >= 1"
#endif

/*
* Default bounded TLS handshake deadline applied by every TLS Stream backend
* (OpenSSL, Mbed TLS) when the integrator does not install a
* SolidSyslogTlsHandshakeTimeoutFunction on the config struct. 5 s covers a
* full TLS 1.2 / 1.3 exchange on a healthy LAN with cert validation; raise
* it for WAN deployments or constrained MCUs that handshake slowly.
*
* Runtime override: install GetHandshakeTimeoutMs on the per-Stream config —
* the getter is invoked on every handshake attempt so live tuning takes
* effect without rebuilding or recreating the stream.
*
* Floor: 1 ms. Sub-floor values rejected at compile time.
*/
#ifndef SOLIDSYSLOG_TLS_HANDSHAKE_TIMEOUT_MS
/* NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -- macro form required for preprocessor visibility (floor #if) and C array-size const-expr. */
#define SOLIDSYSLOG_TLS_HANDSHAKE_TIMEOUT_MS 5000U
#endif

#if SOLIDSYSLOG_TLS_HANDSHAKE_TIMEOUT_MS < 1
#error "SOLIDSYSLOG_TLS_HANDSHAKE_TIMEOUT_MS must be >= 1"
#endif

#endif /* SOLIDSYSLOG_TUNABLES_DEFAULTS_H */
12 changes: 11 additions & 1 deletion Platform/FreeRtos/Interface/SolidSyslogFreeRtosTcpStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@
#define SOLIDSYSLOGFREERTOSTCPSTREAM_H

#include "ExternC.h"
#include "SolidSyslogTcpConnectTimeoutFunction.h"

EXTERN_C_BEGIN

struct SolidSyslogStream;

struct SolidSyslogStream* SolidSyslogFreeRtosTcpStream_Create(void);
struct SolidSyslogFreeRtosTcpStreamConfig
{
SolidSyslogTcpConnectTimeoutFunction
GetConnectTimeoutMs; /* NULL → use SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS tunable */
void* ConnectTimeoutContext; /* passed through to GetConnectTimeoutMs; NULL is fine */
};

struct SolidSyslogStream* SolidSyslogFreeRtosTcpStream_Create(
const struct SolidSyslogFreeRtosTcpStreamConfig* config
);
void SolidSyslogFreeRtosTcpStream_Destroy(struct SolidSyslogStream * base);

EXTERN_C_END
Expand Down
74 changes: 57 additions & 17 deletions Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "SolidSyslogNullStream.h"
#include "SolidSyslogStream.h"
#include "SolidSyslogStreamDefinition.h"
#include "SolidSyslogTunables.h"

/* SolidSyslogStream_Read returns < 0 to signal EOF/error (socket closed
* internally); -1 is the in-tree convention shared with Posix/Winsock. */
Expand All @@ -35,12 +36,15 @@ enum
SEND_RECV_FLAGS_DEFAULT = 0
};

static uint32_t FreeRtosTcpStream_NullConnectTimeoutGetter(void* context);

static bool FreeRtosTcpStream_Open(struct SolidSyslogStream* base, const struct SolidSyslogAddress* addr);
static bool FreeRtosTcpStream_Send(struct SolidSyslogStream* base, const void* buffer, size_t size);
static SolidSyslogSsize FreeRtosTcpStream_Read(struct SolidSyslogStream* base, void* buffer, size_t size);
static void FreeRtosTcpStream_Close(struct SolidSyslogStream* base);

static inline struct SolidSyslogFreeRtosTcpStream* FreeRtosTcpStream_SelfFromBase(struct SolidSyslogStream* base);
static inline bool FreeRtosTcpStream_ConfigProvidesGetter(const struct SolidSyslogFreeRtosTcpStreamConfig* config);
static inline bool FreeRtosTcpStream_IsOpen(const struct SolidSyslogFreeRtosTcpStream* self);
static inline bool FreeRtosTcpStream_IsClosed(const struct SolidSyslogFreeRtosTcpStream* self);
static void FreeRtosTcpStream_OpenSocket(struct SolidSyslogFreeRtosTcpStream* self);
Expand All @@ -56,6 +60,7 @@ static inline void FreeRtosTcpStream_PrimeArpIfMissing(uint32_t ip);
static void FreeRtosTcpStream_ClearTimeouts(Socket_t socket);
static void FreeRtosTcpStream_SetSendTimeout(Socket_t socket, TickType_t ticks);
static void FreeRtosTcpStream_SetRecvTimeout(Socket_t socket, TickType_t ticks);
static uint32_t FreeRtosTcpStream_ResolveConnectTimeoutMs(struct SolidSyslogFreeRtosTcpStream* self);
static bool FreeRtosTcpStream_SendOrCloseOnFailure(
struct SolidSyslogFreeRtosTcpStream* self,
const void* buffer,
Expand All @@ -70,14 +75,41 @@ static SolidSyslogSsize FreeRtosTcpStream_ReceiveOrCloseOnFailure(
);
static void FreeRtosTcpStream_CloseSocket(struct SolidSyslogFreeRtosTcpStream* self);

void FreeRtosTcpStream_Initialise(struct SolidSyslogStream* base)
void FreeRtosTcpStream_Initialise(
struct SolidSyslogStream* base,
const struct SolidSyslogFreeRtosTcpStreamConfig* config
)
{
static const struct SolidSyslogFreeRtosTcpStream DefaultFreeRtosTcpStream = {
.Base =
{.Open = FreeRtosTcpStream_Open,
.Send = FreeRtosTcpStream_Send,
.Read = FreeRtosTcpStream_Read,
.Close = FreeRtosTcpStream_Close},
.Config = {.GetConnectTimeoutMs = FreeRtosTcpStream_NullConnectTimeoutGetter, .ConnectTimeoutContext = NULL},
.Socket = FREERTOS_INVALID_SOCKET,
};

struct SolidSyslogFreeRtosTcpStream* self = FreeRtosTcpStream_SelfFromBase(base);
self->Base.Open = FreeRtosTcpStream_Open;
self->Base.Send = FreeRtosTcpStream_Send;
self->Base.Read = FreeRtosTcpStream_Read;
self->Base.Close = FreeRtosTcpStream_Close;
self->Socket = FREERTOS_INVALID_SOCKET;
*self = DefaultFreeRtosTcpStream;
if (FreeRtosTcpStream_ConfigProvidesGetter(config) == true)
{
self->Config = *config;
}
}

static inline bool FreeRtosTcpStream_ConfigProvidesGetter(const struct SolidSyslogFreeRtosTcpStreamConfig* config)
{
return (config != NULL) && (config->GetConnectTimeoutMs != NULL);
}

/* Null Object substituted when the integrator does not install a getter —
* returns the compile-time tunable so the bounded-wait path has a single
* code path regardless of whether the integrator wired runtime tuning. */
static uint32_t FreeRtosTcpStream_NullConnectTimeoutGetter(void* context)
{
(void) context;
return (uint32_t) SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS;
}

static inline struct SolidSyslogFreeRtosTcpStream* FreeRtosTcpStream_SelfFromBase(struct SolidSyslogStream* base)
Expand Down Expand Up @@ -152,23 +184,31 @@ static bool FreeRtosTcpStream_TryConnect(
const struct SolidSyslogAddress* addr
)
{
/* 200 ms is short enough that the Service task keeps draining
* predictably during an outage, long enough for a healthy peer to
* ACK over slirp/LAN. Both SO_SNDTIMEO and SO_RCVTIMEO are set
* before FreeRTOS_connect — upstream gates connect on SO_RCVTIMEO,
* but we set both as belt-and-braces against an upstream change.
* After connect both timeouts go back to 0 so subsequent Send/Read
* follow the non-blocking single-call contract from
* SolidSyslogStream. */
static const TickType_t CONNECT_TIMEOUT_TICKS = pdMS_TO_TICKS(200);
/* Both SO_SNDTIMEO and SO_RCVTIMEO are set before FreeRTOS_connect —
* upstream gates connect on SO_RCVTIMEO, but we set both as belt-and-
* braces against an upstream change. After connect both timeouts go
* back to 0 so subsequent Send/Read follow the non-blocking single-
* call contract from SolidSyslogStream. The default
* SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS = 200 is short enough that the
* Service task keeps draining predictably during an outage, long
* enough for a healthy peer to ACK over slirp/LAN. */
const TickType_t connectTimeoutTicks = pdMS_TO_TICKS(FreeRtosTcpStream_ResolveConnectTimeoutMs(self));

const struct freertos_sockaddr* dest = SolidSyslogFreeRtosAddress_AsConstFreertosSockaddr(addr);
FreeRtosTcpStream_PrimeArpIfMissing(dest->sin_address.ulIP_IPv4);
FreeRtosTcpStream_SetSendTimeout(self->Socket, CONNECT_TIMEOUT_TICKS);
FreeRtosTcpStream_SetRecvTimeout(self->Socket, CONNECT_TIMEOUT_TICKS);
FreeRtosTcpStream_SetSendTimeout(self->Socket, connectTimeoutTicks);
FreeRtosTcpStream_SetRecvTimeout(self->Socket, connectTimeoutTicks);
return FreeRTOS_connect(self->Socket, dest, sizeof(*dest)) == 0;
}

/* Bridges the integrator-installed getter (or the Null Object substituted in
* Initialise) to the bounded SO_*TIMEO deadline. Invoked on every connect
* attempt so a runtime-tunable value takes effect on the next reconnect. */
static uint32_t FreeRtosTcpStream_ResolveConnectTimeoutMs(struct SolidSyslogFreeRtosTcpStream* self)
{
return self->Config.GetConnectTimeoutMs(self->Config.ConnectTimeoutContext);
}

/* On ARP cache miss issue a probe and yield once for the reply to land
* before FreeRTOS_connect runs. Without this, the cold-start SYN is dropped
* at the IP layer (FreeRTOS-Plus-TCP does not queue while ARP resolves) and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
#include "FreeRTOS.h"
#include "FreeRTOS_Sockets.h"

#include "SolidSyslogFreeRtosTcpStream.h"
#include "SolidSyslogStreamDefinition.h"

struct SolidSyslogFreeRtosTcpStream
{
struct SolidSyslogStream Base;
struct SolidSyslogFreeRtosTcpStreamConfig Config;
Socket_t Socket;
};

void FreeRtosTcpStream_Initialise(struct SolidSyslogStream* base);
void FreeRtosTcpStream_Initialise(
struct SolidSyslogStream* base,
const struct SolidSyslogFreeRtosTcpStreamConfig* config
);
void FreeRtosTcpStream_Cleanup(struct SolidSyslogStream* base);

#endif /* SOLIDSYSLOGFREERTOSTCPSTREAMPRIVATE_H */
4 changes: 2 additions & 2 deletions Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStreamStatic.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ static struct SolidSyslogPoolAllocator FreeRtosTcpStream_Allocator = {
SOLIDSYSLOG_FREE_RTOS_TCP_STREAM_POOL_SIZE
};

struct SolidSyslogStream* SolidSyslogFreeRtosTcpStream_Create(void)
struct SolidSyslogStream* SolidSyslogFreeRtosTcpStream_Create(const struct SolidSyslogFreeRtosTcpStreamConfig* config)
{
size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&FreeRtosTcpStream_Allocator);
struct SolidSyslogStream* handle = SolidSyslogNullStream_Get();
if (SolidSyslogPoolAllocator_IndexIsValid(&FreeRtosTcpStream_Allocator, index) == true)
{
FreeRtosTcpStream_Initialise(&FreeRtosTcpStream_Pool[index].Base);
FreeRtosTcpStream_Initialise(&FreeRtosTcpStream_Pool[index].Base, config);
handle = &FreeRtosTcpStream_Pool[index].Base;
}
else
Expand Down
4 changes: 4 additions & 0 deletions Platform/MbedTls/Interface/SolidSyslogMbedTlsStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "ExternC.h"
#include "SolidSyslogSleep.h"
#include "SolidSyslogTlsHandshakeTimeoutFunction.h"

struct SolidSyslogStream;

Expand All @@ -20,6 +21,9 @@ EXTERN_C_BEGIN
struct SolidSyslogStream* Transport; /* underlying byte stream — caller owns */
SolidSyslogSleepFunction
Sleep; /* drives bounded handshake retry between WANT_READ/WANT_WRITE polls — required */
SolidSyslogTlsHandshakeTimeoutFunction
GetHandshakeTimeoutMs; /* NULL → use SOLIDSYSLOG_TLS_HANDSHAKE_TIMEOUT_MS tunable */
void* HandshakeTimeoutContext; /* passed through to GetHandshakeTimeoutMs; NULL is fine */
struct mbedtls_ctr_drbg_context* Rng; /* seeded CTR-DRBG — caller owns */
struct mbedtls_x509_crt* CaChain; /* trust anchors — caller owns */
const char* ServerName; /* SNI + cert hostname check; NULL to skip */
Expand Down
Loading
Loading