Skip to content

Commit

Permalink
Merge 6c29b98 into a0b9ac7
Browse files Browse the repository at this point in the history
  • Loading branch information
abtink committed Jan 19, 2024
2 parents a0b9ac7 + 6c29b98 commit c467a15
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 11 deletions.
42 changes: 33 additions & 9 deletions src/core/coap/coap_secure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,40 @@ CoapSecure::CoapSecure(Instance &aInstance, bool aLayerTwoSecurity)
{
}

Error CoapSecure::Start(uint16_t aPort)
{
Error error = kErrorNone;
Error CoapSecure::Start(uint16_t aPort) { return Start(aPort, /* aMaxAttempts */ 0, nullptr, nullptr); }

mConnectedCallback.Clear();
Error CoapSecure::Start(uint16_t aPort, uint16_t aMaxAttempts, AutoStopCallback aCallback, void *aContext)
{
Error error;

SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
SuccessOrExit(error = mDtls.Bind(aPort));
SuccessOrExit(error = Open(aMaxAttempts, aCallback, aContext));
error = mDtls.Bind(aPort);

exit:
return error;
}

Error CoapSecure::Start(MeshCoP::SecureTransport::TransportCallback aCallback, void *aContext)
{
Error error = kErrorNone;
Error error;

SuccessOrExit(error = Open(/* aMaxAttemps */ 0, nullptr, nullptr));
error = mDtls.Bind(aCallback, aContext);

exit:
return error;
}

Error CoapSecure::Open(uint16_t aMaxAttempts, AutoStopCallback aCallback, void *aContext)
{
Error error = kErrorAlready;

SuccessOrExit(mDtls.SetMaxConnectionAttempts(aMaxAttempts, HandleDtlsAutoClose, this));
mAutoStopCallback.Set(aCallback, aContext);
mConnectedCallback.Clear();
SuccessOrExit(mDtls.Open(HandleDtlsReceive, HandleDtlsConnected, this));

SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
SuccessOrExit(error = mDtls.Bind(aCallback, aContext));
error = kErrorNone;

exit:
return error;
Expand Down Expand Up @@ -172,6 +185,17 @@ void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected)

void CoapSecure::HandleDtlsConnected(bool aConnected) { mConnectedCallback.InvokeIfSet(aConnected); }

void CoapSecure::HandleDtlsAutoClose(void *aContext)
{
return static_cast<CoapSecure *>(aContext)->HandleDtlsAutoClose();
}

void CoapSecure::HandleDtlsAutoClose(void)
{
Stop();
mAutoStopCallback.InvokeIfSet();
}

void CoapSecure::HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength)
{
return static_cast<CoapSecure *>(aContext)->HandleDtlsReceive(aBuf, aLength);
Expand Down
30 changes: 30 additions & 0 deletions src/core/coap/coap_secure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ class CoapSecure : public CoapBase
*/
typedef void (*ConnectedCallback)(bool aConnected, void *aContext);

/**
* Callback to notify when the agent is automatically stopped due to reaching the maximum number of connection
* attempts.
*
* @param[in] aContext A pointer to arbitrary context information.
*
*/
typedef void (*AutoStopCallback)(void *aContext);

/**
* Initializes the object.
*
Expand All @@ -81,6 +90,21 @@ class CoapSecure : public CoapBase
*/
Error Start(uint16_t aPort);

/**
* Starts the secure CoAP agent and sets the maximum number of allowed connection attempts before stopping the
* agent automatically.
*
* @param[in] aPort The local UDP port to bind to.
* @param[in] aMaxAttempts Maximum number of allowed connection request attempts. Zero indicates no limit.
* @param[in] aCallback Callback to notify if max number of attempts has reached and agent is stopped.
* @param[in] aContext A pointer to arbitrary context to use with `AutoStopCallback`.
*
* @retval kErrorNone Successfully started the CoAP agent.
* @retval kErrorAlready Already started.
*
*/
Error Start(uint16_t aPort, uint16_t aMaxAttempts, AutoStopCallback aCallback, void *aContext);

/**
* Starts the secure CoAP agent, but do not use socket to transmit/receive messages.
*
Expand Down Expand Up @@ -382,6 +406,8 @@ class CoapSecure : public CoapBase
const Ip6::MessageInfo &GetMessageInfo(void) const { return mDtls.GetMessageInfo(); }

private:
Error Open(uint16_t aMaxAttempts, AutoStopCallback aCallback, void *aContext);

static Error Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
return static_cast<CoapSecure &>(aCoapBase).Send(aMessage, aMessageInfo);
Expand All @@ -391,6 +417,9 @@ class CoapSecure : public CoapBase
static void HandleDtlsConnected(void *aContext, bool aConnected);
void HandleDtlsConnected(bool aConnected);

static void HandleDtlsAutoClose(void *aContext);
void HandleDtlsAutoClose(void);

static void HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength);
void HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength);

Expand All @@ -399,6 +428,7 @@ class CoapSecure : public CoapBase

MeshCoP::SecureTransport mDtls;
Callback<ConnectedCallback> mConnectedCallback;
Callback<AutoStopCallback> mAutoStopCallback;
ot::MessageQueue mTransmitQueue;
TaskletContext mTransmitTask;
};
Expand Down
40 changes: 38 additions & 2 deletions src/core/meshcop/secure_transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ SecureTransport::SecureTransport(Instance &aInstance, bool aLayerTwoSecurity, bo
, mTimerSet(false)
, mLayerTwoSecurity(aLayerTwoSecurity)
, mDatagramTransport(aDatagramTransport)
, mMaxConnectionAttempts(0)
, mRemainingConnectionAttempts(0)
, mReceiveMessage(nullptr)
, mSocket(aInstance)
, mMessageSubType(Message::kSubTypeNone)
Expand Down Expand Up @@ -159,18 +161,39 @@ Error SecureTransport::Open(ReceiveHandler aReceiveHandler, ConnectedHandler aCo

mConnectedCallback.Set(aConnectedHandler, aContext);
mReceiveCallback.Set(aReceiveHandler, aContext);

mRemainingConnectionAttempts = mMaxConnectionAttempts;

SetState(kStateOpen);

exit:
return error;
}

Error SecureTransport::SetMaxConnectionAttempts(uint16_t aMaxAttempts, AutoCloseCallback aCallback, void *aContext)
{
Error error = kErrorNone;

VerifyOrExit(IsStateClosed(), error = kErrorInvalidState);

mMaxConnectionAttempts = aMaxAttempts;
mAutoCloseCallback.Set(aCallback, aContext);

exit:
return error;
}

Error SecureTransport::Connect(const Ip6::SockAddr &aSockAddr)
{
Error error;

VerifyOrExit(IsStateOpen(), error = kErrorInvalidState);

if (mRemainingConnectionAttempts > 0)
{
mRemainingConnectionAttempts--;
}

mMessageInfo.SetPeerAddr(aSockAddr.GetAddress());
mMessageInfo.SetPeerPort(aSockAddr.mPort);

Expand All @@ -191,6 +214,11 @@ void SecureTransport::HandleReceive(Message &aMessage, const Ip6::MessageInfo &a

if (IsStateOpen())
{
if (mRemainingConnectionAttempts > 0)
{
mRemainingConnectionAttempts--;
}

IgnoreError(mSocket.Connect(Ip6::SockAddr(aMessageInfo.GetPeerAddr(), aMessageInfo.GetPeerPort())));

mMessageInfo.SetPeerAddr(aMessageInfo.GetPeerAddr());
Expand Down Expand Up @@ -388,8 +416,16 @@ Error SecureTransport::Setup(bool aClient)
exit:
if (IsStateInitializing() && (rval != 0))
{
SetState(kStateOpen);
FreeMbedtls();
if ((mMaxConnectionAttempts > 0) && (mRemainingConnectionAttempts == 0))
{
Close();
mAutoCloseCallback.InvokeIfSet();
}
else
{
SetState(kStateOpen);
FreeMbedtls();
}
}

return Crypto::MbedTls::MapError(rval);
Expand Down
31 changes: 31 additions & 0 deletions src/core/meshcop/secure_transport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ class SecureTransport : public InstanceLocator
*/
typedef Error (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);

/**
* Callback to notify when the socket is automatically closed due to reaching the maximum number of connection
* attempts (set from `SetMaxConnectionAttempts()`).
*
* @param[in] aContext A pointer to arbitrary context information.
*
*/
typedef void (*AutoCloseCallback)(void *aContext);

/**
* Opens the socket.
*
Expand All @@ -141,6 +150,24 @@ class SecureTransport : public InstanceLocator
*/
Error Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext);

/**
* Sets the maximum number of allowed connection requests before socket is automatically closed.
*
* This method can be called when socket is closed. Otherwise `kErrorInvalidSatet` is returned.
*
* If @p aMaxAttempts is zero, no limit is applied and connections are allowed until the socket is closed. This is
* the default behavior if `SetMaxConnectionAttempts()` is not called.
*
* @param[in] aMaxAttempts Maximum number of allowed connection attempts.
* @param[in] aCallback Callback to notify when max number of attempts has reached and socket is closed.
* @param[in] aContext A pointer to arbitrary context to use with `AutoCloseCallback`.
*
* @retval kErrorNone Successfully set the maximum allowed connection attempts and callback.
* @retval kErrorInvalidState Socket is not closed.
*
*/
Error SetMaxConnectionAttempts(uint16_t aMaxAttempts, AutoCloseCallback aCallback, void *aContext);

/**
* Binds this DTLS to a UDP port.
*
Expand Down Expand Up @@ -616,6 +643,10 @@ class SecureTransport : public InstanceLocator
bool mLayerTwoSecurity : 1;
bool mDatagramTransport : 1;

uint16_t mMaxConnectionAttempts;
uint16_t mRemainingConnectionAttempts;
Callback<AutoCloseCallback> mAutoCloseCallback;

Message *mReceiveMessage;

Callback<ConnectedHandler> mConnectedCallback;
Expand Down

0 comments on commit c467a15

Please sign in to comment.