diff --git a/src/core/coap/coap_secure.cpp b/src/core/coap/coap_secure.cpp index 3a5cbdd66..1641fb057 100644 --- a/src/core/coap/coap_secure.cpp +++ b/src/core/coap/coap_secure.cpp @@ -138,12 +138,12 @@ otError CoapSecure::Connect(const Ip6::SockAddr &aSockAddr, ConnectedCallback aC bool CoapSecure::IsConnectionActive(void) { - return GetNetif().GetDtls().IsStarted(); + return GetNetif().GetDtls().GetState() != MeshCoP::Dtls::kStateStopped; } bool CoapSecure::IsConnected(void) { - return GetNetif().GetDtls().IsConnected(); + return GetNetif().GetDtls().GetState() == MeshCoP::Dtls::kStateConnected; } otError CoapSecure::Disconnect(void) @@ -258,7 +258,7 @@ void CoapSecure::HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo { ThreadNetif &netif = GetNetif(); - if (!netif.GetDtls().IsStarted()) + if (netif.GetDtls().GetState() == MeshCoP::Dtls::kStateStopped) { Ip6::SockAddr sockAddr; sockAddr.mAddress = aMessageInfo.GetPeerAddr(); @@ -287,7 +287,10 @@ void CoapSecure::HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo } #if OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER - netif.GetDtls().SetClientId(mPeerAddress.GetPeerAddr().mFields.m8, sizeof(mPeerAddress.GetPeerAddr().mFields)); + if (netif.GetDtls().GetState() == MeshCoP::Dtls::kStateConnecting) + { + netif.GetDtls().SetClientId(mPeerAddress.GetPeerAddr().mFields.m8, sizeof(mPeerAddress.GetPeerAddr().mFields)); + } #endif netif.GetDtls().Receive(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset()); diff --git a/src/core/meshcop/dtls.cpp b/src/core/meshcop/dtls.cpp index 257dbcc0c..d908684de 100644 --- a/src/core/meshcop/dtls.cpp +++ b/src/core/meshcop/dtls.cpp @@ -55,9 +55,9 @@ namespace MeshCoP { Dtls::Dtls(Instance &aInstance) : InstanceLocator(aInstance) + , mState(kStateStopped) , mPskLength(0) , mVerifyPeerCertificate(true) - , mStarted(false) , mTimer(aInstance, &Dtls::HandleTimer, this) , mTimerIntermediate(0) , mTimerSet(false) @@ -68,7 +68,6 @@ Dtls::Dtls(Instance &aInstance) , mReceiveHandler(NULL) , mSendHandler(NULL) , mContext(NULL) - , mGuardTimerSet(false) , mMessageSubType(Message::kSubTypeNone) , mMessageDefaultSubType(Message::kSubTypeNone) { @@ -159,7 +158,7 @@ otError Dtls::Start(bool aClient, int rval; // do not handle new connection before guard time expired - VerifyOrExit(mGuardTimerSet == false, rval = MBEDTLS_ERR_SSL_TIMEOUT); + VerifyOrExit(mState == kStateStopped, rval = MBEDTLS_ERR_SSL_TIMEOUT); mbedtls_ssl_init(&mSsl); mbedtls_ssl_config_init(&mConf); @@ -250,7 +249,7 @@ otError Dtls::Start(bool aClient, mContext = aContext; mReceiveMessage = NULL; mMessageSubType = Message::kSubTypeNone; - mStarted = true; + mState = kStateConnecting; if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8) { @@ -333,33 +332,28 @@ void Dtls::SetSslAuthMode(bool aVerifyPeerCertificate) otError Dtls::Stop(void) { + VerifyOrExit((mState == kStateConnecting) || (mState == kStateConnected)); + mbedtls_ssl_close_notify(&mSsl); Close(); +exit: return OT_ERROR_NONE; } void Dtls::Close(void) { - // guard time, that the possible close notify - // not open an invalid (new) connection - mGuardTimerSet = true; + assert((mState == kStateConnecting) || (mState == kStateConnected)); + + mState = kStateCloseNotify; mTimer.Start(kGuardTimeNewConnectionMilli); - VerifyOrExit(mStarted); - mStarted = false; + FreeMbedtls(); + if (mConnectedHandler != NULL) { mConnectedHandler(mContext, false); } - -exit: - return; -} - -bool Dtls::IsStarted(void) -{ - return mStarted; } otError Dtls::SetPsk(const uint8_t *aPsk, uint8_t aPskLength) @@ -451,7 +445,7 @@ otError Dtls::GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLe { otError error = OT_ERROR_NONE; - VerifyOrExit(IsConnected() == true, error = OT_ERROR_INVALID_STATE); + VerifyOrExit(mState == kStateConnected, error = OT_ERROR_INVALID_STATE); VerifyOrExit(mbedtls_base64_encode(aPeerCert, aCertBufferSize, aCertLength, mSsl.session->peer_cert->raw.p, mSsl.session->peer_cert->raw.len) == 0, @@ -472,11 +466,6 @@ otError Dtls::SetClientId(const uint8_t *aClientId, uint8_t aLength) } #endif // OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER -bool Dtls::IsConnected(void) -{ - return mSsl.state == MBEDTLS_SSL_HANDSHAKE_OVER; -} - otError Dtls::Send(Message &aMessage, uint16_t aLength) { otError error = OT_ERROR_NONE; @@ -710,14 +699,21 @@ void Dtls::HandleTimer(Timer &aTimer) void Dtls::HandleTimer(void) { - if (!mGuardTimerSet) + switch (mState) { + case kStateConnecting: + case kStateConnected: Process(); - } - else - { - mGuardTimerSet = false; + break; + + case kStateCloseNotify: + mState = kStateStopped; mTimer.Stop(); + break; + + default: + assert(false); + break; } } @@ -727,15 +723,20 @@ void Dtls::Process(void) bool shouldClose = false; int rval; - while (mStarted) + while ((mState == kStateConnecting) || (mState == kStateConnected)) { - if (mSsl.state != MBEDTLS_SSL_HANDSHAKE_OVER) + if (mState == kStateConnecting) { rval = mbedtls_ssl_handshake(&mSsl); - if ((mSsl.state == MBEDTLS_SSL_HANDSHAKE_OVER) && (mConnectedHandler != NULL)) + if (mSsl.state == MBEDTLS_SSL_HANDSHAKE_OVER) { - mConnectedHandler(mContext, true); + mState = kStateConnected; + + if (mConnectedHandler != NULL) + { + mConnectedHandler(mContext, true); + } } } else diff --git a/src/core/meshcop/dtls.hpp b/src/core/meshcop/dtls.hpp index 3dbeb3007..1c383eefc 100644 --- a/src/core/meshcop/dtls.hpp +++ b/src/core/meshcop/dtls.hpp @@ -79,6 +79,14 @@ public: #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE }; + enum State + { + kStateStopped = 0, + kStateConnecting, + kStateConnected, + kStateCloseNotify, + }; + /** * This constructor initializes the DTLS object. * @@ -148,12 +156,15 @@ public: otError Stop(void); /** - * This method indicates whether or not the DTLS service is active. + * This method returns the DTLS connection state. * - * @returns true if the DTLS service is active, false otherwise. + * @retval kStateStopped If the DTLS service has not been started. + * @retval kStateConnecting If the DTLS service is establishing a connection. + * @retval kStateConnected If the DTLS service has a connection established. + * @retval kStateCloseNotify If the DTLS service is closing a connection. * */ - bool IsStarted(void); + State GetState(void) const { return mState; } /** * This method sets the PSK. @@ -267,15 +278,6 @@ public: otError SetClientId(const uint8_t *aClientId, uint8_t aLength); #endif // OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER - /** - * This method indicates whether or not the DTLS session is connected. - * - * @retval TRUE The DTLS session is connected. - * @retval FALSE The DTLS session is not connected. - * - */ - bool IsConnected(void); - /** * This method sends data within the DTLS session. * @@ -364,6 +366,8 @@ private: void Close(void); void Process(void); + State mState; + int mCipherSuites[2]; uint8_t mPsk[kPskMaxLength]; uint8_t mPskLength; @@ -401,8 +405,6 @@ private: mbedtls_ssl_cookie_ctx mCookieCtx; #endif - bool mStarted; - TimerMilli mTimer; uint32_t mTimerIntermediate; bool mTimerSet; @@ -415,7 +417,6 @@ private: ReceiveHandler mReceiveHandler; SendHandler mSendHandler; void * mContext; - bool mGuardTimerSet; uint8_t mMessageSubType; uint8_t mMessageDefaultSubType;