From 1c7abb69e04dc7053d06442e5276260f214f76e5 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 14 Jan 2025 11:23:01 -0800 Subject: [PATCH] [border-agent] organize `CoapDtlsSession` method definitions (#11142) This commit improves the organization of `border_agent.cpp` by grouping the method definitions for `CoapDtlsSession` into a separate section. In PR #11131, many methods were moved into this class. To keep the `git diff` smaller and easier to review, the methods were left in the same order as previously defined. This resulted in the methods of `CoapDtlsSession` and `BorderAgent` being mixed and interleaved. This PR rearranges the methods and defines separate sections for each class. This commit does not contain any code logic changes. --- src/core/meshcop/border_agent.cpp | 586 +++++++++++++++--------------- 1 file changed, 293 insertions(+), 293 deletions(-) diff --git a/src/core/meshcop/border_agent.cpp b/src/core/meshcop/border_agent.cpp index 9b2babcd2a4..75fcd286113 100644 --- a/src/core/meshcop/border_agent.cpp +++ b/src/core/meshcop/border_agent.cpp @@ -254,29 +254,6 @@ void BorderAgent::HandleRemoveSession(SecureSession &aSesssion) mCoapDtlsSession = nullptr; } -void BorderAgent::CoapDtlsSession::HandleConnected(ConnectEvent aEvent, void *aContext) -{ - static_cast(aContext)->HandleConnected(aEvent); -} - -void BorderAgent::CoapDtlsSession::HandleConnected(ConnectEvent aEvent) -{ - if (aEvent == kConnected) - { - LogInfo("SecureSession connected"); - mTimer.Start(kKeepAliveTimeout); - Get().HandleSessionConnected(*this); - } - else - { - LogInfo("SecureSession disconnected"); - IgnoreError(Get().RemoveReceiver(mUdpReceiver)); - Get().RemoveUnicastAddress(mCommissionerAloc); - - Get().HandleSessionDisconnected(*this, aEvent); - } -} - void BorderAgent::HandleSessionConnected(CoapDtlsSession &aSesssion) { OT_UNUSED_VARIABLE(aSesssion); @@ -330,6 +307,286 @@ void BorderAgent::HandleSessionDisconnected(CoapDtlsSession &aSesssion, CoapDtls } } +void BorderAgent::HandleCommissionerPetitionAccepted(CoapDtlsSession &aSesssion) +{ + OT_UNUSED_VARIABLE(aSesssion); + + mState = kStateAccepted; + +#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE + if (mUsingEphemeralKey) + { + mCounters.mEpskcCommissionerPetitions++; + } + else +#endif + { + mCounters.mPskcCommissionerPetitions++; + } +} + +Coap::Message::Code BorderAgent::CoapCodeFromError(Error aError) +{ + Coap::Message::Code code; + + switch (aError) + { + case kErrorNone: + code = Coap::kCodeChanged; + break; + + case kErrorParse: + code = Coap::kCodeBadRequest; + break; + + default: + code = Coap::kCodeInternalError; + break; + } + + return code; +} + +template <> void BorderAgent::HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +{ + // This is from TMF agent. + + OT_UNUSED_VARIABLE(aMessageInfo); + + Coap::Message *message = nullptr; + Error error = kErrorNone; + + VerifyOrExit(mState != kStateStopped); + + VerifyOrExit(aMessage.IsNonConfirmablePostRequest(), error = kErrorDrop); + + VerifyOrExit(mCoapDtlsSession != nullptr); + + message = mCoapDtlsSession->NewPriorityNonConfirmablePostMessage(kUriRelayRx); + VerifyOrExit(message != nullptr, error = kErrorNoBufs); + + SuccessOrExit(error = mCoapDtlsSession->ForwardToCommissioner(*message, aMessage)); + LogInfo("Sent to commissioner on RelayRx (c/rx)"); + +exit: + FreeMessageOnError(message, error); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Ephemeral Key + +#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE + +Error BorderAgent::SetEphemeralKey(const char *aKeyString, uint32_t aTimeout, uint16_t aUdpPort) +{ + Error error = kErrorNone; + uint16_t length = StringLength(aKeyString, kMaxEphemeralKeyLength + 1); + + VerifyOrExit(mState == kStateStarted, error = kErrorInvalidState); + VerifyOrExit((length >= kMinEphemeralKeyLength) && (length <= kMaxEphemeralKeyLength), error = kErrorInvalidArgs); + + if (!mUsingEphemeralKey) + { + mOldUdpPort = GetUdpPort(); + } + + Stop(); + + // We set the `mUsingEphemeralKey` before `Start()` since + // callbacks (like `HandleConnected()`) may be invoked from + // `Start()` itself. + + mUsingEphemeralKey = true; + mDidConnectWithEphemeralKey = false; + + error = Start(aUdpPort, reinterpret_cast(aKeyString), static_cast(length)); + + if (error != kErrorNone) + { + mUsingEphemeralKey = false; + IgnoreError(Start(mOldUdpPort)); + mCounters.mEpskcStartSecureSessionErrors++; + ExitNow(); + } + + mEphemeralKeyTask.Post(); + + if (aTimeout == 0) + { + aTimeout = kDefaultEphemeralKeyTimeout; + } + + aTimeout = Min(aTimeout, kMaxEphemeralKeyTimeout); + + mEphemeralKeyTimer.Start(aTimeout); + mCounters.mEpskcActivations++; + + LogInfo("Allow ephemeral key for %lu msec on port %u", ToUlong(aTimeout), GetUdpPort()); + +exit: + switch (error) + { + case kErrorInvalidState: + mCounters.mEpskcInvalidBaStateErrors++; + break; + case kErrorInvalidArgs: + mCounters.mEpskcInvalidArgsErrors++; + break; + default: + break; + } + + return error; +} + +void BorderAgent::ClearEphemeralKey(void) +{ + VerifyOrExit(mUsingEphemeralKey); + + LogInfo("Clearing ephemeral key"); + + mCounters.mEpskcDeactivationClears++; + + switch (mState) + { + case kStateStarted: + RestartAfterRemovingEphemeralKey(); + break; + + case kStateStopped: + case kStateConnected: + case kStateAccepted: + // If a commissioner connection is currently active, we'll + // wait for it to disconnect or for the ephemeral key timeout + // or `kKeepAliveTimeout` to expire before removing the key + // and restarting the agent. + break; + } + +exit: + return; +} + +void BorderAgent::HandleEphemeralKeyTimeout(void) +{ + LogInfo("Ephemeral key timed out"); + mCounters.mEpskcDeactivationTimeouts++; + RestartAfterRemovingEphemeralKey(); +} + +void BorderAgent::InvokeEphemeralKeyCallback(void) { mEphemeralKeyCallback.InvokeIfSet(); } + +void BorderAgent::RestartAfterRemovingEphemeralKey(void) +{ + LogInfo("Removing ephemeral key and restarting agent"); + + Stop(); + IgnoreError(Start(mOldUdpPort)); +} + +void BorderAgent::HandleDtlsTransportClosed(void *aContext) +{ + reinterpret_cast(aContext)->HandleDtlsTransportClosed(); +} + +void BorderAgent::HandleDtlsTransportClosed(void) +{ + LogInfo("Reached max allowed connection attempts with ephemeral key"); + mCounters.mEpskcDeactivationMaxAttempts++; + RestartAfterRemovingEphemeralKey(); +} + +#endif // OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE + +//---------------------------------------------------------------------------------------------------------------------- +// `BorderAgent::CoapDtlsSession + +BorderAgent::CoapDtlsSession::CoapDtlsSession(Instance &aInstance, Dtls::Transport &aDtlsTransport) + : Coap::SecureSession(aInstance, aDtlsTransport) + , mIsActiveCommissioner(false) + , mTimer(aInstance, HandleTimer, this) + , mUdpReceiver(HandleUdpReceive, this) +{ + mCommissionerAloc.InitAsThreadOriginMeshLocal(); + + SetResourceHandler(&HandleResource); + SetConnectCallback(&HandleConnected, this); +} + +void BorderAgent::CoapDtlsSession::Cleanup(void) +{ + mTimer.Stop(); + IgnoreError(Get().RemoveReceiver(mUdpReceiver)); + Get().RemoveUnicastAddress(mCommissionerAloc); + + Coap::SecureSession::Cleanup(); +} + +bool BorderAgent::CoapDtlsSession::HandleResource(CoapBase &aCoapBase, + const char *aUriPath, + Coap::Message &aMessage, + const Ip6::MessageInfo &aMessageInfo) +{ + return static_cast(aCoapBase).HandleResource(aUriPath, aMessage, aMessageInfo); +} + +bool BorderAgent::CoapDtlsSession::HandleResource(const char *aUriPath, + Coap::Message &aMessage, + const Ip6::MessageInfo &aMessageInfo) +{ + bool didHandle = true; + Uri uri = UriFromPath(aUriPath); + + switch (uri) + { + case kUriCommissionerPetition: + IgnoreError(ForwardToLeader(aMessage, aMessageInfo, kUriLeaderPetition)); + break; + case kUriCommissionerKeepAlive: + HandleTmfCommissionerKeepAlive(aMessage, aMessageInfo); + break; + case kUriRelayTx: + HandleTmfRelayTx(aMessage); + break; + case kUriCommissionerGet: + case kUriActiveGet: + case kUriPendingGet: + HandleTmfDatasetGet(aMessage, uri); + break; + case kUriProxyTx: + HandleTmfProxyTx(aMessage); + break; + default: + didHandle = false; + break; + } + + return didHandle; +} + +void BorderAgent::CoapDtlsSession::HandleConnected(ConnectEvent aEvent, void *aContext) +{ + static_cast(aContext)->HandleConnected(aEvent); +} + +void BorderAgent::CoapDtlsSession::HandleConnected(ConnectEvent aEvent) +{ + if (aEvent == kConnected) + { + LogInfo("SecureSession connected"); + mTimer.Start(kKeepAliveTimeout); + Get().HandleSessionConnected(*this); + } + else + { + LogInfo("SecureSession disconnected"); + IgnoreError(Get().RemoveReceiver(mUdpReceiver)); + Get().RemoveUnicastAddress(mCommissionerAloc); + + Get().HandleSessionDisconnected(*this, aEvent); + } +} + void BorderAgent::CoapDtlsSession::HandleTmfCommissionerKeepAlive(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { @@ -459,40 +716,22 @@ void BorderAgent::CoapDtlsSession::HandleCoapResponse(const ForwardContext &aFor SuccessOrExit(error = aForwardContext.ToHeader(*message, aResponse->GetCode())); - if (aResponse->GetLength() > aResponse->GetOffset()) - { - SuccessOrExit(error = message->SetPayloadMarker()); - } - - SuccessOrExit(error = ForwardToCommissioner(*message, *aResponse)); - -exit: - - if (error != kErrorNone) - { - FreeMessage(message); - - LogWarn("Commissioner request[%u] failed: %s", aForwardContext.mMessageId, ErrorToString(error)); - - SendErrorMessage(aForwardContext, error); - } -} - -void BorderAgent::HandleCommissionerPetitionAccepted(CoapDtlsSession &aSesssion) -{ - OT_UNUSED_VARIABLE(aSesssion); - - mState = kStateAccepted; - -#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE - if (mUsingEphemeralKey) + if (aResponse->GetLength() > aResponse->GetOffset()) { - mCounters.mEpskcCommissionerPetitions++; + SuccessOrExit(error = message->SetPayloadMarker()); } - else -#endif + + SuccessOrExit(error = ForwardToCommissioner(*message, *aResponse)); + +exit: + + if (error != kErrorNone) { - mCounters.mPskcCommissionerPetitions++; + FreeMessage(message); + + LogWarn("Commissioner request[%u] failed: %s", aForwardContext.mMessageId, ErrorToString(error)); + + SendErrorMessage(aForwardContext, error); } } @@ -607,53 +846,6 @@ void BorderAgent::CoapDtlsSession::SendErrorMessage(const Coap::Message &aReques LogWarnOnError(error, "send error CoAP message"); } -Coap::Message::Code BorderAgent::CoapCodeFromError(Error aError) -{ - Coap::Message::Code code; - - switch (aError) - { - case kErrorNone: - code = Coap::kCodeChanged; - break; - - case kErrorParse: - code = Coap::kCodeBadRequest; - break; - - default: - code = Coap::kCodeInternalError; - break; - } - - return code; -} - -template <> void BorderAgent::HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) -{ - // This is from TMF agent. - - OT_UNUSED_VARIABLE(aMessageInfo); - - Coap::Message *message = nullptr; - Error error = kErrorNone; - - VerifyOrExit(mState != kStateStopped); - - VerifyOrExit(aMessage.IsNonConfirmablePostRequest(), error = kErrorDrop); - - VerifyOrExit(mCoapDtlsSession != nullptr); - - message = mCoapDtlsSession->NewPriorityNonConfirmablePostMessage(kUriRelayRx); - VerifyOrExit(message != nullptr, error = kErrorNoBufs); - - SuccessOrExit(error = mCoapDtlsSession->ForwardToCommissioner(*message, aMessage)); - LogInfo("Sent to commissioner on RelayRx (c/rx)"); - -exit: - FreeMessageOnError(message, error); -} - void BorderAgent::CoapDtlsSession::HandleTmfProxyTx(Coap::Message &aMessage) { Error error = kErrorNone; @@ -761,198 +953,6 @@ void BorderAgent::CoapDtlsSession::HandleTmfDatasetGet(Coap::Message &aMessage, FreeMessageOnError(response, error); } -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Ephemeral Key - -#if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE - -Error BorderAgent::SetEphemeralKey(const char *aKeyString, uint32_t aTimeout, uint16_t aUdpPort) -{ - Error error = kErrorNone; - uint16_t length = StringLength(aKeyString, kMaxEphemeralKeyLength + 1); - - VerifyOrExit(mState == kStateStarted, error = kErrorInvalidState); - VerifyOrExit((length >= kMinEphemeralKeyLength) && (length <= kMaxEphemeralKeyLength), error = kErrorInvalidArgs); - - if (!mUsingEphemeralKey) - { - mOldUdpPort = GetUdpPort(); - } - - Stop(); - - // We set the `mUsingEphemeralKey` before `Start()` since - // callbacks (like `HandleConnected()`) may be invoked from - // `Start()` itself. - - mUsingEphemeralKey = true; - mDidConnectWithEphemeralKey = false; - - error = Start(aUdpPort, reinterpret_cast(aKeyString), static_cast(length)); - - if (error != kErrorNone) - { - mUsingEphemeralKey = false; - IgnoreError(Start(mOldUdpPort)); - mCounters.mEpskcStartSecureSessionErrors++; - ExitNow(); - } - - mEphemeralKeyTask.Post(); - - if (aTimeout == 0) - { - aTimeout = kDefaultEphemeralKeyTimeout; - } - - aTimeout = Min(aTimeout, kMaxEphemeralKeyTimeout); - - mEphemeralKeyTimer.Start(aTimeout); - mCounters.mEpskcActivations++; - - LogInfo("Allow ephemeral key for %lu msec on port %u", ToUlong(aTimeout), GetUdpPort()); - -exit: - switch (error) - { - case kErrorInvalidState: - mCounters.mEpskcInvalidBaStateErrors++; - break; - case kErrorInvalidArgs: - mCounters.mEpskcInvalidArgsErrors++; - break; - default: - break; - } - - return error; -} - -void BorderAgent::ClearEphemeralKey(void) -{ - VerifyOrExit(mUsingEphemeralKey); - - LogInfo("Clearing ephemeral key"); - - mCounters.mEpskcDeactivationClears++; - - switch (mState) - { - case kStateStarted: - RestartAfterRemovingEphemeralKey(); - break; - - case kStateStopped: - case kStateConnected: - case kStateAccepted: - // If a commissioner connection is currently active, we'll - // wait for it to disconnect or for the ephemeral key timeout - // or `kKeepAliveTimeout` to expire before removing the key - // and restarting the agent. - break; - } - -exit: - return; -} - -void BorderAgent::HandleEphemeralKeyTimeout(void) -{ - LogInfo("Ephemeral key timed out"); - mCounters.mEpskcDeactivationTimeouts++; - RestartAfterRemovingEphemeralKey(); -} - -void BorderAgent::InvokeEphemeralKeyCallback(void) { mEphemeralKeyCallback.InvokeIfSet(); } - -void BorderAgent::RestartAfterRemovingEphemeralKey(void) -{ - LogInfo("Removing ephemeral key and restarting agent"); - - Stop(); - IgnoreError(Start(mOldUdpPort)); -} - -void BorderAgent::HandleDtlsTransportClosed(void *aContext) -{ - reinterpret_cast(aContext)->HandleDtlsTransportClosed(); -} - -void BorderAgent::HandleDtlsTransportClosed(void) -{ - LogInfo("Reached max allowed connection attempts with ephemeral key"); - mCounters.mEpskcDeactivationMaxAttempts++; - RestartAfterRemovingEphemeralKey(); -} - -#endif // OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE - -//---------------------------------------------------------------------------------------------------------------------- -// `BorderAgent::CoapDtlsSession - -BorderAgent::CoapDtlsSession::CoapDtlsSession(Instance &aInstance, Dtls::Transport &aDtlsTransport) - : Coap::SecureSession(aInstance, aDtlsTransport) - , mIsActiveCommissioner(false) - , mTimer(aInstance, HandleTimer, this) - , mUdpReceiver(HandleUdpReceive, this) -{ - mCommissionerAloc.InitAsThreadOriginMeshLocal(); - - SetResourceHandler(&HandleResource); - SetConnectCallback(&HandleConnected, this); -} - -void BorderAgent::CoapDtlsSession::Cleanup(void) -{ - mTimer.Stop(); - IgnoreError(Get().RemoveReceiver(mUdpReceiver)); - Get().RemoveUnicastAddress(mCommissionerAloc); - - Coap::SecureSession::Cleanup(); -} - -bool BorderAgent::CoapDtlsSession::HandleResource(CoapBase &aCoapBase, - const char *aUriPath, - Coap::Message &aMessage, - const Ip6::MessageInfo &aMessageInfo) -{ - return static_cast(aCoapBase).HandleResource(aUriPath, aMessage, aMessageInfo); -} - -bool BorderAgent::CoapDtlsSession::HandleResource(const char *aUriPath, - Coap::Message &aMessage, - const Ip6::MessageInfo &aMessageInfo) -{ - bool didHandle = true; - Uri uri = UriFromPath(aUriPath); - - switch (uri) - { - case kUriCommissionerPetition: - IgnoreError(ForwardToLeader(aMessage, aMessageInfo, kUriLeaderPetition)); - break; - case kUriCommissionerKeepAlive: - HandleTmfCommissionerKeepAlive(aMessage, aMessageInfo); - break; - case kUriRelayTx: - HandleTmfRelayTx(aMessage); - break; - case kUriCommissionerGet: - case kUriActiveGet: - case kUriPendingGet: - HandleTmfDatasetGet(aMessage, uri); - break; - case kUriProxyTx: - HandleTmfProxyTx(aMessage); - break; - default: - didHandle = false; - break; - } - - return didHandle; -} - void BorderAgent::CoapDtlsSession::HandleTimer(Timer &aTimer) { static_cast(static_cast(aTimer).GetContext())->HandleTimer();