mirror of
https://github.com/espressif/openthread.git
synced 2026-09-15 21:50:08 +00:00
[dtls] refine CoAP secure and DTLS (#3632)
`CoapSecure` is always used by joiner, border agent or commissioner. DTLS should not be shared with the application `CoapSecure`. This commit includes the following changes: * allow multiple DTLS by using `TimerMilliContext` * move `CoAP::mSocket` into `Dtls` * move `ThreadNetif::mDtls` into `CoapSecure` * remove unnecessary getters of `Dtls` and `CoapSecure`
This commit is contained in:
@@ -78,21 +78,19 @@ typedef void (*otHandleCoapSecureClientConnect)(bool aConnected, void *aContext)
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aPort The local UDP port to bind to.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the CoAP Secure server.
|
||||
*
|
||||
*/
|
||||
otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort, void *aContext);
|
||||
otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort);
|
||||
|
||||
/**
|
||||
* This function stops the CoAP Secure server.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully stopped the CoAP Secure server.
|
||||
*/
|
||||
otError otCoapSecureStop(otInstance *aInstance);
|
||||
void otCoapSecureStop(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* This method sets the Pre-Shared Key (PSK) and cipher suite
|
||||
|
||||
@@ -147,7 +147,7 @@ otError CoapSecure::Process(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
otCoapSecureSetSslAuthMode(mInterpreter.mInstance, mVerifyPeerCert);
|
||||
SuccessOrExit(error = otCoapSecureStart(mInterpreter.mInstance, OT_DEFAULT_COAP_SECURE_PORT, this));
|
||||
SuccessOrExit(error = otCoapSecureStart(mInterpreter.mInstance, OT_DEFAULT_COAP_SECURE_PORT));
|
||||
otCoapSecureSetClientConnectedCallback(mInterpreter.mInstance, &CoapSecure::HandleClientConnect, this);
|
||||
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
|
||||
otCoapSecureSetDefaultHandler(mInterpreter.mInstance, &CoapSecure::DefaultHandle, this);
|
||||
@@ -274,7 +274,7 @@ otError CoapSecure::Process(int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = Stop());
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[0], "help") == 0)
|
||||
@@ -311,13 +311,11 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError CoapSecure::Stop(void)
|
||||
void CoapSecure::Stop(void)
|
||||
{
|
||||
otError error = OT_ERROR_ABORT;
|
||||
otCoapRemoveResource(mInterpreter.mInstance, &mResource);
|
||||
error = otCoapSecureStop(mInterpreter.mInstance);
|
||||
mInterpreter.mServer->OutputFormat("Coap Secure service stopped: ");
|
||||
return error;
|
||||
otCoapSecureStop(mInterpreter.mInstance);
|
||||
mInterpreter.mServer->OutputFormat("Coap Secure service stopped");
|
||||
}
|
||||
|
||||
void OTCALL CoapSecure::HandleClientConnect(bool aConnected, void *aContext)
|
||||
@@ -342,14 +340,8 @@ void CoapSecure::HandleClientConnect(bool aConnected)
|
||||
else
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("CoAP Secure disconnected before stop.\r\n> ");
|
||||
if (Stop() == OT_ERROR_NONE)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat(" Done\r\n> ");
|
||||
}
|
||||
else
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat(" With error\r\n> ");
|
||||
}
|
||||
Stop();
|
||||
mInterpreter.mServer->OutputFormat(" Done\r\n> ");
|
||||
mShutdownFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
|
||||
otError ProcessRequest(int argc, char *argv[]);
|
||||
|
||||
otError Stop(void);
|
||||
void Stop(void);
|
||||
|
||||
static void OTCALL HandleServerResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
void HandleServerResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
|
||||
using namespace ot;
|
||||
|
||||
otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort, void *aContext)
|
||||
otError otCoapSecureStart(otInstance *aInstance, uint16_t aPort)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().Start(aPort, NULL, aContext);
|
||||
return instance.GetApplicationCoapSecure().Start(aPort);
|
||||
}
|
||||
|
||||
otError otCoapSecureSetCertificate(otInstance * aInstance,
|
||||
@@ -184,11 +184,11 @@ bool otCoapSecureIsConnectionActive(otInstance *aInstance)
|
||||
return instance.GetApplicationCoapSecure().IsConnectionActive();
|
||||
}
|
||||
|
||||
otError otCoapSecureStop(otInstance *aInstance)
|
||||
void otCoapSecureStop(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.GetApplicationCoapSecure().Stop();
|
||||
instance.GetApplicationCoapSecure().Stop();
|
||||
}
|
||||
|
||||
otError otCoapSecureSendRequest(otInstance * aInstance,
|
||||
|
||||
+32
-182
@@ -49,35 +49,37 @@ namespace Coap {
|
||||
|
||||
CoapSecure::CoapSecure(Instance &aInstance, bool aLayerTwoSecurity)
|
||||
: CoapBase(aInstance, &CoapSecure::Send)
|
||||
, mDtls(aInstance, aLayerTwoSecurity)
|
||||
, mConnectedCallback(NULL)
|
||||
, mConnectedContext(NULL)
|
||||
, mTransportCallback(NULL)
|
||||
, mTransportContext(NULL)
|
||||
, mTransmitQueue()
|
||||
, mTransmitTask(aInstance, &CoapSecure::HandleTransmit, this)
|
||||
, mSocket(aInstance.GetThreadNetif().GetIp6().GetUdp())
|
||||
, mLayerTwoSecurity(aLayerTwoSecurity)
|
||||
{
|
||||
}
|
||||
|
||||
otError CoapSecure::Start(uint16_t aPort, TransportCallback aCallback, void *aContext)
|
||||
otError CoapSecure::Start(uint16_t aPort)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
mTransportCallback = aCallback;
|
||||
mTransportContext = aContext;
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
mConnectedCallback = NULL;
|
||||
mConnectedContext = NULL;
|
||||
|
||||
// Passing mTransportCallback means that we do not want to use socket
|
||||
// to transmit/receive messages, so do not open it in that case.
|
||||
if (mTransportCallback == NULL)
|
||||
{
|
||||
Ip6::SockAddr sockaddr;
|
||||
SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
|
||||
SuccessOrExit(error = mDtls.Bind(aPort));
|
||||
|
||||
sockaddr.mPort = aPort;
|
||||
SuccessOrExit(error = mSocket.Open(&CoapSecure::HandleUdpReceive, this));
|
||||
VerifyOrExit((error = mSocket.Bind(sockaddr)) == OT_ERROR_NONE, mSocket.Close());
|
||||
}
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError CoapSecure::Start(MeshCoP::Dtls::TransportCallback aCallback, void *aContext)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
mConnectedCallback = NULL;
|
||||
mConnectedContext = NULL;
|
||||
|
||||
SuccessOrExit(error = mDtls.Open(&CoapSecure::HandleDtlsReceive, &CoapSecure::HandleDtlsConnected, this));
|
||||
SuccessOrExit(error = mDtls.Bind(aCallback, aContext));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -89,16 +91,9 @@ void CoapSecure::SetConnectedCallback(ConnectedCallback aCallback, void *aContex
|
||||
mConnectedContext = aContext;
|
||||
}
|
||||
|
||||
otError CoapSecure::Stop(void)
|
||||
void CoapSecure::Stop(void)
|
||||
{
|
||||
otError error;
|
||||
|
||||
SuccessOrExit(error = mSocket.Close());
|
||||
|
||||
if (IsConnectionActive())
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
mDtls.Stop();
|
||||
|
||||
for (ot::Message *message = mTransmitQueue.GetHead(); message != NULL; message = message->GetNext())
|
||||
{
|
||||
@@ -106,66 +101,20 @@ otError CoapSecure::Stop(void)
|
||||
message->Free();
|
||||
}
|
||||
|
||||
mTransportCallback = NULL;
|
||||
mTransportContext = NULL;
|
||||
|
||||
ClearRequestsAndResponses();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError CoapSecure::Connect(const Ip6::SockAddr &aSockAddr, ConnectedCallback aCallback, void *aContext)
|
||||
{
|
||||
memcpy(&mPeerAddress.mPeerAddr, &aSockAddr.mAddress, sizeof(mPeerAddress.mPeerAddr));
|
||||
mPeerAddress.mPeerPort = aSockAddr.mPort;
|
||||
|
||||
if (aSockAddr.GetAddress().IsLinkLocal() || aSockAddr.GetAddress().IsMulticast())
|
||||
{
|
||||
mPeerAddress.mInterfaceId = aSockAddr.mScopeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPeerAddress.mInterfaceId = 0;
|
||||
}
|
||||
|
||||
mConnectedCallback = aCallback;
|
||||
mConnectedContext = aContext;
|
||||
|
||||
return GetNetif().GetDtls().Start(true, &CoapSecure::HandleDtlsConnected, &CoapSecure::HandleDtlsReceive,
|
||||
&CoapSecure::HandleDtlsSend, this);
|
||||
}
|
||||
|
||||
bool CoapSecure::IsConnectionActive(void)
|
||||
{
|
||||
return GetNetif().GetDtls().GetState() != MeshCoP::Dtls::kStateStopped;
|
||||
}
|
||||
|
||||
bool CoapSecure::IsConnected(void)
|
||||
{
|
||||
return GetNetif().GetDtls().GetState() == MeshCoP::Dtls::kStateConnected;
|
||||
}
|
||||
|
||||
void CoapSecure::Disconnect(void)
|
||||
{
|
||||
GetNetif().GetDtls().Stop();
|
||||
|
||||
// Disconnect from previous peer by connecting to any address
|
||||
{
|
||||
otError error = mSocket.Connect(Ip6::SockAddr());
|
||||
|
||||
assert(error == OT_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
MeshCoP::Dtls &CoapSecure::GetDtls(void)
|
||||
{
|
||||
return GetNetif().GetDtls();
|
||||
return mDtls.Connect(aSockAddr);
|
||||
}
|
||||
|
||||
otError CoapSecure::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
|
||||
{
|
||||
return GetNetif().GetDtls().SetPsk(aPsk, aPskLength);
|
||||
return mDtls.SetPsk(aPsk, aPskLength);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
@@ -176,12 +125,12 @@ otError CoapSecure::SetCertificate(const uint8_t *aX509Cert,
|
||||
const uint8_t *aPrivateKey,
|
||||
uint32_t aPrivateKeyLength)
|
||||
{
|
||||
return GetNetif().GetDtls().SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
|
||||
return mDtls.SetCertificate(aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
|
||||
}
|
||||
|
||||
otError CoapSecure::SetCaCertificateChain(const uint8_t *aX509CaCertificateChain, uint32_t aX509CaCertChainLength)
|
||||
{
|
||||
return GetNetif().GetDtls().SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength);
|
||||
return mDtls.SetCaCertificateChain(aX509CaCertificateChain, aX509CaCertChainLength);
|
||||
}
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
|
||||
@@ -191,14 +140,14 @@ otError CoapSecure::SetPreSharedKey(const uint8_t *aPsk,
|
||||
const uint8_t *aPskIdentity,
|
||||
uint16_t aPskIdLength)
|
||||
{
|
||||
return GetNetif().GetDtls().SetPreSharedKey(aPsk, aPskLength, aPskIdentity, aPskIdLength);
|
||||
return mDtls.SetPreSharedKey(aPsk, aPskLength, aPskIdentity, aPskIdLength);
|
||||
}
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
|
||||
#ifdef MBEDTLS_BASE64_C
|
||||
otError CoapSecure::GetPeerCertificateBase64(unsigned char *aPeerCert, size_t *aCertLength, size_t aCertBufferSize)
|
||||
{
|
||||
return GetNetif().GetDtls().GetPeerCertificateBase64(aPeerCert, aCertLength, aCertBufferSize);
|
||||
return mDtls.GetPeerCertificateBase64(aPeerCert, aCertLength, aCertBufferSize);
|
||||
}
|
||||
#endif // MBEDTLS_BASE64_C
|
||||
|
||||
@@ -210,7 +159,7 @@ void CoapSecure::SetClientConnectedCallback(ConnectedCallback aCallback, void *a
|
||||
|
||||
void CoapSecure::SetSslAuthMode(bool aVerifyPeerCertificate)
|
||||
{
|
||||
GetNetif().GetDtls().SetSslAuthMode(aVerifyPeerCertificate);
|
||||
mDtls.SetSslAuthMode(aVerifyPeerCertificate);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
@@ -221,7 +170,7 @@ otError CoapSecure::SendMessage(Message &aMessage, otCoapResponseHandler aHandle
|
||||
|
||||
VerifyOrExit(IsConnected(), error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
error = CoapBase::SendMessage(aMessage, mPeerAddress, aHandler, aContext);
|
||||
error = CoapBase::SendMessage(aMessage, mDtls.GetPeerAddress(), aHandler, aContext);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -238,6 +187,7 @@ otError CoapSecure::SendMessage(Message & aMessage,
|
||||
otError CoapSecure::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aMessageInfo);
|
||||
|
||||
otError error;
|
||||
|
||||
SuccessOrExit(error = mTransmitQueue.Enqueue(aMessage));
|
||||
@@ -247,57 +197,6 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapSecure::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
static_cast<CoapSecure *>(aContext)->HandleUdpReceive(*static_cast<ot::Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
void CoapSecure::HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadNetif &netif = GetNetif();
|
||||
|
||||
if (netif.GetDtls().GetState() == MeshCoP::Dtls::kStateStopped)
|
||||
{
|
||||
Ip6::SockAddr sockAddr;
|
||||
sockAddr.mAddress = aMessageInfo.GetPeerAddr();
|
||||
sockAddr.mPort = aMessageInfo.GetPeerPort();
|
||||
mSocket.Connect(sockAddr);
|
||||
|
||||
mPeerAddress.SetPeerAddr(aMessageInfo.GetPeerAddr());
|
||||
mPeerAddress.SetPeerPort(aMessageInfo.GetPeerPort());
|
||||
mPeerAddress.SetInterfaceId(aMessageInfo.GetInterfaceId());
|
||||
|
||||
if (netif.IsUnicastAddress(aMessageInfo.GetSockAddr()))
|
||||
{
|
||||
mPeerAddress.SetSockAddr(aMessageInfo.GetSockAddr());
|
||||
}
|
||||
|
||||
mPeerAddress.SetSockPort(aMessageInfo.GetSockPort());
|
||||
|
||||
VerifyOrExit(netif.GetDtls().Start(false, &CoapSecure::HandleDtlsConnected, &CoapSecure::HandleDtlsReceive,
|
||||
CoapSecure::HandleDtlsSend, this) == OT_ERROR_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Once DTLS session is started, communicate only with a peer.
|
||||
VerifyOrExit((mPeerAddress.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
|
||||
(mPeerAddress.GetPeerPort() == aMessageInfo.GetPeerPort()));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER
|
||||
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());
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected)
|
||||
{
|
||||
return static_cast<CoapSecure *>(aContext)->HandleDtlsConnected(aConnected);
|
||||
@@ -305,14 +204,6 @@ void CoapSecure::HandleDtlsConnected(void *aContext, bool aConnected)
|
||||
|
||||
void CoapSecure::HandleDtlsConnected(bool aConnected)
|
||||
{
|
||||
if (!aConnected)
|
||||
{
|
||||
// Disconnect from previous peer by connecting to any address
|
||||
otError error = mSocket.Connect(Ip6::SockAddr());
|
||||
|
||||
assert(error == OT_ERROR_NONE);
|
||||
}
|
||||
|
||||
if (mConnectedCallback != NULL)
|
||||
{
|
||||
mConnectedCallback(aConnected, mConnectedContext);
|
||||
@@ -332,7 +223,7 @@ void CoapSecure::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength)
|
||||
NULL);
|
||||
SuccessOrExit(message->Append(aBuf, aLength));
|
||||
|
||||
CoapBase::Receive(*message, mPeerAddress);
|
||||
CoapBase::Receive(*message, mDtls.GetPeerAddress());
|
||||
|
||||
exit:
|
||||
|
||||
@@ -342,47 +233,6 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
otError CoapSecure::HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
|
||||
{
|
||||
return static_cast<CoapSecure *>(aContext)->HandleDtlsSend(aBuf, aLength, aMessageSubType);
|
||||
}
|
||||
|
||||
otError CoapSecure::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
ot::Message *message = NULL;
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
message->SetSubType(aMessageSubType);
|
||||
message->SetLinkSecurityEnabled(mLayerTwoSecurity);
|
||||
|
||||
SuccessOrExit(error = message->Append(aBuf, aLength));
|
||||
|
||||
// Set message sub type in case Joiner Finalize Response is appended to the message.
|
||||
if (aMessageSubType != Message::kSubTypeNone)
|
||||
{
|
||||
message->SetSubType(aMessageSubType);
|
||||
}
|
||||
|
||||
if (mTransportCallback)
|
||||
{
|
||||
SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mPeerAddress));
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, mPeerAddress));
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapSecure::HandleTransmit(Tasklet &aTasklet)
|
||||
{
|
||||
static_cast<CoapSecure *>(static_cast<TaskletContext &>(aTasklet).GetContext())->HandleTransmit();
|
||||
@@ -401,7 +251,7 @@ void CoapSecure::HandleTransmit(void)
|
||||
mTransmitTask.Post();
|
||||
}
|
||||
|
||||
SuccessOrExit(error = GetDtls().Send(*message, message->GetLength()));
|
||||
SuccessOrExit(error = mDtls.Send(*message, message->GetLength()));
|
||||
|
||||
exit:
|
||||
if (error != OT_ERROR_NONE)
|
||||
|
||||
@@ -57,16 +57,6 @@ public:
|
||||
*/
|
||||
typedef void (*ConnectedCallback)(bool aConnected, void *aContext);
|
||||
|
||||
/**
|
||||
* This function pointer is called when secure CoAP server want to send encrypted message.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aMessage A reference to the message to send.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
*
|
||||
*/
|
||||
typedef otError (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
@@ -80,15 +70,24 @@ public:
|
||||
* This method starts the secure CoAP agent.
|
||||
*
|
||||
* @param[in] aPort The local UDP port to bind to.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the CoAP agent.
|
||||
* @retval OT_ERROR_ALREADY Already started.
|
||||
*
|
||||
*/
|
||||
otError Start(uint16_t aPort);
|
||||
|
||||
/**
|
||||
* This method starts the secure CoAP agent, but do not use socket to transmit/receive messages.
|
||||
*
|
||||
* @param[in] aCallback A pointer to a function for sending messages.
|
||||
* If NULL, the message is sent directly to the socket.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the CoAP agent.
|
||||
* @retval OT_ERROR_ALREADY Already started.
|
||||
*
|
||||
*/
|
||||
otError Start(uint16_t aPort, TransportCallback aCallback = NULL, void *aContext = NULL);
|
||||
otError Start(MeshCoP::Dtls::TransportCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* This method sets connected callback of this secure CoAP agent.
|
||||
@@ -102,10 +101,8 @@ public:
|
||||
/**
|
||||
* This method stops the secure CoAP agent.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully stopped the secure CoAP agent.
|
||||
*
|
||||
*/
|
||||
otError Stop(void);
|
||||
void Stop(void);
|
||||
|
||||
/**
|
||||
* This method initializes DTLS session with a peer.
|
||||
@@ -126,7 +123,7 @@ public:
|
||||
* @retval FALSE If DTLS session is not active.
|
||||
*
|
||||
*/
|
||||
bool IsConnectionActive(void);
|
||||
bool IsConnectionActive(void) { return mDtls.IsConnectionActive(); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the DTLS session is connected.
|
||||
@@ -135,13 +132,13 @@ public:
|
||||
* @retval FALSE The DTLS session is not connected.
|
||||
*
|
||||
*/
|
||||
bool IsConnected(void);
|
||||
bool IsConnected(void) { return mDtls.IsConnected(); }
|
||||
|
||||
/**
|
||||
* This method stops the DTLS connection.
|
||||
*
|
||||
*/
|
||||
void Disconnect(void);
|
||||
void Disconnect(void) { mDtls.Close(); }
|
||||
|
||||
/**
|
||||
* This method returns a reference to the DTLS object.
|
||||
@@ -149,7 +146,7 @@ public:
|
||||
* @returns A reference to the DTLS object.
|
||||
*
|
||||
*/
|
||||
MeshCoP::Dtls &GetDtls(void);
|
||||
MeshCoP::Dtls &GetDtls(void) { return mDtls; }
|
||||
|
||||
/**
|
||||
* This method sets the PSK.
|
||||
@@ -306,7 +303,10 @@ public:
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
*
|
||||
*/
|
||||
void HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleUdpReceive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
return mDtls.HandleUdpReceive(aMessage, aMessageInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the DTLS session's peer address.
|
||||
@@ -314,7 +314,7 @@ public:
|
||||
* @return DTLS session's message info.
|
||||
*
|
||||
*/
|
||||
const Ip6::MessageInfo &GetPeerMessageInfo(void) const { return mPeerAddress; }
|
||||
const Ip6::MessageInfo &GetPeerAddress(void) const { return mDtls.GetPeerAddress(); }
|
||||
|
||||
private:
|
||||
static otError Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
@@ -329,24 +329,14 @@ private:
|
||||
static void HandleDtlsReceive(void *aContext, uint8_t *aBuf, uint16_t aLength);
|
||||
void HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
static otError HandleDtlsSend(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
|
||||
otError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
|
||||
|
||||
static void HandleTransmit(Tasklet &aTasklet);
|
||||
void HandleTransmit(void);
|
||||
|
||||
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
|
||||
Ip6::MessageInfo mPeerAddress;
|
||||
MeshCoP::Dtls mDtls;
|
||||
ConnectedCallback mConnectedCallback;
|
||||
void * mConnectedContext;
|
||||
TransportCallback mTransportCallback;
|
||||
void * mTransportContext;
|
||||
MessageQueue mTransmitQueue;
|
||||
TaskletContext mTransmitTask;
|
||||
Ip6::UdpSocket mSocket;
|
||||
|
||||
bool mLayerTwoSecurity : 1;
|
||||
};
|
||||
|
||||
} // namespace Coap
|
||||
|
||||
@@ -623,18 +623,6 @@ template <> inline Dns::Client &Instance::Get(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
template <> inline MeshCoP::Dtls &Instance::Get(void)
|
||||
{
|
||||
return GetThreadNetif().GetDtls();
|
||||
}
|
||||
|
||||
template <> inline Coap::CoapSecure &Instance::Get(void)
|
||||
{
|
||||
return GetThreadNetif().GetCoapSecure();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_DHCP6_CLIENT
|
||||
template <> inline Dhcp6::Dhcp6Client &Instance::Get(void)
|
||||
{
|
||||
|
||||
@@ -164,7 +164,7 @@ static void SendErrorMessage(Coap::CoapSecure &aCoapSecure, ForwardContext &aFor
|
||||
|
||||
VerifyOrExit((message = NewMeshCoPMessage(aCoapSecure)) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
aForwardContext.ToHeader(*message, CoapCodeFromError(error));
|
||||
SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerMessageInfo()));
|
||||
SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerAddress()));
|
||||
|
||||
exit:
|
||||
if (error != OT_ERROR_NONE)
|
||||
@@ -197,7 +197,7 @@ static void SendErrorMessage(Coap::CoapSecure &aCoapSecure, const Coap::Message
|
||||
message->SetMessageId(aSeparate ? 0 : aRequest.GetMessageId());
|
||||
message->SetToken(aRequest.GetToken(), aRequest.GetTokenLength());
|
||||
|
||||
SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerMessageInfo()));
|
||||
SuccessOrExit(error = aCoapSecure.SendMessage(*message, aCoapSecure.GetPeerAddress()));
|
||||
|
||||
exit:
|
||||
if (error != OT_ERROR_NONE)
|
||||
@@ -436,7 +436,7 @@ bool BorderAgent::HandleUdpReceive(const Message &aMessage, const Ip6::MessageIn
|
||||
SuccessOrExit(error = message->Append(&tlv, sizeof(tlv)));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = netif.GetCoapSecure().SendMessage(*message, netif.GetCoapSecure().GetPeerMessageInfo()));
|
||||
SuccessOrExit(error = netif.GetCoapSecure().SendMessage(*message, netif.GetCoapSecure().GetPeerAddress()));
|
||||
|
||||
otLogInfoMeshCoP("Sent to commissioner on %s", OT_URI_PATH_PROXY_RX);
|
||||
|
||||
@@ -487,7 +487,7 @@ otError BorderAgent::ForwardToCommissioner(Coap::Message &aNewMessage, const Mes
|
||||
SuccessOrExit(error = aNewMessage.SetLength(offset + aMessage.GetLength() - aMessage.GetOffset()));
|
||||
aMessage.CopyTo(aMessage.GetOffset(), offset, aMessage.GetLength() - aMessage.GetOffset(), aNewMessage);
|
||||
|
||||
SuccessOrExit(error = netif.GetCoapSecure().SendMessage(aNewMessage, netif.GetCoapSecure().GetPeerMessageInfo()));
|
||||
SuccessOrExit(error = netif.GetCoapSecure().SendMessage(aNewMessage, netif.GetCoapSecure().GetPeerAddress()));
|
||||
|
||||
otLogInfoMeshCoP("Sent to commissioner");
|
||||
|
||||
@@ -698,7 +698,7 @@ void BorderAgent::HandleTimeout(void)
|
||||
|
||||
otError BorderAgent::Stop(void)
|
||||
{
|
||||
otError error;
|
||||
otError error = OT_ERROR_NONE;
|
||||
ThreadNetif & netif = GetNetif();
|
||||
Coap::CoapSecure &coaps = netif.GetCoapSecure();
|
||||
Coap::Coap & coap = netif.GetCoap();
|
||||
@@ -720,8 +720,7 @@ otError BorderAgent::Stop(void)
|
||||
|
||||
coap.RemoveResource(mRelayReceive);
|
||||
|
||||
error = coaps.Stop();
|
||||
assert(error == OT_ERROR_NONE);
|
||||
coaps.Stop();
|
||||
|
||||
SetState(OT_BORDER_AGENT_STATE_STOPPED);
|
||||
|
||||
|
||||
@@ -62,7 +62,8 @@ public:
|
||||
/**
|
||||
* This method starts the Border Agent service.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the Border Agent service.
|
||||
* @retval OT_ERROR_NONE Successfully started the Border Agent service.
|
||||
* @retval OT_ERROR_ALREADY Already started.
|
||||
*
|
||||
*/
|
||||
otError Start(void);
|
||||
|
||||
@@ -107,7 +107,7 @@ otError Commissioner::Start(void)
|
||||
|
||||
VerifyOrExit(mState == OT_COMMISSIONER_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);
|
||||
|
||||
SuccessOrExit(error = GetNetif().GetCoapSecure().Start(OPENTHREAD_CONFIG_JOINER_UDP_PORT, SendRelayTransmit, this));
|
||||
SuccessOrExit(error = GetNetif().GetCoapSecure().Start(SendRelayTransmit, this));
|
||||
|
||||
mState = OT_COMMISSIONER_STATE_PETITION;
|
||||
mTransmitAttempts = 0;
|
||||
@@ -135,7 +135,7 @@ otError Commissioner::Stop(void)
|
||||
|
||||
mTimer.Stop();
|
||||
|
||||
GetNetif().GetDtls().Stop();
|
||||
GetNetif().GetCoapSecure().Stop();
|
||||
|
||||
SendKeepAlive();
|
||||
|
||||
@@ -318,7 +318,7 @@ exit:
|
||||
|
||||
const char *Commissioner::GetProvisioningUrl(uint16_t &aLength) const
|
||||
{
|
||||
ProvisioningUrlTlv &provisioningUrl = GetNetif().GetDtls().mProvisioningUrl;
|
||||
ProvisioningUrlTlv &provisioningUrl = GetNetif().GetCoapSecure().GetDtls().mProvisioningUrl;
|
||||
|
||||
aLength = provisioningUrl.GetLength();
|
||||
|
||||
@@ -327,7 +327,7 @@ const char *Commissioner::GetProvisioningUrl(uint16_t &aLength) const
|
||||
|
||||
otError Commissioner::SetProvisioningUrl(const char *aProvisioningUrl)
|
||||
{
|
||||
return GetNetif().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl);
|
||||
return GetNetif().GetCoapSecure().GetDtls().mProvisioningUrl.SetProvisioningUrl(aProvisioningUrl);
|
||||
}
|
||||
|
||||
uint16_t Commissioner::GetSessionId(void) const
|
||||
@@ -898,8 +898,9 @@ void Commissioner::HandleJoinerFinalize(Coap::Message &aMessage, const Ip6::Mess
|
||||
|
||||
if (Tlv::GetTlv(aMessage, Tlv::kProvisioningUrl, sizeof(provisioningUrl), provisioningUrl) == OT_ERROR_NONE)
|
||||
{
|
||||
if (provisioningUrl.GetLength() != GetNetif().GetDtls().mProvisioningUrl.GetLength() ||
|
||||
memcmp(provisioningUrl.GetProvisioningUrl(), GetNetif().GetDtls().mProvisioningUrl.GetProvisioningUrl(),
|
||||
if (provisioningUrl.GetLength() != GetNetif().GetCoapSecure().GetDtls().mProvisioningUrl.GetLength() ||
|
||||
memcmp(provisioningUrl.GetProvisioningUrl(),
|
||||
GetNetif().GetCoapSecure().GetDtls().mProvisioningUrl.GetProvisioningUrl(),
|
||||
provisioningUrl.GetLength()) != 0)
|
||||
{
|
||||
state = StateTlv::kReject;
|
||||
|
||||
+177
-21
@@ -43,6 +43,7 @@
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "common/new.hpp"
|
||||
#include "common/owner-locator.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "crypto/sha256.hpp"
|
||||
@@ -53,7 +54,7 @@
|
||||
namespace ot {
|
||||
namespace MeshCoP {
|
||||
|
||||
Dtls::Dtls(Instance &aInstance)
|
||||
Dtls::Dtls(Instance &aInstance, bool aLayerTwoSecurity)
|
||||
: InstanceLocator(aInstance)
|
||||
, mState(kStateStopped)
|
||||
, mPskLength(0)
|
||||
@@ -61,6 +62,7 @@ Dtls::Dtls(Instance &aInstance)
|
||||
, mTimer(aInstance, &Dtls::HandleTimer, this)
|
||||
, mTimerIntermediate(0)
|
||||
, mTimerSet(false)
|
||||
, mLayerTwoSecurity(aLayerTwoSecurity)
|
||||
, mReceiveMessage(NULL)
|
||||
, mReceiveOffset(0)
|
||||
, mReceiveLength(0)
|
||||
@@ -68,6 +70,9 @@ Dtls::Dtls(Instance &aInstance)
|
||||
, mReceiveHandler(NULL)
|
||||
, mSendHandler(NULL)
|
||||
, mContext(NULL)
|
||||
, mSocket(aInstance.GetThreadNetif().GetIp6().GetUdp())
|
||||
, mTransportCallback(NULL)
|
||||
, mTransportContext(NULL)
|
||||
, mMessageSubType(Message::kSubTypeNone)
|
||||
, mMessageDefaultSubType(Message::kSubTypeNone)
|
||||
{
|
||||
@@ -149,11 +154,120 @@ void Dtls::FreeMbedtls(void)
|
||||
mbedtls_ssl_free(&mSsl);
|
||||
}
|
||||
|
||||
otError Dtls::Start(bool aClient,
|
||||
ConnectedHandler aConnectedHandler,
|
||||
ReceiveHandler aReceiveHandler,
|
||||
SendHandler aSendHandler,
|
||||
void * aContext)
|
||||
otError Dtls::Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext)
|
||||
{
|
||||
otError error;
|
||||
|
||||
SuccessOrExit(error = mSocket.Open(&Dtls::HandleUdpReceive, this));
|
||||
|
||||
mReceiveHandler = aReceiveHandler;
|
||||
mConnectedHandler = aConnectedHandler;
|
||||
mContext = aContext;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Dtls::Connect(const Ip6::SockAddr &aSockAddr)
|
||||
{
|
||||
memcpy(&mPeerAddress.mPeerAddr, &aSockAddr.mAddress, sizeof(mPeerAddress.mPeerAddr));
|
||||
mPeerAddress.mPeerPort = aSockAddr.mPort;
|
||||
|
||||
if (aSockAddr.GetAddress().IsLinkLocal() || aSockAddr.GetAddress().IsMulticast())
|
||||
{
|
||||
mPeerAddress.mInterfaceId = aSockAddr.mScopeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPeerAddress.mInterfaceId = 0;
|
||||
}
|
||||
|
||||
return Setup(true);
|
||||
}
|
||||
|
||||
void Dtls::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
|
||||
{
|
||||
static_cast<Dtls *>(aContext)->HandleUdpReceive(*static_cast<Message *>(aMessage),
|
||||
*static_cast<const Ip6::MessageInfo *>(aMessageInfo));
|
||||
}
|
||||
|
||||
void Dtls::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadNetif &netif = GetNetif();
|
||||
|
||||
if (mState == MeshCoP::Dtls::kStateStopped)
|
||||
{
|
||||
Ip6::SockAddr sockAddr;
|
||||
|
||||
sockAddr.mAddress = aMessageInfo.GetPeerAddr();
|
||||
sockAddr.mPort = aMessageInfo.GetPeerPort();
|
||||
mSocket.Connect(sockAddr);
|
||||
|
||||
mPeerAddress.SetPeerAddr(aMessageInfo.GetPeerAddr());
|
||||
mPeerAddress.SetPeerPort(aMessageInfo.GetPeerPort());
|
||||
mPeerAddress.SetInterfaceId(aMessageInfo.GetInterfaceId());
|
||||
|
||||
if (netif.IsUnicastAddress(aMessageInfo.GetSockAddr()))
|
||||
{
|
||||
mPeerAddress.SetSockAddr(aMessageInfo.GetSockAddr());
|
||||
}
|
||||
|
||||
mPeerAddress.SetSockPort(aMessageInfo.GetSockPort());
|
||||
|
||||
SuccessOrExit(Setup(false));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Once DTLS session is started, communicate only with a peer.
|
||||
VerifyOrExit((mPeerAddress.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
|
||||
(mPeerAddress.GetPeerPort() == aMessageInfo.GetPeerPort()));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER
|
||||
if (mState == MeshCoP::Dtls::kStateConnecting)
|
||||
{
|
||||
SetClientId(mPeerAddress.GetPeerAddr().mFields.m8, sizeof(mPeerAddress.GetPeerAddr().mFields));
|
||||
}
|
||||
#endif
|
||||
|
||||
Receive(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset());
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otError Dtls::Bind(uint16_t aPort)
|
||||
{
|
||||
otError error;
|
||||
Ip6::SockAddr sockaddr;
|
||||
|
||||
VerifyOrExit(mTransportCallback == NULL, error = OT_ERROR_ALREADY);
|
||||
|
||||
sockaddr.mPort = aPort;
|
||||
SuccessOrExit(error = mSocket.Bind(sockaddr));
|
||||
|
||||
mState = kStateStopped;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Dtls::Bind(TransportCallback aCallback, void *aContext)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(mTransportCallback == NULL, error = OT_ERROR_ALREADY);
|
||||
|
||||
mState = kStateStopped;
|
||||
|
||||
mTransportCallback = aCallback;
|
||||
mTransportContext = aContext;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Dtls::Setup(bool aClient)
|
||||
{
|
||||
int rval;
|
||||
|
||||
@@ -240,12 +354,9 @@ otError Dtls::Start(bool aClient,
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
VerifyOrExit(rval == 0);
|
||||
|
||||
mConnectedHandler = aConnectedHandler;
|
||||
mReceiveHandler = aReceiveHandler;
|
||||
mSendHandler = aSendHandler;
|
||||
mContext = aContext;
|
||||
mReceiveMessage = NULL;
|
||||
mMessageSubType = Message::kSubTypeNone;
|
||||
mReceiveMessage = NULL;
|
||||
mMessageSubType = Message::kSubTypeNone;
|
||||
mState = kStateConnecting;
|
||||
|
||||
if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8)
|
||||
{
|
||||
@@ -331,28 +442,37 @@ void Dtls::SetSslAuthMode(bool aVerifyPeerCertificate)
|
||||
|
||||
void Dtls::Stop(void)
|
||||
{
|
||||
VerifyOrExit((mState == kStateConnecting) || (mState == kStateConnected));
|
||||
|
||||
mbedtls_ssl_close_notify(&mSsl);
|
||||
Close();
|
||||
|
||||
exit:
|
||||
return;
|
||||
mState = kStateStopped;
|
||||
mTransportCallback = NULL;
|
||||
mTransportContext = NULL;
|
||||
mTimerSet = false;
|
||||
|
||||
mSocket.Close();
|
||||
mTimer.Stop();
|
||||
}
|
||||
|
||||
void Dtls::Close(void)
|
||||
{
|
||||
assert((mState == kStateConnecting) || (mState == kStateConnected));
|
||||
VerifyOrExit(mState == kStateConnecting || mState == kStateConnected);
|
||||
|
||||
mbedtls_ssl_close_notify(&mSsl);
|
||||
mState = kStateCloseNotify;
|
||||
mTimer.Start(kGuardTimeNewConnectionMilli);
|
||||
|
||||
FreeMbedtls();
|
||||
new (&mPeerAddress) Ip6::MessageInfo();
|
||||
mSocket.Connect(Ip6::SockAddr());
|
||||
|
||||
if (mConnectedHandler != NULL)
|
||||
{
|
||||
mConnectedHandler(mContext, false);
|
||||
}
|
||||
|
||||
FreeMbedtls();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otError Dtls::SetPsk(const uint8_t *aPsk, uint8_t aPskLength)
|
||||
@@ -518,7 +638,7 @@ int Dtls::HandleMbedtlsTransmit(const unsigned char *aBuf, size_t aLength)
|
||||
}
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
|
||||
error = mSendHandler(mContext, aBuf, static_cast<uint16_t>(aLength), mMessageSubType);
|
||||
error = HandleDtlsSend(aBuf, static_cast<uint16_t>(aLength), mMessageSubType);
|
||||
|
||||
// Restore default sub type.
|
||||
mMessageSubType = mMessageDefaultSubType;
|
||||
@@ -691,7 +811,7 @@ int Dtls::HandleMbedtlsExportKeys(const unsigned char *aMasterSecret,
|
||||
|
||||
void Dtls::HandleTimer(Timer &aTimer)
|
||||
{
|
||||
aTimer.GetOwner<Dtls>().HandleTimer();
|
||||
static_cast<Dtls *>(static_cast<TimerMilliContext &>(aTimer).GetContext())->HandleTimer();
|
||||
}
|
||||
|
||||
void Dtls::HandleTimer(void)
|
||||
@@ -933,6 +1053,42 @@ void Dtls::HandleMbedtlsDebug(void *ctx, int level, const char *, int, const cha
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
}
|
||||
|
||||
otError Dtls::HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
ot::Message *message = NULL;
|
||||
|
||||
VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
message->SetSubType(aMessageSubType);
|
||||
message->SetLinkSecurityEnabled(mLayerTwoSecurity);
|
||||
|
||||
SuccessOrExit(error = message->Append(aBuf, aLength));
|
||||
|
||||
// Set message sub type in case Joiner Finalize Response is appended to the message.
|
||||
if (aMessageSubType != Message::kSubTypeNone)
|
||||
{
|
||||
message->SetSubType(aMessageSubType);
|
||||
}
|
||||
|
||||
if (mTransportCallback)
|
||||
{
|
||||
SuccessOrExit(error = mTransportCallback(mTransportContext, *message, mPeerAddress));
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = mSocket.SendTo(*message, mPeerAddress));
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace MeshCoP
|
||||
} // namespace ot
|
||||
|
||||
|
||||
+123
-17
@@ -60,6 +60,8 @@
|
||||
#include "common/timer.hpp"
|
||||
#include "crypto/sha256.hpp"
|
||||
#include "meshcop/meshcop_tlvs.hpp"
|
||||
#include "net/socket.hpp"
|
||||
#include "net/udp6.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
@@ -91,10 +93,11 @@ public:
|
||||
/**
|
||||
* This constructor initializes the DTLS object.
|
||||
*
|
||||
* @param[in] aNetif A reference to the Thread network interface.
|
||||
* @param[in] aNetif A reference to the Thread network interface.
|
||||
* @param[in] aLayerTwoSecurity Specifies whether to use layer two security or not.
|
||||
*
|
||||
*/
|
||||
explicit Dtls(Instance &aInstance);
|
||||
explicit Dtls(Instance &aInstance, bool aLayerTwoSecurity);
|
||||
|
||||
/**
|
||||
* This function pointer is called when a connection is established or torn down.
|
||||
@@ -115,6 +118,16 @@ public:
|
||||
*/
|
||||
typedef void (*ReceiveHandler)(void *aContext, uint8_t *aBuf, uint16_t aLength);
|
||||
|
||||
/**
|
||||
* This function pointer is called when secure CoAP server want to send encrypted message.
|
||||
*
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
* @param[in] aMessage A reference to the message to send.
|
||||
* @param[in] aMessageInfo A reference to the message info associated with @p aMessage.
|
||||
*
|
||||
*/
|
||||
typedef otError (*TransportCallback)(void *aContext, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* This function pointer is called when data is ready to transmit for the DTLS session.
|
||||
*
|
||||
@@ -126,6 +139,19 @@ public:
|
||||
*/
|
||||
typedef otError (*SendHandler)(void *aContext, const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
|
||||
|
||||
/**
|
||||
* This method opens the DTLS socket.
|
||||
*
|
||||
* @param[in] aReceiveHandler A pointer to a function that is called to receive DTLS payload.
|
||||
* @param[in] aConnectedHandler A pointer to a function that is called when connected or disconnected.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully opened the socket.
|
||||
* @retval OT_ERROR_ALREADY The DTLS is already open.
|
||||
*
|
||||
*/
|
||||
otError Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* This method starts the DTLS service.
|
||||
*
|
||||
@@ -133,20 +159,73 @@ public:
|
||||
* Set X509 Pk and Cert for use DTLS mode ECDHE ECDSA with AES 128 CCM 8 or
|
||||
* set PreShared Key for use DTLS mode PSK with AES 128 CCM 8.
|
||||
*
|
||||
* @param[in] aClient TRUE if operating as a client, FALSE if operating as a server.
|
||||
* @param[in] aConnectedHandler A pointer to the connected handler.
|
||||
* @param[in] aReceiveHandler A pointer to the receive handler.
|
||||
* @param[in] aSendHandler A pointer to the send handler.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
* @param[in] aSockAddr A reference to the remote sockaddr.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the DTLS service.
|
||||
*
|
||||
*/
|
||||
otError Start(bool aClient,
|
||||
ConnectedHandler aConnectedHandler,
|
||||
ReceiveHandler aReceiveHandler,
|
||||
SendHandler aSendHandler,
|
||||
void * aContext);
|
||||
otError Connect(const Ip6::SockAddr &aSockAddr);
|
||||
|
||||
/**
|
||||
* This method set up the DTLS service.
|
||||
*
|
||||
* For CoAP Secure API do first:
|
||||
* Set X509 Pk and Cert for use DTLS mode ECDHE ECDSA with AES 128 CCM 8 or
|
||||
* set PreShared Key for use DTLS mode PSK with AES 128 CCM 8.
|
||||
*
|
||||
* @param[in] aClient TRUE if setup for client, otherwise setup for server.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started the DTLS service.
|
||||
*
|
||||
*/
|
||||
otError Setup(bool aClient);
|
||||
|
||||
/**
|
||||
* This method binds this DTLS to a UDP port.
|
||||
*
|
||||
* @param[in] aPort The port to bind.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully binded the DTLS service.
|
||||
* @retval OT_ERROR_ALREADY Already bound.
|
||||
*
|
||||
*/
|
||||
otError Bind(uint16_t aPort);
|
||||
|
||||
/**
|
||||
* This method binds this DTLS with a transport callback.
|
||||
*
|
||||
* @param[in] aCallback A pointer to a function for sending messages.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully binded the DTLS service.
|
||||
* @retval OT_ERROR_ALREADY Already bound.
|
||||
*
|
||||
*/
|
||||
otError Bind(TransportCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the DTLS session is active.
|
||||
*
|
||||
* @retval TRUE If DTLS session is active.
|
||||
* @retval FALSE If DTLS session is not active.
|
||||
*
|
||||
*/
|
||||
bool IsConnectionActive(void) { return mState != kStateStopped; }
|
||||
|
||||
/**
|
||||
* 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) { return mState == kStateConnected; }
|
||||
|
||||
/**
|
||||
* This method close the current session.
|
||||
*
|
||||
*/
|
||||
void Close(void);
|
||||
|
||||
/**
|
||||
* This method stops the DTLS service.
|
||||
@@ -308,12 +387,22 @@ public:
|
||||
*/
|
||||
void SetDefaultMessageSubType(uint8_t aMessageSubType) { mMessageDefaultSubType = aMessageSubType; }
|
||||
|
||||
/**
|
||||
* This method returns the DTLS session's peer address.
|
||||
*
|
||||
* @return DTLS session's message info.
|
||||
*
|
||||
*/
|
||||
const Ip6::MessageInfo &GetPeerAddress(void) const { return mPeerAddress; }
|
||||
|
||||
/**
|
||||
* The provisioning URL is placed here so that both the Commissioner and Joiner can share the same object.
|
||||
*
|
||||
*/
|
||||
ProvisioningUrlTlv mProvisioningUrl;
|
||||
|
||||
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
private:
|
||||
void FreeMbedtls(void);
|
||||
|
||||
@@ -358,9 +447,16 @@ private:
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
|
||||
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
|
||||
|
||||
void HandleDtlsReceive(const uint8_t *aBuf, uint16_t aLength);
|
||||
otError HandleDtlsSend(const uint8_t *aBuf, uint16_t aLength, uint8_t aMessageSubType);
|
||||
|
||||
static void HandleUdpTransmit(Tasklet &aTasklet);
|
||||
void HandleUdpTransmit(void);
|
||||
|
||||
static int HandleMbedtlsEntropyPoll(void *aData, unsigned char *aOutput, size_t aInLen, size_t *aOutLen);
|
||||
|
||||
void Close(void);
|
||||
void Process(void);
|
||||
|
||||
State mState;
|
||||
@@ -402,11 +498,15 @@ private:
|
||||
mbedtls_ssl_cookie_ctx mCookieCtx;
|
||||
#endif
|
||||
|
||||
TimerMilli mTimer;
|
||||
uint32_t mTimerIntermediate;
|
||||
bool mTimerSet;
|
||||
TimerMilliContext mTimer;
|
||||
|
||||
uint32_t mTimerIntermediate;
|
||||
bool mTimerSet : 1;
|
||||
|
||||
bool mLayerTwoSecurity : 1;
|
||||
|
||||
const Message *mReceiveMessage;
|
||||
|
||||
Message *mReceiveMessage;
|
||||
uint16_t mReceiveOffset;
|
||||
uint16_t mReceiveLength;
|
||||
|
||||
@@ -415,6 +515,12 @@ private:
|
||||
SendHandler mSendHandler;
|
||||
void * mContext;
|
||||
|
||||
Ip6::MessageInfo mPeerAddress;
|
||||
Ip6::UdpSocket mSocket;
|
||||
|
||||
TransportCallback mTransportCallback;
|
||||
void * mTransportContext;
|
||||
|
||||
uint8_t mMessageSubType;
|
||||
uint8_t mMessageDefaultSubType;
|
||||
};
|
||||
|
||||
@@ -88,7 +88,6 @@ ThreadNetif::ThreadNetif(Instance &aInstance)
|
||||
, mCommissioner(aInstance)
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
, mDtls(aInstance)
|
||||
, mCoapSecure(aInstance)
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
@@ -150,14 +149,14 @@ void ThreadNetif::Down(void)
|
||||
{
|
||||
VerifyOrExit(mIsUp);
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
mDtls.Stop();
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_DNS_CLIENT
|
||||
mDnsClient.Stop();
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_SNTP_CLIENT
|
||||
mSntpClient.Stop();
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
mCoapSecure.Stop();
|
||||
#endif
|
||||
mCoap.Stop();
|
||||
mMleRouter.Disable();
|
||||
|
||||
@@ -49,10 +49,6 @@
|
||||
|
||||
#include "meshcop/dataset_manager.hpp"
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
#include "meshcop/dtls.hpp"
|
||||
#endif // OPENTHREAD_ENABLE_DTLS
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
#include "meshcop/joiner.hpp"
|
||||
#endif // OPENTHREAD_ENABLE_JOINER
|
||||
@@ -341,14 +337,6 @@ public:
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
/**
|
||||
* This method returns a reference to the Dtls object.
|
||||
*
|
||||
* @returns A reference to the Dtls object.
|
||||
*
|
||||
*/
|
||||
MeshCoP::Dtls &GetDtls(void) { return mDtls; }
|
||||
|
||||
/**
|
||||
* This method returns a reference to the secure CoAP object.
|
||||
*
|
||||
@@ -491,7 +479,6 @@ private:
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER
|
||||
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
MeshCoP::Dtls mDtls;
|
||||
Coap::CoapSecure mCoapSecure;
|
||||
#endif // OPENTHREAD_ENABLE_DTLS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user