[dtls] do not allow Open() or Bind() when DTLS session is started (#3694)

This commit is contained in:
Jonathan Hui
2019-03-18 22:58:38 -07:00
committed by Jonathan Hui
parent 8bddf61ae2
commit a39f2c86d3
2 changed files with 49 additions and 26 deletions
+26 -13
View File
@@ -59,7 +59,7 @@ namespace MeshCoP {
Dtls::Dtls(Instance &aInstance, bool aLayerTwoSecurity)
: InstanceLocator(aInstance)
, mState(kStateStopped)
, mState(kStateClosed)
, mPskLength(0)
, mVerifyPeerCertificate(true)
, mTimer(aInstance, &Dtls::HandleTimer, this)
@@ -166,6 +166,7 @@ otError Dtls::Open(ReceiveHandler aReceiveHandler, ConnectedHandler aConnectedHa
mReceiveHandler = aReceiveHandler;
mConnectedHandler = aConnectedHandler;
mContext = aContext;
mState = kStateOpen;
exit:
return error;
@@ -173,6 +174,10 @@ exit:
otError Dtls::Connect(const Ip6::SockAddr &aSockAddr)
{
otError error;
VerifyOrExit(mState == kStateOpen, error = OT_ERROR_INVALID_STATE);
memcpy(&mPeerAddress.mPeerAddr, &aSockAddr.mAddress, sizeof(mPeerAddress.mPeerAddr));
mPeerAddress.mPeerPort = aSockAddr.mPort;
@@ -185,7 +190,10 @@ otError Dtls::Connect(const Ip6::SockAddr &aSockAddr)
mPeerAddress.mInterfaceId = 0;
}
return Setup(true);
error = Setup(true);
exit:
return error;
}
void Dtls::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
@@ -198,7 +206,12 @@ void Dtls::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageI
{
ThreadNetif &netif = GetNetif();
if (mState == MeshCoP::Dtls::kStateStopped)
switch (mState)
{
case MeshCoP::Dtls::kStateClosed:
ExitNow();
case MeshCoP::Dtls::kStateOpen:
{
Ip6::SockAddr sockAddr;
@@ -218,12 +231,14 @@ void Dtls::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageI
mPeerAddress.SetSockPort(aMessageInfo.GetSockPort());
SuccessOrExit(Setup(false));
break;
}
else
{
default:
// Once DTLS session is started, communicate only with a peer.
VerifyOrExit((mPeerAddress.GetPeerAddr() == aMessageInfo.GetPeerAddr()) &&
(mPeerAddress.GetPeerPort() == aMessageInfo.GetPeerPort()));
break;
}
#if OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER
@@ -244,13 +259,12 @@ otError Dtls::Bind(uint16_t aPort)
otError error;
Ip6::SockAddr sockaddr;
VerifyOrExit(mState == kStateOpen, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(mTransportCallback == NULL, error = OT_ERROR_ALREADY);
sockaddr.mPort = aPort;
SuccessOrExit(error = mSocket.Bind(sockaddr));
mState = kStateStopped;
exit:
return error;
}
@@ -259,11 +273,10 @@ otError Dtls::Bind(TransportCallback aCallback, void *aContext)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mState == kStateOpen, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(mSocket.GetSockName().mPort == 0, error = OT_ERROR_ALREADY);
VerifyOrExit(mTransportCallback == NULL, error = OT_ERROR_ALREADY);
mState = kStateStopped;
mTransportCallback = aCallback;
mTransportContext = aContext;
@@ -276,7 +289,7 @@ otError Dtls::Setup(bool aClient)
int rval;
// do not handle new connection before guard time expired
VerifyOrExit(mState == kStateStopped, rval = MBEDTLS_ERR_SSL_TIMEOUT);
VerifyOrExit(mState == kStateOpen, rval = MBEDTLS_ERR_SSL_TIMEOUT);
mState = kStateInitializing;
@@ -380,7 +393,7 @@ otError Dtls::Setup(bool aClient)
exit:
if ((mState == kStateInitializing) && (rval != 0))
{
mState = kStateStopped;
mState = kStateOpen;
FreeMbedtls();
}
@@ -448,7 +461,7 @@ void Dtls::Stop(void)
{
Close();
mState = kStateStopped;
mState = kStateClosed;
mTransportCallback = NULL;
mTransportContext = NULL;
mTimerSet = false;
@@ -828,7 +841,7 @@ void Dtls::HandleTimer(void)
break;
case kStateCloseNotify:
mState = kStateStopped;
mState = kStateOpen;
mTimer.Stop();
break;
+23 -13
View File
@@ -83,7 +83,8 @@ public:
enum State
{
kStateStopped = 0,
kStateClosed = 0,
kStateOpen,
kStateInitializing,
kStateConnecting,
kStateConnected,
@@ -161,7 +162,8 @@ public:
*
* @param[in] aSockAddr A reference to the remote sockaddr.
*
* @retval OT_ERROR_NONE Successfully started the DTLS service.
* @retval OT_ERROR_NONE Successfully started the DTLS service.
* @retval OT_ERROR_INVALID_STATE The DTLS service is not in state kStateOpen.
*
*/
otError Connect(const Ip6::SockAddr &aSockAddr);
@@ -175,7 +177,8 @@ public:
*
* @param[in] aClient TRUE if setup for client, otherwise setup for server.
*
* @retval OT_ERROR_NONE Successfully started the DTLS service.
* @retval OT_ERROR_NONE Successfully started the DTLS service.
* @retval OT_ERROR_INVALID_STATE The DTLS service is not in state kStateClosed.
*
*/
otError Setup(bool aClient);
@@ -185,8 +188,9 @@ public:
*
* @param[in] aPort The port to bind.
*
* @retval OT_ERROR_NONE Successfully binded the DTLS service.
* @retval OT_ERROR_ALREADY Already bound.
* @retval OT_ERROR_NONE Successfully binded the DTLS service.
* @retval OT_ERROR_INVALID_STATE The DTLS service is not in state kStateOpen.
* @retval OT_ERROR_ALREADY Already bound.
*
*/
otError Bind(uint16_t aPort);
@@ -197,8 +201,9 @@ public:
* @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.
* @retval OT_ERROR_NONE Successfully binded the DTLS service.
* @retval OT_ERROR_INVALID_STATE The DTLS service is not in state kStateOpen.
* @retval OT_ERROR_ALREADY Already bound.
*
*/
otError Bind(TransportCallback aCallback, void *aContext);
@@ -206,20 +211,24 @@ public:
/**
* This method indicates whether or not the DTLS session is active.
*
* In other words, the state is kStateConnecting, kStateConnected, or kStateCloseNotify.
*
* @retval TRUE If DTLS session is active.
* @retval FALSE If DTLS session is not active.
*
*/
bool IsConnectionActive(void) { return mState != kStateStopped; }
bool IsConnectionActive(void) const { return mState >= kStateConnecting; }
/**
* This method indicates whether or not the DTLS session is connected.
*
* In other words, the state is kStateConnected.
*
* @retval TRUE The DTLS session is connected.
* @retval FALSE The DTLS session is not connected.
*
*/
bool IsConnected(void) { return mState == kStateConnected; }
bool IsConnected(void) const { return mState == kStateConnected; }
/**
* This method close the current session.
@@ -236,10 +245,11 @@ public:
/**
* This method returns the DTLS connection state.
*
* @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.
* @retval kStateClosed The UDP socket closed.
* @retval kStateOpen The UDP socket is open.
* @retval kStateConnecting The DTLS service is establishing a connection.
* @retval kStateConnected The DTLS service has a connection established.
* @retval kStateCloseNotify The DTLS service is closing a connection.
*
*/
State GetState(void) const { return mState; }