blob: 9a37e71fd7015b2f6add58fdf5c7498a78f2d384 [file] [log] [blame]
/*
*
* Copyright (c) 2014-2017 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file implements the Weave Tunnel Connection Manager that
* manages the connection state machine.
*
*/
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#ifndef _WEAVE_TUNNEL_CONNECTION_MGR_H_
#define _WEAVE_TUNNEL_CONNECTION_MGR_H_
#include <Weave/Core/WeaveCore.h>
#include <InetLayer/InetInterface.h>
#include <Weave/Profiles/WeaveProfiles.h>
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelCommon.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelControl.h>
#if WEAVE_CONFIG_ENABLE_TUNNELING
#define SERVICE_CONN_INTF_NAME_MAX_LEN (16)
#define CONNECT_NO_DELAY (0)
namespace nl {
namespace Weave {
namespace Profiles {
namespace WeaveTunnel {
class WeaveTunnelAgent;
/**
* The reconnect policy parameters that are used to govern the way the
* tunnel reconnects to the Service.
*/
class ReconnectParam
{
public:
void PopulateReconnectParam(WEAVE_ERROR mLastConnectError = WEAVE_NO_ERROR,
uint32_t mStatusProfileId = kWeaveProfile_Common,
uint16_t mStatusCode = Common::kStatus_Success,
uint32_t mMinDelayToConnectSecs = 0);
WEAVE_ERROR mLastConnectError;
uint32_t mMinDelayToConnectSecs;
uint32_t mStatusProfileId;
uint16_t mStatusCode;
};
/**
* @class WeaveTunnelConnectionMgr
*
* @brief
* This class encapsulates all the Weave tunnel connection states
* and the associated management logic and functions. An instance
* of this class would be used to manage the tunnel over each
* interface through which the Weave tunnel to the Service would
* exist.
*
*/
class NL_DLL_EXPORT WeaveTunnelConnectionMgr
{
friend class WeaveTunnelAgent;
friend class WeaveTunnelControl;
public:
typedef enum TunnelConnectionState
{
kState_NotConnected = 0, /**< Used to indicate that the Weave Tunnel is not connected */
kState_Connecting = 1, /**< Used to indicate that the Weave Tunnel connection has been initiated */
kState_ConnectionEstablished = 2, /**< Used to indicate that the Weave Tunnel connection is established and route information is being exchanged */
kState_TunnelOpen = 3, /**< Used to indicate that the Weave Tunnel is open and ready for data traffic transit */
kState_TunnelClosing = 4, /**< Used to indicate that the Weave Tunnel is closing and the connection is being torn down */
kState_ReconnectRecvd = 5, /**< Used to indicate that the Service wants the border gateway to reconnect after a directory lookup */
} TunnelConnectionState;
typedef enum TunnelConnNotifyReasons
{
kStatus_TunDown = 0, /**< Used to indicate that the Weave tunnel has gone down */
kStatus_TunPrimaryUp = 1, /**< Used to indicate that the primary Weave tunnel is up */
kStatus_TunPrimaryConnError = 2, /**< Used to indicate that a primary tunnel connection attempt has failed or an existing one was locally aborted or closed by peer */
kStatus_TunBackupConnError = 3, /**< Used to indicate that a backup tunnel connection attempt has failed or an existing one was locally aborted or closed by peer */
kStatus_TunFailoverToBackup = 4, /**< Used to indicate that the primary tunnel is down and switchover to backup tunnel has occurred */
kStatus_TunBackupOnlyDown = 5, /**< Used to indicate that the backup tunnel is down */
kStatus_TunBackupUp = 6, /**< Used to indicate that the Backup Weave tunnel is up */
kStatus_TunPrimaryAndBackupUp = 7, /**< Used to indicate that both the Primary and Backup Weave tunnel are up */
kStatus_TunPrimaryReconnectRcvd = 8, /**< Used to indicate that the Service has requested a reconnect for the Primary Weave tunnel */
kStatus_TunBackupReconnectRcvd = 9, /**< Used to indicate that the Service has requested a reconnect for the Backup Weave tunnel */
kStatus_TunPrimaryLiveness = 10, /**< Used to indicate information about the Tunnel Liveness probe on the Primary Weave tunnel */
kStatus_TunBackupLiveness = 11, /**< Used to indicate information about the Tunnel Liveness probe on the Backup Weave tunnel */
} TunnelConnNotifyReasons;
WeaveTunnelConnectionMgr(void);
#if WEAVE_CONFIG_PERSIST_CONNECTED_SESSION
/**
* Check if a persisted secure session for the tunnel exists
*/
typedef bool (*PersistedSecureSessionExistsFunct)(uint64_t peerNodeId);
PersistedSecureSessionExistsFunct IsPersistedTunnelSessionPresent;
/**
* Populate the persisted secure session within the passed WeaveConnection object
*/
typedef void (*LoadPersistedSessionFunct)(WeaveConnection *con);
LoadPersistedSessionFunct LoadPersistedTunnelSession;
void SetCallbacksForPersistedTunnelConnection(PersistedSecureSessionExistsFunct aIsPersistedTunnelSessionPresent,
LoadPersistedSessionFunct aLoadPersistedTunnelSession);
#endif // WEAVE_CONFIG_PERSIST_CONNECTED_SESSION
/**
* Initialize the WeaveTunnelConnectionMgr.
*/
WEAVE_ERROR Init(WeaveTunnelAgent *tunAgent, TunnelType tunType, SrcInterfaceType srcIntfType,
const char *connIntfName = NULL);
/**
* Shutdown the WeaveTunnelConnectionMgr.
*
*/
void Shutdown(void);
#if WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED
/**
* Configure the TCP user timeout.
*/
WEAVE_ERROR ConfigureConnTimeout(uint16_t maxTimeoutSecs);
#endif // WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED
#if WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED
/**
* Configure the TCP keepalive parameters.
*/
WEAVE_ERROR ConfigureAndEnableTCPKeepAlive(uint16_t intervalSecs, uint16_t maxNumProbes);
#endif // WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED
#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
/**
* Configure the Tunnel Liveness interval.
*/
void ConfigureTunnelLivenessInterval(uint16_t livenessIntervalSecs);
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
/**
* Set InterfaceName for Tunnel connection.
*/
void SetInterfaceName(const char *intfName);
/**
* Set SrcInterfaceType for Tunnel connection.
*/
void SetInterfaceType(const SrcInterfaceType srcIntfType);
/**
* Handler invoked if the Service Manager failed to establish the TCP connection to the Service.
*/
static void ServiceMgrStatusHandler(void* appState, WEAVE_ERROR err, StatusReport *report);
/**
* Handler invoked when Service TCP connection is completed. The device proceeds to initiate Tunnel control
* commands to the Service from this function.
*/
static void HandleServiceConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);
#if WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
/**
* Handler invoked when the Idle state of the underlying TCP connection's send channel changes.
*/
static void HandleTCPSendIdleChanged(TCPEndPoint *tcpEndPoint, bool isIdle);
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
/**
* Handler invoked when Service TCP connection is closed. The device tries to re-establish the connection to
* the Service if the mServiceConKeepAlive is set to true.
*/
static void HandleServiceConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr);
/**
* Handler to receive tunneled IPv6 packets from the Service TCP connection and forward to the Tunnel
* EndPoint interface after decapsulating the raw IPv6 packet from inside the tunnel header.
*/
static void RecvdFromService(WeaveConnection *con, const WeaveMessageInfo *msgInfo,
PacketBuffer *message);
/**
* @brief Callback to fetch the interval of time to wait before the next
* tunnel reconnect.
*
* @param[in] appState App state pointer set during initialization of
* the SubscriptionClient.
* @param[in] reconnectParam Structure with parameters that influence the calculation of the
* reconnection delay.
*
* @param[out] delayMsec Time in milliseconds to wait before next
* reconnect attempt.
*/
typedef void (*ConnectPolicyCallback) (void * const appState,
ReconnectParam & reconnectParam,
uint32_t & delayMsec);
ConnectPolicyCallback mServiceConnDelayPolicyCallback;
static void DefaultReconnectPolicyCallback(void * const appstate,
ReconnectParam & reconnectParam,
uint32_t & delayMsec);
/**
* Attempt to establish a connection to the Service.
*/
WEAVE_ERROR TryConnectingNow(void);
/**
* Close the Service tunnel.
*/
void ServiceTunnelClose(WEAVE_ERROR err);
/**
* Stop Service tunnel connection and attempt to reconnect again.
*/
void StopAndReconnectTunnelConn(ReconnectParam & reconnParam);
#if WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
void SetConnectionRepairInfoCallback(nl::Weave::WeaveConnection::ConnectionRepairInfoGetterFunct aGetConnectionRepairInfo, void *repairCtxt);
#endif // WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
/**
* Get a pointer to the Weave Tunnel Connection object for this
* Tunnel Connection Manager.
*/
nl::Weave::WeaveConnection * GetTunnelConnection(void) const;
private:
WEAVE_ERROR StartServiceTunnelConn(uint64_t destNodeId, IPAddress destIPAddr,
uint16_t destPort,
WeaveAuthMode authMode,
InterfaceId connIntfId);
void StopServiceTunnelConn(WEAVE_ERROR err);
void AttemptReconnect(ReconnectParam &reconnParam);
void DecideOnReconnect(ReconnectParam &reconnParam);
void ResetCacheAndScheduleConnect(uint32_t delay);
void ScheduleConnect(uint32_t delay);
void CancelDelayedReconnect(void);
void ReleaseResourcesAndStopTunnelConn(WEAVE_ERROR err);
WEAVE_ERROR ResetReconnectBackoff(bool reconnectImmediately);
static void ServiceConnectTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);
WEAVE_ERROR AllocateAndPrepTunnelConnection(WeaveConnection **con);
#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
void StartLivenessTimer(void);
void StopLivenessTimer(void);
void RestartLivenessTimer(void);
static void TunnelLivenessTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
void SetOnlineCheckIntervalFast(bool aProbeFast);
void StartOnlineCheck(void);
void StopOnlineCheck(void);
void ReStartOnlineCheck(void);
static void OnlineCheckTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);
void HandleOnlineCheckResult(bool isOnline);
#if WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
WEAVE_ERROR AttemptRepairTunnelConnection(uint64_t peerNodeId, WeaveAuthMode aAuthMode,
nl::Inet::InterfaceId aConnIntfId = INET_NULL_INTERFACEID);
#endif // WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
// Pointer to a Weave Tunnel Agent object.
WeaveTunnelAgent *mTunAgent;
// Tunnel control object
WeaveTunnelControl mTunControl;
// State of the Weave Tunnel Connection
TunnelConnectionState mConnectionState;
// Number of failed Service Tunnel connection attempts in a row
uint16_t mTunFailedConnAttemptsInRow;
// Maximum number of failed Service connection attempts before notification
uint16_t mMaxFailedConAttemptsBeforeNotify;
// The fibonacci index of the reconnect backoff.
uint16_t mTunReconnectFibonacciIndex;
// The tunnel type of this connection
TunnelType mTunType;
// Flag to indicate that the ResetReconnect timer is armed
bool mResetReconnectArmed;
// The interface type for this connection
SrcInterfaceType mSrcInterfaceType;
// The interface identifier for the tunnel connection to the Service
char mServiceConIntf[SERVICE_CONN_INTF_NAME_MAX_LEN];
// Handle to the Weave connection object.
WeaveConnection *mServiceCon;
#if WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED
// TCP connection keepalive interval (in secs)
uint16_t mKeepAliveIntervalSecs;
// The max number of TCP KeepAlive probes
uint16_t mMaxNumProbes;
#endif // WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED
#if WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED
// Tunnel TCP connection max user timeout (in secs)
uint16_t mMaxUserTimeoutSecs;
#endif // WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED
#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
// Tunnel Liveness interval
uint16_t mTunnelLivenessInterval;
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
// Flag to check if the network is online for this Tunnel.
bool mIsNetworkOnline;
// The current periodic interval for performing any online checks
// over the network.
uint16_t mOnlineCheckInterval;
#if WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
nl::Weave::WeaveConnection::ConnectionRepairInfoGetterFunct mConnRepairInfoGet;
void *mConnRepairCtxt; // A pointer to an application-specific context object used for repair info retrieval.
#endif // WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
};
} // namespace WeaveTunnel
} // namespace Profiles
} // namespace Weave
} // namespace nl
#endif // WEAVE_CONFIG_ENABLE_TUNNELING
#endif//_WEAVE_TUNNEL_CONNECTION_MGR_H_