Skip to content
Open
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
5 changes: 4 additions & 1 deletion Core/Interface/SolidSyslogSender.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
* first use, which can block on the transport. @p buffer is read only during the call. */
bool SolidSyslogSender_Send(struct SolidSyslogSender * sender, const void* buffer, size_t size);

/** Drop the connection; the next Send reconnects. Idempotent. */
/** Drop the connection; the next Send reconnects. Idempotent. Touches the
* same connection state as Send and takes no lock, so call it from the
* servicing thread. From any other thread, move the version the sender polls
* instead - the endpoint's or the stream's - and the next Send reconnects. */
void SolidSyslogSender_Disconnect(struct SolidSyslogSender * sender);

SOLIDSYSLOG_EXTERN_C_END
Expand Down
12 changes: 12 additions & 0 deletions Core/Interface/SolidSyslogStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
* a later Open reconnects. */
void SolidSyslogStream_Close(struct SolidSyslogStream * stream);

/** Returns a monotonic version the integrator bumps when the stream's
* configuration changes - the material it presents, the peer it will accept.
* A stream implementation polls this to answer SolidSyslogStream_Version, so
* it must be cheap and pure. @p context is the paired context field on that
* stream's config, passed through unchanged. */
typedef uint32_t (*SolidSyslogStreamVersionFunction)(void* context);

/** The stream's current configuration version. The sender polls this every
* Send and reconnects when it has moved, so a stream whose configuration
* cannot change at runtime reports 0 throughout. */
uint32_t SolidSyslogStream_Version(struct SolidSyslogStream * stream);

SOLIDSYSLOG_EXTERN_C_END

#endif /* SOLIDSYSLOGSTREAM_H */
8 changes: 8 additions & 0 deletions Core/Interface/SolidSyslogStreamDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
* reconnects it. Called on a stream that is already closed, on one that
* never opened, and again from Destroy. */
void (*Close)(struct SolidSyslogStream* base);
/** Report a monotonic version of this stream's own configuration - what it
* will present or accept on the next Open. Bump it when that changes and
* the sender reconnects on its next pass. Polled every Send, so it must be
* cheap and pure. Make the change before moving the version: the sender
* may reconnect on the very next record, and a version moved first lets
* it reopen with the configuration being replaced. A stream with nothing
* to change reports 0 for its lifetime. */
uint32_t (*Version)(struct SolidSyslogStream* base);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
};

SOLIDSYSLOG_EXTERN_C_END
Expand Down
9 changes: 9 additions & 0 deletions Core/Source/SolidSyslogNullStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "SolidSyslogStream.h"
#include "SolidSyslogStreamDefinition.h"
Expand All @@ -16,6 +17,7 @@ static bool NullStream_Open(struct SolidSyslogStream* base, const struct SolidSy
static bool NullStream_Send(struct SolidSyslogStream* base, const void* buffer, size_t size);
static SolidSyslogSsize NullStream_Read(struct SolidSyslogStream* base, void* buffer, size_t size);
static void NullStream_Close(struct SolidSyslogStream* base);
static uint32_t NullStream_Version(struct SolidSyslogStream* base);

struct SolidSyslogStream* SolidSyslogNullStream_Get(void)
{
Expand All @@ -24,6 +26,7 @@ struct SolidSyslogStream* SolidSyslogNullStream_Get(void)
.Send = NullStream_Send,
.Read = NullStream_Read,
.Close = NullStream_Close,
.Version = NullStream_Version,
};
return &instance;
}
Expand Down Expand Up @@ -60,3 +63,9 @@ static void NullStream_Close(struct SolidSyslogStream* base)
{
(void) base;
}

static uint32_t NullStream_Version(struct SolidSyslogStream* base)
{
(void) base;
return 0U;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
6 changes: 6 additions & 0 deletions Core/Source/SolidSyslogStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "SolidSyslogStreamDefinition.h"
#include "SolidSyslogStream.h"
Expand All @@ -29,3 +30,8 @@ void SolidSyslogStream_Close(struct SolidSyslogStream* stream)
{
stream->Close(stream);
}

uint32_t SolidSyslogStream_Version(struct SolidSyslogStream* stream)
{
return stream->Version(stream);
}
25 changes: 21 additions & 4 deletions Core/Source/SolidSyslogStreamSender.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ static inline struct SolidSyslogStreamSender* StreamSender_SelfFromBase(struct S

static inline bool StreamSender_Reconcile(struct SolidSyslogStreamSender* self);
static inline void StreamSender_DisconnectIfStale(struct SolidSyslogStreamSender* self);
static inline bool StreamSender_ConfigurationMoved(
const struct SolidSyslogStreamSender* self,
uint32_t endpointVersion,
uint32_t streamVersion
);
static inline bool StreamSender_EnsureConnected(struct SolidSyslogStreamSender* self);
static inline bool StreamSender_Connected(struct SolidSyslogStreamSender* self);
static bool StreamSender_Connect(struct SolidSyslogStreamSender* self);
Expand Down Expand Up @@ -74,6 +79,7 @@ void SolidSyslogStreamSender_Initialise(
self->Connected = false;
self->DeliveryHealthy = true;
self->LastEndpointVersion = 0;
self->LastStreamVersion = 0;
}

void SolidSyslogStreamSender_Cleanup(struct SolidSyslogSender* base)
Expand Down Expand Up @@ -112,15 +118,26 @@ static inline bool StreamSender_Reconcile(struct SolidSyslogStreamSender* self)

static inline void StreamSender_DisconnectIfStale(struct SolidSyslogStreamSender* self)
{
uint32_t version = self->Config.EndpointVersion(self->Config.EndpointContext);
uint32_t endpointVersion = self->Config.EndpointVersion(self->Config.EndpointContext);
uint32_t streamVersion = SolidSyslogStream_Version(self->Config.Stream);

if (version != self->LastEndpointVersion)
if (StreamSender_ConfigurationMoved(self, endpointVersion, streamVersion))
{
StreamSender_Disconnect(&self->Base);
self->LastEndpointVersion = version;
self->LastEndpointVersion = endpointVersion;
self->LastStreamVersion = streamVersion;
}
}

static inline bool StreamSender_ConfigurationMoved(
const struct SolidSyslogStreamSender* self,
uint32_t endpointVersion,
uint32_t streamVersion
)
{
return (endpointVersion != self->LastEndpointVersion) || (streamVersion != self->LastStreamVersion);
}

static inline bool StreamSender_EnsureConnected(struct SolidSyslogStreamSender* self)
{
return StreamSender_Connected(self) || StreamSender_Connect(self);
Expand Down Expand Up @@ -229,5 +246,5 @@ static void StreamSender_NilEndpoint(struct SolidSyslogEndpoint* endpoint, void*
static uint32_t StreamSender_NilEndpointVersion(void* context)
{
(void) context;
return 0;
return 0U;
}
1 change: 1 addition & 0 deletions Core/Source/SolidSyslogStreamSenderPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct SolidSyslogStreamSender
bool Connected;
bool DeliveryHealthy;
uint32_t LastEndpointVersion;
uint32_t LastStreamVersion;
};

void SolidSyslogStreamSender_Initialise(
Expand Down
10 changes: 9 additions & 1 deletion Platform/LwipRaw/Source/SolidSyslogLwipRawTcpStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ static bool LwipRawTcpStream_Open(struct SolidSyslogStream* base, const struct S
static bool LwipRawTcpStream_Send(struct SolidSyslogStream* base, const void* buffer, size_t size);
static SolidSyslogSsize LwipRawTcpStream_Read(struct SolidSyslogStream* base, void* buffer, size_t size);
static void LwipRawTcpStream_Close(struct SolidSyslogStream* base);
static uint32_t LwipRawTcpStream_Version(struct SolidSyslogStream* base);

static inline struct SolidSyslogLwipRawTcpStream* LwipRawTcpStream_SelfFromBase(struct SolidSyslogStream* base);
static inline struct SolidSyslogLwipRawTcpStream* LwipRawTcpStream_SelfFromArg(void* arg);
Expand Down Expand Up @@ -102,7 +103,8 @@ void SolidSyslogLwipRawTcpStream_Initialise(
{.Open = LwipRawTcpStream_Open,
.Send = LwipRawTcpStream_Send,
.Read = LwipRawTcpStream_Read,
.Close = LwipRawTcpStream_Close},
.Close = LwipRawTcpStream_Close,
.Version = LwipRawTcpStream_Version},
.Config =
{.GetConnectTimeoutMs = LwipRawTcpStream_NullConnectTimeoutGetter,
.ConnectTimeoutContext = NULL,
Expand Down Expand Up @@ -460,6 +462,12 @@ static void LwipRawTcpStream_Close(struct SolidSyslogStream* base)
}
}

static uint32_t LwipRawTcpStream_Version(struct SolidSyslogStream* base)
{
(void) base;
return 0U;
}

/* Close touches lwIP only if there is a pcb to close or queued pbufs to
* free. Close-before-open and close-after-tcp_err (Pcb already nulled, queue
* empty) do no lwIP work and take no marshal hop. */
Expand Down
12 changes: 12 additions & 0 deletions Platform/MbedTls/Interface/SolidSyslogMbedTlsStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

#include "SolidSyslogExternC.h"
#include "SolidSyslogSleep.h"
#include "SolidSyslogStream.h"
#include "SolidSyslogTlsHandshakeTimeoutFunction.h"

struct SolidSyslogStream;
Expand All @@ -52,6 +53,10 @@ struct mbedtls_ctr_drbg_context;

SOLIDSYSLOG_EXTERN_C_BEGIN

/** Wires SolidSyslogMbedTlsStream to its transport, trust anchors, and identity.
* Copied at Create, so a runtime change is made in what these fields point at -
* rewrite the buffer, re-parse into the handle, hand back new material from the
* Credentials - never by reassigning a field here. */
struct SolidSyslogMbedTlsStreamConfig
{
/** Underlying byte stream the TLS records ride on; required - a NULL is
Expand Down Expand Up @@ -82,6 +87,13 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
* private CA): the peer must still satisfy whatever the credentials
* installed, but the endpoint identity is not checked; no diagnostic. */
const char* ServerName;
/** Bumped by the integrator when anything above changes at runtime - the
* Credentials or ServerName. The sender polls it every Send and reconnects
* on the next pass when it moves, so a rotation applies without calling
* SolidSyslogSender_Disconnect. Polled from the servicing thread, so it
* must be cheap and pure. NULL means this configuration never changes. */
SolidSyslogStreamVersionFunction Version;
void* VersionContext; /**< Passed to Version unchanged; NULL is fine. */
Comment thread
coderabbitai[bot] marked this conversation as resolved.
};

/** Draw a TLS stream from the pool over the config's Transport (see the file
Expand Down
29 changes: 29 additions & 0 deletions Platform/MbedTls/Source/SolidSyslogMbedTlsStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ enum
struct SolidSyslogAddress;

static uint32_t MbedTlsStream_NullHandshakeTimeoutGetter(void* context);
static uint32_t MbedTlsStream_NullVersion(void* context);
static inline bool MbedTlsStream_ConfigProvidesHandshakeGetter(const struct SolidSyslogMbedTlsStreamConfig* config);
static inline bool MbedTlsStream_ConfigProvidesVersion(const struct SolidSyslogMbedTlsStreamConfig* config);
static inline uint32_t MbedTlsStream_ResolveHandshakeTimeoutMs(struct SolidSyslogMbedTlsStream* self);
static inline struct SolidSyslogMbedTlsStream* MbedTlsStream_SelfFromBase(struct SolidSyslogStream* base);
static inline bool MbedTlsStream_Open(struct SolidSyslogStream* base, const struct SolidSyslogAddress* addr);
Expand Down Expand Up @@ -72,6 +74,7 @@ static inline bool MbedTlsStream_IsHandshakeBudgetExhausted(uint32_t totalSleptM
static inline bool MbedTlsStream_Send(struct SolidSyslogStream* base, const void* buffer, size_t size);
static inline SolidSyslogSsize MbedTlsStream_Read(struct SolidSyslogStream* base, void* buffer, size_t size);
static inline void MbedTlsStream_Close(struct SolidSyslogStream* base);
static uint32_t MbedTlsStream_Version(struct SolidSyslogStream* base);
static int MbedTlsStream_BioSend(void* ctx, const unsigned char* buf, size_t len);
static int MbedTlsStream_BioRecv(void* ctx, unsigned char* buf, size_t len);

Expand All @@ -85,6 +88,7 @@ void SolidSyslogMbedTlsStream_Initialise(
self->Base.Send = MbedTlsStream_Send;
self->Base.Read = MbedTlsStream_Read;
self->Base.Close = MbedTlsStream_Close;
self->Base.Version = MbedTlsStream_Version;
self->Config = *config;
self->CredentialsInstalled = false;
if (MbedTlsStream_ConfigProvidesHandshakeGetter(config) == false)
Expand All @@ -95,6 +99,11 @@ void SolidSyslogMbedTlsStream_Initialise(
self->Config.GetHandshakeTimeoutMs = MbedTlsStream_NullHandshakeTimeoutGetter;
self->Config.HandshakeTimeoutContext = NULL;
}
if (MbedTlsStream_ConfigProvidesVersion(config) == false)
{
self->Config.Version = MbedTlsStream_NullVersion;
self->Config.VersionContext = NULL;
}
/* Eager init so mbedtls_*_free in Close is always safe - whether Open
* was ever reached, whether it succeeded, or whether Close is being
* called twice in a row. mbedTLS guarantees a freed struct is left in
Expand All @@ -118,6 +127,20 @@ static inline bool MbedTlsStream_ConfigProvidesHandshakeGetter(const struct Soli
return (config != NULL) && (config->GetHandshakeTimeoutMs != NULL);
}

/* Null Object substituted at Initialise when the integrator installs no version
* function - reports an unchanging configuration, so the sender never reconnects
* on this stream's account. */
static uint32_t MbedTlsStream_NullVersion(void* context)
{
(void) context;
return 0U;
}

static inline bool MbedTlsStream_ConfigProvidesVersion(const struct SolidSyslogMbedTlsStreamConfig* config)
{
return (config != NULL) && (config->Version != NULL);
}

/* Bridges the integrator-installed getter (or the Null Object substituted at
* config-copy time) to the bounded handshake deadline. Invoked at the start
* of each handshake attempt so runtime-tunable values take effect on the next
Expand Down Expand Up @@ -159,6 +182,12 @@ static inline void MbedTlsStream_Close(struct SolidSyslogStream* base)
SolidSyslogStream_Close(self->Config.Transport);
}

static uint32_t MbedTlsStream_Version(struct SolidSyslogStream* base)
{
struct SolidSyslogMbedTlsStream* self = MbedTlsStream_SelfFromBase(base);
return self->Config.Version(self->Config.VersionContext);
}

static inline bool MbedTlsStream_Open(struct SolidSyslogStream* base, const struct SolidSyslogAddress* addr)
{
struct SolidSyslogMbedTlsStream* self = MbedTlsStream_SelfFromBase(base);
Expand Down
14 changes: 13 additions & 1 deletion Platform/OpenSsl/Interface/SolidSyslogOpenSslStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,18 @@

#include "SolidSyslogExternC.h"
#include "SolidSyslogSleep.h"
#include "SolidSyslogStream.h"
#include "SolidSyslogTlsHandshakeTimeoutFunction.h"

struct SolidSyslogStream;
struct SolidSyslogOpenSslCredentials;

SOLIDSYSLOG_EXTERN_C_BEGIN

/** Wires SolidSyslogOpenSslStream to its transport, trust anchors, and identity. */
/** Wires SolidSyslogOpenSslStream to its transport, trust anchors, and identity.
* Copied at Create, so a runtime change is made in what these fields point at -
* rewrite the buffer, re-parse into the handle, hand back new material from the
* Credentials - never by reassigning a field here. */
struct SolidSyslogOpenSslStreamConfig
{
/** Underlying byte stream carrying the ciphertext; required - a NULL is
Expand Down Expand Up @@ -69,6 +73,14 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
* endpoint identity unchecked; no diagnostic. */
const char* ServerName;
const char* CipherList; /**< TLS 1.2 cipher list; NULL uses the OpenSSL default. */
/** Bumped by the integrator when anything above changes at runtime - the
* Credentials, ServerName or CipherList. The sender polls it every Send and
* reconnects on the next pass when it moves, so a rotation applies without
* calling SolidSyslogSender_Disconnect. Polled from the servicing thread,
* so it must be cheap and pure. NULL means this configuration never
* changes. */
SolidSyslogStreamVersionFunction Version;
void* VersionContext; /**< Passed to Version unchanged; NULL is fine. */
Comment thread
coderabbitai[bot] marked this conversation as resolved.
};

/** Draw a TLS stream from the pool over the injected transport (see the file
Expand Down
Loading
Loading