Skip to content

Commit ddc6415

Browse files
committed
TCP connection setup/management and CASESession association.
Add ConnectToPeer() API for explicit connection setup. Currently, connecting to a peer is coupled with sending a message to the peer. This decouples the two and creates a clear API for connecting to a peer address. Goes along with the existing Disconnect() API. This would be essential during activation of retained sessions by solely connecting to the peer and associating with the retained session. Surface Connection completion and Closure callbacks and hook them through SessionManager(TransportMgr delegate) and CASESession. Mark SecureSession as defunct on connection closures. Modify ActiveConnectionState in TCPBase to hold state for each connection, so that it is able to handle the various control flow paths.
1 parent a3c5d19 commit ddc6415

14 files changed

+693
-135
lines changed

src/app/OperationalSessionSetup.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ CHIP_ERROR OperationalSessionSetup::EstablishConnection(const ReliableMessagePro
278278
mCASEClient = mClientPool->Allocate();
279279
ReturnErrorCodeIf(mCASEClient == nullptr, CHIP_ERROR_NO_MEMORY);
280280

281+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
282+
mDeviceAddress.SetTransportType(chip::Transport::Type::kTcp);
283+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
284+
281285
CHIP_ERROR err = mCASEClient->EstablishSession(mInitParams, mPeerId, mDeviceAddress, config, this);
282286
if (err != CHIP_NO_ERROR)
283287
{

src/lib/core/CHIPConfig.h

+10
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,16 @@ extern const char CHIP_NON_PRODUCTION_MARKER[];
16341634
#define CHIP_CONFIG_ICD_OBSERVERS_POOL_SIZE 2
16351635
#endif
16361636

1637+
/**
1638+
* @def CHIP_CONFIG_TCP_SUPPORT_ENABLED
1639+
* @brief
1640+
* Enable (1) or disable (0) support for TCP as a transport protocol for
1641+
* operational communications.
1642+
*/
1643+
#ifndef CHIP_CONFIG_TCP_SUPPORT_ENABLED
1644+
#define CHIP_CONFIG_TCP_SUPPORT_ENABLED (INET_CONFIG_ENABLE_TCP_ENDPOINT)
1645+
#endif
1646+
16371647
/**
16381648
* @}
16391649
*/

src/protocols/secure_channel/CASESession.cpp

+66-3
Original file line numberDiff line numberDiff line change
@@ -444,14 +444,21 @@ CHIP_ERROR CASESession::Init(SessionManager & sessionManager, Credentials::Certi
444444

445445
ReturnErrorOnFailure(mCommissioningHash.Begin());
446446

447-
mDelegate = delegate;
447+
mDelegate = delegate;
448+
mSessionManager = &sessionManager;
449+
448450
ReturnErrorOnFailure(AllocateSecureSession(sessionManager, sessionEvictionHint));
449451

450452
mValidContext.Reset();
451453
mValidContext.mRequiredKeyUsages.Set(KeyUsageFlags::kDigitalSignature);
452454
mValidContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kServerAuth);
453455
mValidContext.mValidityPolicy = policy;
454456

457+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
458+
// Set callbacks for connection in sessionmanager
459+
sessionManager.SetConnectionCallbacks(HandleConnectionComplete, HandleConnectionClosed, this);
460+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
461+
455462
return CHIP_NO_ERROR;
456463
}
457464

@@ -531,8 +538,23 @@ CHIP_ERROR CASESession::EstablishSession(SessionManager & sessionManager, Fabric
531538
ChipLogProgress(SecureChannel, "Initiating session on local FabricIndex %u from 0x" ChipLogFormatX64 " -> 0x" ChipLogFormatX64,
532539
static_cast<unsigned>(mFabricIndex), ChipLogValueX64(mLocalNodeId), ChipLogValueX64(mPeerNodeId));
533540

534-
err = SendSigma1();
535-
SuccessOrExit(err);
541+
// TODO: Need to look into unifying this call to invoke ConnectToPeer() for
542+
// all transports, including MRP.
543+
// For UDP based transports, this call would short-circuit back into
544+
// HandleConnectionComplete() callback.
545+
// Currently, TestCASESession is organized such that it requires synchronous
546+
// calls back from EstablishSession() over UDP. So, bifurcate TCP and MRP
547+
// calls here, for now.
548+
if (mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->GetPeerAddress().GetTransportType() == Transport::Type::kTcp)
549+
{
550+
err = sessionManager.ConnectToPeer(mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->GetPeerAddress());
551+
SuccessOrExit(err);
552+
}
553+
else
554+
{
555+
err = SendSigma1();
556+
SuccessOrExit(err);
557+
}
536558

537559
exit:
538560
if (err != CHIP_NO_ERROR)
@@ -638,6 +660,47 @@ CHIP_ERROR CASESession::RecoverInitiatorIpk()
638660
return CHIP_NO_ERROR;
639661
}
640662

663+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
664+
void CASESession::HandleConnectionComplete(void * context, Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr)
665+
{
666+
CHIP_ERROR err = CHIP_NO_ERROR;
667+
668+
VerifyOrReturn(context != nullptr);
669+
VerifyOrReturn(conObj != nullptr);
670+
VerifyOrReturn(conObj->mPeerAddr.GetTransportType() == Transport::Type::kTcp);
671+
672+
ChipLogDetail(SecureChannel, "TCP Connection established before session establishment");
673+
674+
CASESession * caseSession = reinterpret_cast<CASESession *>(context);
675+
676+
// Associate the connection with the session
677+
caseSession->mExchangeCtxt->GetSessionHandle()->AsUnauthenticatedSession()->SetTCPConnection(conObj);
678+
679+
// Send Sigma1 after connection is established for sessions over TCP
680+
err = caseSession->SendSigma1();
681+
if (err != CHIP_NO_ERROR)
682+
{
683+
caseSession->Clear();
684+
}
685+
}
686+
687+
void CASESession::HandleConnectionClosed(void * context, Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr)
688+
{
689+
// CHIP_ERROR err = CHIP_NO_ERROR;
690+
691+
VerifyOrReturn(context != nullptr);
692+
CASESession * caseSession = reinterpret_cast<CASESession *>(context);
693+
if (conErr == CHIP_NO_ERROR)
694+
{
695+
caseSession->Clear();
696+
}
697+
else
698+
{
699+
// Connection establishment failed
700+
}
701+
}
702+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
703+
641704
CHIP_ERROR CASESession::SendSigma1()
642705
{
643706
MATTER_TRACE_SCOPE("SendSigma1", "CASESession");

src/protocols/secure_channel/CASESession.h

+6
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
283283

284284
void InvalidateIfPendingEstablishmentOnFabric(FabricIndex fabricIndex);
285285

286+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
287+
static void HandleConnectionComplete(void * context, Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr);
288+
static void HandleConnectionClosed(void * context, Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr);
289+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
290+
286291
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
287292
void SetStopSigmaHandshakeAt(Optional<State> state) { mStopHandshakeAtState = state; }
288293
#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST
@@ -298,6 +303,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler,
298303
uint8_t mIPK[kIPKSize];
299304

300305
SessionResumptionStorage * mSessionResumptionStorage = nullptr;
306+
SessionManager * mSessionManager = nullptr;
301307

302308
FabricTable * mFabricsTable = nullptr;
303309
FabricIndex mFabricIndex = kUndefinedFabricIndex;

src/transport/Session.h

+11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
#include <platform/LockTracker.h>
2929
#include <protocols/secure_channel/SessionParameters.h>
3030
#include <transport/SessionDelegate.h>
31+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
32+
#include <transport/raw/TCP.h>
33+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
3134

3235
namespace chip {
3336
namespace Transport {
@@ -224,6 +227,11 @@ class Session
224227

225228
bool IsUnauthenticatedSession() const { return GetSessionType() == SessionType::kUnauthenticated; }
226229

230+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
231+
TCPBase::ActiveConnectionState * GetTCPConnection() const { return mTCPConnection; }
232+
void SetTCPConnection(TCPBase::ActiveConnectionState * conn) { mTCPConnection = conn; }
233+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
234+
227235
void DispatchSessionEvent(SessionDelegate::Event event)
228236
{
229237
// Holders might remove themselves when notified.
@@ -263,6 +271,9 @@ class Session
263271

264272
private:
265273
FabricIndex mFabricIndex = kUndefinedFabricIndex;
274+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
275+
TCPBase::ActiveConnectionState * mTCPConnection = nullptr;
276+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
266277
};
267278

268279
//

src/transport/SessionManager.cpp

+80
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ CHIP_ERROR SessionManager::Init(System::Layer * systemLayer, TransportMgrBase *
108108

109109
mTransportMgr->SetSessionManager(this);
110110

111+
mTransportMgr->SetSystemLayer(systemLayer);
112+
113+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
114+
mConnCompleteCb = nullptr;
115+
mConnClosedCb = nullptr;
116+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
117+
111118
return CHIP_NO_ERROR;
112119
}
113120

@@ -582,6 +589,79 @@ void SessionManager::OnMessageReceived(const PeerAddress & peerAddress, System::
582589
}
583590
}
584591

592+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
593+
void SessionManager::SetConnectionCallbacks(OnConnectionCompleteCallback connCompleteCb, OnConnectionClosedCallback connClosedCb,
594+
void * connContext)
595+
{
596+
mConnCompleteCb = connCompleteCb;
597+
mConnClosedCb = connClosedCb;
598+
mConnContext = connContext;
599+
}
600+
601+
void SessionManager::HandleConnectionComplete(Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr)
602+
{
603+
if (mConnCompleteCb != nullptr)
604+
{
605+
ChipLogProgress(Inet, "Calling Connection Complete callback");
606+
mConnCompleteCb(mConnContext, conObj, conErr);
607+
}
608+
else
609+
{
610+
ChipLogProgress(Inet, "Connection Complete callback missing");
611+
}
612+
}
613+
614+
void SessionManager::HandleConnectionClosed(Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr)
615+
{
616+
if (mConnClosedCb != nullptr)
617+
{
618+
mConnClosedCb(mConnContext, conObj, conErr);
619+
}
620+
else
621+
{
622+
ChipLogProgress(Inet, "Connection Closed callback missing");
623+
}
624+
625+
// Mark the corresponding secure session as defunct
626+
mSecureSessions.ForEachSession([&](auto session) {
627+
if (session->IsActiveSession() && session->GetTCPConnection() == conObj)
628+
{
629+
session->MarkAsDefunct();
630+
return Loop::Break;
631+
}
632+
633+
return Loop::Continue;
634+
});
635+
636+
// TODO: A mechanism to mark an unauthenticated session as unusable when
637+
// the underlying connection is broken.
638+
}
639+
640+
CHIP_ERROR SessionManager::ConnectToPeer(const PeerAddress & peerAddress)
641+
{
642+
if (mTransportMgr != nullptr)
643+
{
644+
ChipLogProgress(Inet, "Connecting to peer ");
645+
return mTransportMgr->ConnectToPeer(peerAddress);
646+
}
647+
648+
ChipLogError(Inet, "The transport manager is not initialized. Unable to connect to peer");
649+
650+
return CHIP_ERROR_INCORRECT_STATE;
651+
}
652+
653+
CHIP_ERROR SessionManager::Disconnect(const PeerAddress & peerAddress)
654+
{
655+
if (mTransportMgr != nullptr)
656+
{
657+
ChipLogProgress(Inet, "Disconnecting from peer ");
658+
mTransportMgr->Disconnect(peerAddress);
659+
}
660+
661+
return CHIP_NO_ERROR;
662+
}
663+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
664+
585665
void SessionManager::UnauthenticatedMessageDispatch(const PacketHeader & partialPacketHeader,
586666
const Transport::PeerAddress & peerAddress, System::PacketBufferHandle && msg)
587667
{

src/transport/SessionManager.h

+27
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,27 @@ class DLL_EXPORT SessionManager : public TransportMgrDelegate, public FabricTabl
416416
*/
417417
void OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msgBuf) override;
418418

419+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
420+
CHIP_ERROR ConnectToPeer(const Transport::PeerAddress & peerAddress);
421+
422+
CHIP_ERROR Disconnect(const Transport::PeerAddress & peerAddress);
423+
424+
void HandleConnectionComplete(Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr) override;
425+
426+
void HandleConnectionClosed(Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr) override;
427+
428+
// Functors for callbacks into higher layers
429+
using OnConnectionCompleteCallback = void (*)(void * appContext, Transport::TCPBase::ActiveConnectionState * conObj,
430+
CHIP_ERROR conErr);
431+
432+
using OnConnectionClosedCallback = void (*)(void * appContext, Transport::TCPBase::ActiveConnectionState * conObj,
433+
CHIP_ERROR conErr);
434+
435+
// Set the higher layer callbacks
436+
void SetConnectionCallbacks(OnConnectionCompleteCallback connCompleteCb, OnConnectionClosedCallback connClosedCb,
437+
void * connContext);
438+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
439+
419440
Optional<SessionHandle> CreateUnauthenticatedSession(const Transport::PeerAddress & peerAddress,
420441
const ReliableMessageProtocolConfig & config)
421442
{
@@ -477,6 +498,12 @@ class DLL_EXPORT SessionManager : public TransportMgrDelegate, public FabricTabl
477498
State mState; // < Initialization state of the object
478499
chip::Transport::GroupOutgoingCounters mGroupClientCounter;
479500

501+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
502+
OnConnectionCompleteCallback mConnCompleteCb = nullptr;
503+
OnConnectionClosedCallback mConnClosedCb = nullptr;
504+
void * mConnContext = nullptr;
505+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
506+
480507
SessionMessageDelegate * mCB = nullptr;
481508

482509
TransportMgrBase * mTransportMgr = nullptr;

src/transport/TransportMgr.h

+16
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
#include <transport/raw/MessageHeader.h>
3535
#include <transport/raw/PeerAddress.h>
3636
#include <transport/raw/Tuple.h>
37+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
38+
#include <transport/raw/TCP.h>
39+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
3740

3841
namespace chip {
3942

@@ -51,6 +54,19 @@ class TransportMgrDelegate
5154
* @param msgBuf the buffer containing a full CHIP message (except for the optional length field).
5255
*/
5356
virtual void OnMessageReceived(const Transport::PeerAddress & source, System::PacketBufferHandle && msgBuf) = 0;
57+
58+
#if CHIP_CONFIG_TCP_SUPPORT_ENABLED
59+
/**
60+
* @brief
61+
* Handle connection completion.
62+
*
63+
* @param conObj the connection object
64+
* @param conErr the connection error on the attempt.
65+
*/
66+
virtual void HandleConnectionComplete(Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr){};
67+
68+
virtual void HandleConnectionClosed(Transport::TCPBase::ActiveConnectionState * conObj, CHIP_ERROR conErr){};
69+
#endif // CHIP_CONFIG_TCP_SUPPORT_ENABLED
5470
};
5571

5672
template <typename... TransportTypes>

0 commit comments

Comments
 (0)