[tcp] add TCP class and stub implementations of the TCP API (#6744)

This commit implements the boilerplate code for implementing the TCP
API in #6491. It creates a TCP class in src/core/net, and implements
the functions needed to transfer control there when a TCP API function
is called.
This commit is contained in:
Sam Kumar
2021-06-28 09:42:50 -07:00
committed by GitHub
parent 3a7e836dd7
commit 2752365e03
18 changed files with 976 additions and 167 deletions
+2
View File
@@ -201,6 +201,7 @@ LOCAL_SRC_FILES := \
src/core/api/srp_client_buffers_api.cpp \
src/core/api/srp_server_api.cpp \
src/core/api/tasklet_api.cpp \
src/core/api/tcp_api.cpp \
src/core/api/thread_api.cpp \
src/core/api/thread_ftd_api.cpp \
src/core/api/udp_api.cpp \
@@ -287,6 +288,7 @@ LOCAL_SRC_FILES := \
src/core/net/socket.cpp \
src/core/net/srp_client.cpp \
src/core/net/srp_server.cpp \
src/core/net/tcp6.cpp \
src/core/net/udp6.cpp \
src/core/radio/radio.cpp \
src/core/radio/radio_callbacks.cpp \
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (129)
#define OPENTHREAD_API_VERSION (130)
/**
* @addtogroup api-instance
+20 -13
View File
@@ -199,8 +199,10 @@ typedef void (*otTcpDisconnected)(otTcpEndpoint *aEndpoint, otTcpDisconnectedRea
*/
typedef struct otTcpEndpoint
{
struct otTcpEndpoint *mNext; ///< A pointer to the next TCP endpoint (internal use only)
void * mContext; ///< A pointer to application-specific context
struct otTcpEndpoint *mNext; ///< A pointer to the next TCP endpoint (internal use only)
otInstance * mInstance; ///< A pointer to the OpenThread instance associated with this TCP endpoint
void * mContext; ///< A pointer to application-specific context
otTcpEstablished mEstablishedCallback; ///< "Established" callback function
otTcpSendDone mSendDoneCallback; ///< "Send done" callback function
otTcpSendReady mSendReadyCallback; ///< "Send ready" callback function
@@ -215,15 +217,17 @@ typedef struct otTcpEndpoint
*/
typedef struct otTcpEndpointInitializeArgs
{
void *mContext; ///< Pointer to application-specific context
otTcpEstablished mEstablishedCallback; ///< "Established" callback function
otTcpSendDone mSendDoneCallback; ///< "Send done" callback function
otTcpBytesAcked mBytesAckedCallback; ///< "Bytes acked" callback
otTcpSendReady mSendReadyCallback; ///< "Send ready" callback function
otTcpReceiveAvailable mReceiveAvailableCallback; ///< "Receive available" callback function
otTcpDisconnected mDisconnectedCallback; ///< "Disconnected" callback function
void * mContext; ///< Pointer to application-specific context
void * mReceiveBuffer; ///< Pointer to memory provided to the system for the TCP receive buffer
size_t mReceiveBufferSize; ///< Size of memory provided to the system for the TCP receive buffer
void * mReceiveBuffer; ///< Pointer to memory provided to the system for the TCP receive buffer
size_t mReceiveBufferSize; ///< Size of memory provided to the system for the TCP receive buffer
} otTcpEndpointInitializeArgs;
/**
@@ -274,7 +278,7 @@ void *otTcpEndpointGetContext(otTcpEndpoint *aEndpoint);
*
* @returns The local host and port of @p aEndpoint.
*/
const otSockAddr *otTcpGetLocalAddress(otTcpEndpoint *aEndpoint);
const otSockAddr *otTcpGetLocalAddress(const otTcpEndpoint *aEndpoint);
/**
* Obtains a pointer to a TCP endpoint's peer's host and port.
@@ -286,7 +290,7 @@ const otSockAddr *otTcpGetLocalAddress(otTcpEndpoint *aEndpoint);
*
* @returns The host and port of the connection peer of @p aEndpoint.
*/
const otSockAddr *otTcpGetPeerAddress(otTcpEndpoint *aEndpoint);
const otSockAddr *otTcpGetPeerAddress(const otTcpEndpoint *aEndpoint);
/**
* Binds the TCP endpoint to an IP address and port.
@@ -388,7 +392,7 @@ otError otTcpSendByExtension(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_
* @retval OT_ERROR_NONE Successfully completed the operation.
* @retval OT_ERROR_FAILED Failed to complete the operation.
*/
otError otTcpReceiveByReference(otTcpEndpoint *aEndpoint, const otLinkedBuffer **aBuffer);
otError otTcpReceiveByReference(const otTcpEndpoint *aEndpoint, const otLinkedBuffer **aBuffer);
/**
* Reorganizes the receive buffer to be entirely contiguous in memory.
@@ -546,10 +550,12 @@ typedef void (*otTcpAcceptDone)(otTcpListener *aListener, otTcpEndpoint *aEndpoi
*/
typedef struct otTcpListener
{
struct otTcpListener *mNext; ///< A pointer to the next TCP listener (internal use only)
void * mContext; ///< A pointer to application-specific context
otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function
otTcpAcceptDone mAcceptDoneCallback; ///< "Accept done" callback function
struct otTcpListener *mNext; ///< A pointer to the next TCP listener (internal use only)
otInstance * mInstance; ///< A pointer to the OpenThread instance associated with this TCP listener
void * mContext; ///< A pointer to application-specific context
otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function
otTcpAcceptDone mAcceptDoneCallback; ///< "Accept done" callback function
/* Other implementation-defined fields go here. */
} otTcpListener;
@@ -559,9 +565,10 @@ typedef struct otTcpListener
*/
typedef struct otTcpListenerInitializeArgs
{
void *mContext; ///< Pointer to application-specific context
otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function
otTcpAcceptDone mAcceptDoneCallback; ///< "Accept done" callback function
void * mContext; ///< Pointer to application-specific context
} otTcpListenerInitializeArgs;
/**
+3 -1
View File
@@ -338,6 +338,7 @@ openthread_core_files = [
"api/srp_client_buffers_api.cpp",
"api/srp_server_api.cpp",
"api/tasklet_api.cpp",
"api/tcp_api.cpp",
"api/thread_api.cpp",
"api/thread_ftd_api.cpp",
"api/udp_api.cpp",
@@ -525,7 +526,8 @@ openthread_core_files = [
"net/srp_client.hpp",
"net/srp_server.cpp",
"net/srp_server.hpp",
"net/tcp.hpp",
"net/tcp6.cpp",
"net/tcp6.hpp",
"net/udp6.cpp",
"net/udp6.hpp",
"radio/max_power_table.hpp",
+2
View File
@@ -74,6 +74,7 @@ set(COMMON_SOURCES
api/srp_client_buffers_api.cpp
api/srp_server_api.cpp
api/tasklet_api.cpp
api/tcp_api.cpp
api/thread_api.cpp
api/thread_ftd_api.cpp
api/udp_api.cpp
@@ -160,6 +161,7 @@ set(COMMON_SOURCES
net/socket.cpp
net/srp_client.cpp
net/srp_server.cpp
net/tcp6.cpp
net/udp6.cpp
radio/radio.cpp
radio/radio_callbacks.cpp
+3 -1
View File
@@ -151,6 +151,7 @@ SOURCES_COMMON = \
api/srp_client_buffers_api.cpp \
api/srp_server_api.cpp \
api/tasklet_api.cpp \
api/tcp_api.cpp \
api/thread_api.cpp \
api/thread_ftd_api.cpp \
api/udp_api.cpp \
@@ -237,6 +238,7 @@ SOURCES_COMMON = \
net/socket.cpp \
net/srp_client.cpp \
net/srp_server.cpp \
net/tcp6.cpp \
net/udp6.cpp \
radio/radio.cpp \
radio/radio_callbacks.cpp \
@@ -498,7 +500,7 @@ HEADERS_COMMON = \
net/socket.hpp \
net/srp_client.hpp \
net/srp_server.hpp \
net/tcp.hpp \
net/tcp6.hpp \
net/udp6.hpp \
openthread-core-config.h \
radio/max_power_table.hpp \
+192
View File
@@ -0,0 +1,192 @@
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread TCP API.
*/
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_TCP_ENABLE
#include <openthread/tcp.h>
#include "common/instance.hpp"
#include "net/tcp6.hpp"
using namespace ot;
otError otTcpEndpointInitialize(otInstance *aInstance, otTcpEndpoint *aEndpoint, otTcpEndpointInitializeArgs *aArgs)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.Initialize(*static_cast<Instance *>(aInstance), *aArgs);
}
otInstance *otTcpEndpointGetInstance(otTcpEndpoint *aEndpoint)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return &endpoint.GetInstance();
}
void *otTcpEndpointGetContext(otTcpEndpoint *aEndpoint)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.GetContext();
}
const otSockAddr *otTcpGetLocalAddress(const otTcpEndpoint *aEndpoint)
{
const Ip6::Tcp::Endpoint &endpoint = *static_cast<const Ip6::Tcp::Endpoint *>(aEndpoint);
return &endpoint.GetLocalAddress();
}
const otSockAddr *otTcpGetPeerAddress(const otTcpEndpoint *aEndpoint)
{
const Ip6::Tcp::Endpoint &endpoint = *static_cast<const Ip6::Tcp::Endpoint *>(aEndpoint);
return &endpoint.GetPeerAddress();
}
otError otTcpBind(otTcpEndpoint *aEndpoint, const otSockAddr *aSockName)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.Bind(*static_cast<const Ip6::SockAddr *>(aSockName));
}
otError otTcpConnect(otTcpEndpoint *aEndpoint, const otSockAddr *aSockName, uint32_t aFlags)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.Connect(*static_cast<const Ip6::SockAddr *>(aSockName), aFlags);
}
otError otTcpSendByReference(otTcpEndpoint *aEndpoint, otLinkedBuffer *aBuffer, uint32_t aFlags)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.SendByReference(*aBuffer, aFlags);
}
otError otTcpSendByExtension(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_t aFlags)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.SendByExtension(aNumBytes, aFlags);
}
otError otTcpReceiveByReference(const otTcpEndpoint *aEndpoint, const otLinkedBuffer **aBuffer)
{
const Ip6::Tcp::Endpoint &endpoint = *static_cast<const Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.ReceiveByReference(*aBuffer);
}
otError otTcpReceiveContiguify(otTcpEndpoint *aEndpoint)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.ReceiveContiguify();
}
otError otTcpCommitReceive(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_t aFlags)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.CommitReceive(aNumBytes, aFlags);
}
otError otTcpSendEndOfStream(otTcpEndpoint *aEndpoint)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.SendEndOfStream();
}
otError otTcpAbort(otTcpEndpoint *aEndpoint)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.Abort();
}
otError otTcpEndpointDeinitialize(otTcpEndpoint *aEndpoint)
{
Ip6::Tcp::Endpoint &endpoint = *static_cast<Ip6::Tcp::Endpoint *>(aEndpoint);
return endpoint.Deinitialize();
}
otError otTcpListenerInitialize(otInstance *aInstance, otTcpListener *aListener, otTcpListenerInitializeArgs *aArgs)
{
Ip6::Tcp::Listener &listener = *static_cast<Ip6::Tcp::Listener *>(aListener);
return listener.Initialize(*static_cast<Instance *>(aInstance), *aArgs);
}
otInstance *otTcpListenerGetInstance(otTcpListener *aListener)
{
Ip6::Tcp::Listener &listener = *static_cast<Ip6::Tcp::Listener *>(aListener);
return &listener.GetInstance();
}
void *otTcpListenerGetContext(otTcpListener *aListener)
{
Ip6::Tcp::Listener &listener = *static_cast<Ip6::Tcp::Listener *>(aListener);
return listener.GetContext();
}
otError otTcpListen(otTcpListener *aListener, const otSockAddr *aSockName)
{
Ip6::Tcp::Listener &listener = *static_cast<Ip6::Tcp::Listener *>(aListener);
return listener.Listen(*static_cast<const Ip6::SockAddr *>(aSockName));
}
otError otTcpStopListening(otTcpListener *aListener)
{
Ip6::Tcp::Listener &listener = *static_cast<Ip6::Tcp::Listener *>(aListener);
return listener.StopListening();
}
otError otTcpListenerDeinitialize(otTcpListener *aListener)
{
Ip6::Tcp::Listener &listener = *static_cast<Ip6::Tcp::Listener *>(aListener);
return listener.Deinitialize();
}
#endif // OPENTHREAD_CONFIG_TCP_ENABLE
+7
View File
@@ -645,6 +645,13 @@ template <> inline NetworkData::Service::Manager &Instance::Get(void)
return mThreadNetif.mNetworkDataServiceManager;
}
#if OPENTHREAD_CONFIG_TCP_ENABLE
template <> inline Ip6::Tcp &Instance::Get(void)
{
return mIp6.mTcp;
}
#endif
template <> inline Ip6::Udp &Instance::Get(void)
{
return mIp6.mUdp;
+10
View File
@@ -177,4 +177,14 @@
#define OPENTHREAD_CONFIG_UNSECURE_TRAFFIC_MANAGED_BY_STACK_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_TCP_ENABLE
*
* Define as 1 to enable TCP.
*
*/
#ifndef OPENTHREAD_CONFIG_TCP_ENABLE
#define OPENTHREAD_CONFIG_TCP_ENABLE 1
#endif
#endif // CONFIG_IP6_H_
+5
View File
@@ -36,6 +36,7 @@
#include "common/code_utils.hpp"
#include "common/message.hpp"
#include "net/icmp6.hpp"
#include "net/tcp6.hpp"
#include "net/udp6.hpp"
namespace ot {
@@ -133,6 +134,10 @@ void Checksum::UpdateMessageChecksum(Message & aMessage,
switch (aIpProto)
{
case Ip6::kProtoTcp:
headerOffset = Ip6::Tcp::Header::kChecksumFieldOffset;
break;
case Ip6::kProtoUdp:
headerOffset = Ip6::Udp::Header::kChecksumFieldOffset;
break;
+12
View File
@@ -72,6 +72,9 @@ Ip6::Ip6(Instance &aInstance)
, mIcmp(aInstance)
, mUdp(aInstance)
, mMpl(aInstance)
#if OPENTHREAD_CONFIG_TCP_ENABLE
, mTcp(aInstance)
#endif
{
}
@@ -958,6 +961,15 @@ Error Ip6::HandlePayload(Message & aMessage,
switch (aIpProto)
{
#if OPENTHREAD_CONFIG_TCP_ENABLE
case kProtoTcp:
error = mTcp.ProcessReceivedSegment(*message, aMessageInfo);
if (error == kErrorDrop)
{
otLogNoteIp6("Error TCP Checksum");
}
break;
#endif
case kProtoUdp:
error = mUdp.HandleMessage(*message, aMessageInfo);
if (error == kErrorDrop)
+5
View File
@@ -53,6 +53,7 @@
#include "net/ip6_mpl.hpp"
#include "net/netif.hpp"
#include "net/socket.hpp"
#include "net/tcp6.hpp"
#include "net/udp6.hpp"
namespace ot {
@@ -376,6 +377,10 @@ private:
Udp mUdp;
Mpl mMpl;
#if OPENTHREAD_CONFIG_TCP_ENABLE
Tcp mTcp;
#endif
#if OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE
MessageQueue mReassemblyList;
#endif
+1 -1
View File
@@ -41,7 +41,7 @@
#include "common/logging.hpp"
#include "meshcop/meshcop.hpp"
#include "net/ip6.hpp"
#include "net/tcp.hpp"
#include "net/tcp6.hpp"
#include "net/udp6.hpp"
#include "thread/mle.hpp"
-148
View File
@@ -1,148 +0,0 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for parsing TCP header.
*/
#ifndef TCP_HPP_
#define TCP_HPP_
#include "openthread-core-config.h"
#include "net/ip6_headers.hpp"
namespace ot {
namespace Ip6 {
namespace Tcp {
/**
* @addtogroup core-tcp
*
* @brief
* This module includes definitions for parsing TCP header
*
* @{
*
*/
/**
* This class implements TCP header parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class Header
{
public:
/**
* This method returns the TCP Source Port.
*
* @returns The TCP Source Port.
*
*/
uint16_t GetSourcePort(void) const { return HostSwap16(mSource); }
/**
* This method returns the TCP Destination Port.
*
* @returns The TCP Destination Port.
*
*/
uint16_t GetDestinationPort(void) const { return HostSwap16(mDestination); }
/**
* This method returns the TCP Sequence Number.
*
* @returns The TCP Sequence Number.
*
*/
uint32_t GetSequenceNumber(void) const { return HostSwap32(mSequenceNumber); }
/**
* This method returns the TCP Acknowledgment Sequence Number.
*
* @returns The TCP Acknowledgment Sequence Number.
*
*/
uint32_t GetAcknowledgmentNumber(void) const { return HostSwap32(mAckNumber); }
/**
* This method returns the TCP Flags.
*
* @returns The TCP Flags.
*
*/
uint16_t GetFlags(void) const { return HostSwap16(mFlags); }
/**
* This method returns the TCP Window.
*
* @returns The TCP Window.
*
*/
uint16_t GetWindow(void) const { return HostSwap16(mWindow); }
/**
* This method returns the TCP Checksum.
*
* @returns The TCP Checksum.
*
*/
uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); }
/**
* This method returns the TCP Urgent Pointer.
*
* @returns The TCP Urgent Pointer.
*
*/
uint16_t GetUrgentPointer(void) const { return HostSwap16(mUrgentPointer); }
private:
uint16_t mSource;
uint16_t mDestination;
uint32_t mSequenceNumber;
uint32_t mAckNumber;
uint16_t mFlags;
uint16_t mWindow;
uint16_t mChecksum;
uint16_t mUrgentPointer;
} OT_TOOL_PACKED_END;
/**
* @}
*
*/
} // namespace Tcp
} // namespace Ip6
} // namespace ot
#endif // TCP_HPP_
+193
View File
@@ -0,0 +1,193 @@
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements TCP/IPv6 sockets.
*/
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_TCP_ENABLE
#include "tcp6.hpp"
#include "common/code_utils.hpp"
#include "common/error.hpp"
namespace ot {
namespace Ip6 {
Tcp::Tcp(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
Error Tcp::Endpoint::Initialize(Instance &aInstance, otTcpEndpointInitializeArgs &aArgs)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aArgs);
return kErrorNotImplemented;
}
Instance &Tcp::Endpoint::GetInstance(void)
{
return *reinterpret_cast<Instance *>(this->mInstance);
}
void *Tcp::Endpoint::GetContext(void)
{
return this->mContext;
}
const SockAddr &Tcp::Endpoint::GetLocalAddress(void) const
{
static otSockAddr temp;
return *static_cast<SockAddr *>(&temp);
}
const SockAddr &Tcp::Endpoint::GetPeerAddress(void) const
{
static otSockAddr temp;
return *static_cast<SockAddr *>(&temp);
}
Error Tcp::Endpoint::Bind(const SockAddr &aSockName)
{
OT_UNUSED_VARIABLE(aSockName);
return kErrorNotImplemented;
}
Error Tcp::Endpoint::Connect(const SockAddr &aSockName, uint32_t aFlags)
{
OT_UNUSED_VARIABLE(aSockName);
OT_UNUSED_VARIABLE(aFlags);
return kErrorNotImplemented;
}
Error Tcp::Endpoint::SendByReference(otLinkedBuffer &aBuffer, uint32_t aFlags)
{
OT_UNUSED_VARIABLE(aBuffer);
OT_UNUSED_VARIABLE(aFlags);
return kErrorNotImplemented;
}
Error Tcp::Endpoint::SendByExtension(size_t aNumBytes, uint32_t aFlags)
{
OT_UNUSED_VARIABLE(aNumBytes);
OT_UNUSED_VARIABLE(aFlags);
return kErrorNotImplemented;
}
Error Tcp::Endpoint::ReceiveByReference(const otLinkedBuffer *&aBuffer) const
{
OT_UNUSED_VARIABLE(aBuffer);
return kErrorNotImplemented;
}
Error Tcp::Endpoint::ReceiveContiguify(void)
{
return kErrorNotImplemented;
}
Error Tcp::Endpoint::CommitReceive(size_t aNumBytes, uint32_t aFlags)
{
OT_UNUSED_VARIABLE(aNumBytes);
OT_UNUSED_VARIABLE(aFlags);
return kErrorNotImplemented;
}
Error Tcp::Endpoint::SendEndOfStream(void)
{
return kErrorNotImplemented;
}
Error Tcp::Endpoint::Abort(void)
{
return kErrorNotImplemented;
}
Error Tcp::Endpoint::Deinitialize(void)
{
return kErrorNotImplemented;
}
Error Tcp::Listener::Initialize(Instance &aInstance, otTcpListenerInitializeArgs &aArgs)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aArgs);
return kErrorNotImplemented;
}
Instance &Tcp::Listener::GetInstance(void)
{
return *reinterpret_cast<Instance *>(this->mInstance);
}
void *Tcp::Listener::GetContext(void)
{
return this->mContext;
}
Error Tcp::Listener::Listen(const SockAddr &aSockName)
{
OT_UNUSED_VARIABLE(aSockName);
return kErrorNotImplemented;
}
Error Tcp::Listener::StopListening(void)
{
return kErrorNotImplemented;
}
Error Tcp::Listener::Deinitialize(void)
{
return kErrorNotImplemented;
}
Error Tcp::ProcessReceivedSegment(Message &aMessage, MessageInfo &aMessageInfo)
{
OT_UNUSED_VARIABLE(aMessage);
OT_UNUSED_VARIABLE(aMessageInfo);
return kErrorNotImplemented;
}
} // namespace Ip6
} // namespace ot
#endif // OPENTHREAD_CONFIG_TCP_ENABLE
+518
View File
@@ -0,0 +1,518 @@
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for UDP/IPv6 sockets.
*/
#ifndef TCP6_HPP_
#define TCP6_HPP_
#include "openthread-core-config.h"
#include <openthread/tcp.h>
#include "net/ip6_headers.hpp"
#include "net/socket.hpp"
#include "common/linked_list.hpp"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
namespace ot {
namespace Ip6 {
class Udp;
/**
* @addtogroup core-tcp
*
* @brief
* This module includes definitions for TCP/IPv6 sockets.
*
* @{
*
*/
class Tcp : public InstanceLocator, private NonCopyable
{
public:
/**
* This class represents an endpoint of a TCP/IPv6 connection.
*
*/
class Endpoint : public otTcpEndpoint, public LinkedListEntry<Endpoint>
{
friend class Tcp;
friend class LinkedList<Endpoint>;
public:
/**
* Initializes a TCP endpoint.
*
* Calling this function causes OpenThread to keep track of this Endpoint
* and store and retrieve TCP data inside of it. The application
* should refrain from directly accessing or modifying the fields in
* this Endpoint. If the application needs to reclaimthe memory backing
* this Endpoint, it should call otTcpEndpointDeinitialize().
*
* @sa otTcpEndpointInitialize in include/openthread/tcp.h.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aArgs A pointer to a structure of arguments.
*
* @retval kErrorNone Successfully opened the TCP endpoint.
* @retval kErrorFailed Failed to open the TCP endpoint.
*/
Error Initialize(Instance &aInstance, otTcpEndpointInitializeArgs &aArgs);
/**
* Obtains the Instance that was associated with this Endpoint upon
* initialization.
*
* @sa otTcpEndpointGetInstance
*
* @returns The Instance pointer associated with this Endpoint.
*/
Instance &GetInstance(void);
/**
* Obtains the context pointer that was associated this Endpoint upon
* initialization.
*
* @sa otTcpEndpointGetContext
*
* @returns The context pointer associated with this Endpoint.
*/
void *GetContext(void);
/**
* Obtains a pointer to a TCP endpoint's local host and port.
*
* The contents of the host and port may be stale if this socket is not in a
* connected state and has not been bound after it was last disconnected.
*
* @sa otTcpGetLocalAddress
*
* @returns The local host and port of this Endpoint.
*/
const SockAddr &GetLocalAddress(void) const;
/**
* Obtains a pointer to a TCP endpoint's peer's host and port.
*
* The contents of the host and port may be stale if this socket is not in a
* connected state.
*
* @sa otTcpGetPeerAddress
*
* @returns The host and port of the connection peer of this Endpoint.
*/
const SockAddr &GetPeerAddress(void) const;
/**
* Binds the TCP endpoint to an IP address and port.
*
* @sa otTcpBind
*
* @param[in] aSockName The address and port to which to bind this TCP endpoint.
*
* @retval kErrorNone Successfully bound the TCP endpoint.
* @retval kErrorFailed Failed to bind the TCP endpoint.
*/
Error Bind(const SockAddr &aSockName);
/**
* Records the remote host and port for this connection.
*
* By default TCP Fast Open is used. This means that this function merely
* records the remote host and port, and that the TCP connection establishment
* handshake only happens on the first call to otTcpSendByReference(). TCP Fast
* Open can be explicitly disabled using @p aFlags, in which case the TCP
* connection establishment handshake is initiated immediately.
*
* @sa otTcpConnect
*
* @param[in] aSockName The IP address and port of the host to which to connect.
* @param[in] aFlags Flags specifying options for this operation (see enumeration above).
*
* @retval kErrorNone Successfully completed the operation.
* @retval kErrorFailed Failed to complete the operation.
*/
Error Connect(const SockAddr &aSockName, uint32_t aFlags);
/**
* Adds data referenced by the linked buffer pointed to by @p aBuffer to the
* send buffer.
*
* Upon a sucessful call to this function, the linked buffer and data it
* references are owned by the TCP stack; they should not be modified by the
* application until a "send done" callback returns ownership of those objects
* to the application. It is acceptable to call this function to add another
* linked buffer to the send queue, even if the "send done" callback for a
* previous invocation of this function has not yet fired.
*
* Note that @p aBuffer should not be chained; its mNext field should be
* NULL. If additional data will be added right after this call, then the
* OT_TCP_SEND_MORE_TO_COME flag should be used as a hint to the TCP
* implementation.
*
* @sa otTcpSendByReference
*
* @param[in] aBuffer A pointer to the linked buffer chain referencing data to add to the send buffer.
* @param[in] aFlags Flags specifying options for this operation (see enumeration above).
*
* @retval kErrorNone Successfully added data to the send buffer.
* @retval kErrorFailed Failed to add data to the send buffer.
*/
Error SendByReference(otLinkedBuffer &aBuffer, uint32_t aFlags);
/**
* Adds data to the send buffer by extending the length of the final
* otLinkedBuffer in the send buffer by the specified amount.
*
* If the send buffer is empty, then the operation fails.
*
* @sa otTcpSendByExtension
*
* @param[in] aNumBytes The number of bytes by which to extend the length of the final linked buffer.
* @param[in] aFlags Flags specifying options for this operation (see enumeration above).
*
* @retval kErrorNone Successfully added data to the send buffer.
* @retval kErrorFailed Failed to add data to the send buffer.
*/
Error SendByExtension(size_t aNumBytes, uint32_t aFlags);
/**
* Provides the application with a linked buffer chain referencing data
* currently in the TCP receive buffer.
*
* The linked buffer chain is valid until the "receive ready" callback is next
* invoked, or until the next call to otTcpReceiveContiguify() or
* otTcpCommitReceive().
*
* @sa otTcpReceiveByReference
*
* @param[out] aBuffer A pointer to the linked buffer chain referencing data currently in the receive
* buffer.
*
* @retval kErrorNone Successfully completed the operation.
* @retval kErrorFailed Failed to complete the operation.
*/
Error ReceiveByReference(const otLinkedBuffer *&aBuffer) const;
/**
* Reorganizes the receive buffer to be entirely contiguous in memory.
*
* This is optional; an application can simply traverse the linked buffer
* chain obtained by calling @p otTcpReceiveByReference. Some
* applications may wish to call this function to make the receive buffer
* contiguous to simplify their data processing, but this comes at the expense
* of CPU time to reorganize the data in the receive buffer.
*
* @sa otTcpReceiveContiguify
*
* @retval kErrorNone Successfully completed the operation.
* @retval kErrorFailed Failed to complete the operation.
*/
Error ReceiveContiguify(void);
/**
* Informs the TCP stack that the application has finished processing
* @p aNumBytes bytes of data at the start of the receive buffer and that the
* TCP stack need not continue maintaining those bytes in the receive buffer.
*
* @sa otTcpCommitReceive
*
* @param[in] aNumBytes The number of bytes consumed.
* @param[in] aFlags Flags specifying options for this operation (none yet).
*
* @retval kErrorNone Successfully completed the receive operation.
* @retval kErrorFailed Failed to complete the receive operation.
*/
Error CommitReceive(size_t aNumBytes, uint32_t aFlags);
/**
* Informs the connection peer that this TCP endpoint will not send more data.
*
* This should be used when the application has no more data to send to the
* connection peer. For this connection, future reads on the connection peer
* will result in the "end of stream" condition, and future writes on this
* connection endpoint will fail.
*
* The "end of stream" condition only applies after any data previously
* provided to the TCP stack to send out has been received by the connection
* peer.
*
* @sa otTcpSendEndOfStream
*
* @retval kErrorNone Successfully queued the "end of stream" condition for transmission.
* @retval kErrorFailed Failed to queue the "end of stream" condition for transmission.
*/
Error SendEndOfStream(void);
/**
* Forcibly ends the TCP connection associated with this TCP endpoint.
*
* This immediately makes the TCP endpoint free for use for another connection
* and empties the send and receive buffers, transferring ownership of any data
* provided by the application in otTcpSendByReference() calls back to
* the application. The TCP endpoint's callbacks and memory for the receive
* buffer remain associated with the TCP endpoint.
*
* @sa otTcpAbort
*
* @retval kErrorNone Successfully aborted the TCP endpoint's connection.
* @retval kErrorFailed Failed to abort the TCP endpoint's connection.
*/
Error Abort(void);
/**
* Deinitializes this TCP endpoint.
*
* This means that OpenThread no longer keeps track of this TCP endpoint and
* deallocates all resources it has internally allocated for this TCP endpoint.
* The application can reuse the memory backing the TCP endpoint as it sees fit.
*
* If it corresponds to a live TCP connection, the connection is terminated
* unceremoniously (as in otTcpAbort()). All resources the application has
* provided for this TCP endpoint (linked buffers for the send buffer, memory
* for the receive buffer, this Endpoint structure itself, etc.) are
* immediately returned to the application.
*
* @sa otTcpEndpointDeinitialize
*
* @retval kErrorNone Successfully deinitialized the TCP endpoint.
* @retval kErrorFailed Failed to deinitialize the TCP endpoint.
*/
Error Deinitialize(void);
};
/**
* This class represents a TCP/IPv6 listener.
*/
class Listener : public otTcpListener, public LinkedListEntry<Listener>
{
friend class Tcp;
friend class LinkedList<Listener>;
public:
/**
* Initializes a TCP listener.
*
* Calling this function causes OpenThread to keep track of the TCP listener
* and store and retrieve TCP data inside this Listener. The application should
* refrain from directly accessing or modifying the fields in this Listener. If
* the application needs to reclaim the memory backing this Listener, it should
* call otTcpListenerDeinitialize().
*
* @sa otTcpListenerInitialize
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aArgs A pointer to a structure of arguments.
*
* @retval kErrorNone Successfully opened the TCP listener.
* @retval kErrorFailed Failed to open the TCP listener.
*/
Error Initialize(Instance &aInstance, otTcpListenerInitializeArgs &aArgs);
/**
* Obtains the otInstance that was associated with this Listener upon
* initialization.
*
* @sa otTcpListenerGetInstance
*
* @returns The otInstance pointer associated with this Listener.
*/
Instance &GetInstance(void);
/**
* Obtains the context pointer that was associated with this Listener upon
* initialization.
*
* @sa otTcpListenerGetContext
*
* @returns The context pointer associated with this Listener.
*/
void *GetContext(void);
/**
* Causes incoming TCP connections that match the specified IP address and port
* to trigger this TCP listener's callbacks.
*
* @sa otTcpListen
*
* @param[in] aSockName The address and port on which to listen for incoming connections.
*
* @retval kErrorNone Successfully initiated listening on the TCP listener.
* @retval kErrorFailed Failed to initiate listening on the TCP listener.
*/
Error Listen(const SockAddr &aSockName);
/**
* Causes this TCP listener to stop listening for incoming connections.
*
* @sa otTcpStopListening
*
* @retval kErrorNone Successfully stopped listening on the TCP listener.
* @retval kErrorFailed Failed to stop listening on the TCP listener.
*/
Error StopListening(void);
/**
* Deinitializes this TCP listener.
*
* This means that OpenThread no longer keeps track of this TCP listener and
* deallocates all resources it has internally allocated for this TCP listener.
* The application can reuse the memory backing the TCP listener as it sees
* fit.
*
* If the TCP listener is currently listening, it stops listening.
*
* @sa otTcpListenerDeinitialize
*
* @retval kErrorNone Successfully deinitialized the TCP listener.
* @retval kErrorFailed Failed to deinitialize the TCP listener.
*/
Error Deinitialize(void);
};
/**
* This class implements TCP header parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class Header
{
public:
enum : uint8_t
{
kChecksumFieldOffset = 16, ///< The byte offset of the Checksum field in the TCP header.
};
/**
* This method returns the TCP Source Port.
*
* @returns The TCP Source Port.
*
*/
uint16_t GetSourcePort(void) const { return HostSwap16(mSource); }
/**
* This method returns the TCP Destination Port.
*
* @returns The TCP Destination Port.
*
*/
uint16_t GetDestinationPort(void) const { return HostSwap16(mDestination); }
/**
* This method returns the TCP Sequence Number.
*
* @returns The TCP Sequence Number.
*
*/
uint32_t GetSequenceNumber(void) const { return HostSwap32(mSequenceNumber); }
/**
* This method returns the TCP Acknowledgment Sequence Number.
*
* @returns The TCP Acknowledgment Sequence Number.
*
*/
uint32_t GetAcknowledgmentNumber(void) const { return HostSwap32(mAckNumber); }
/**
* This method returns the TCP Flags.
*
* @returns The TCP Flags.
*
*/
uint16_t GetFlags(void) const { return HostSwap16(mFlags); }
/**
* This method returns the TCP Window.
*
* @returns The TCP Window.
*
*/
uint16_t GetWindow(void) const { return HostSwap16(mWindow); }
/**
* This method returns the TCP Checksum.
*
* @returns The TCP Checksum.
*
*/
uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); }
/**
* This method returns the TCP Urgent Pointer.
*
* @returns The TCP Urgent Pointer.
*
*/
uint16_t GetUrgentPointer(void) const { return HostSwap16(mUrgentPointer); }
private:
uint16_t mSource;
uint16_t mDestination;
uint32_t mSequenceNumber;
uint32_t mAckNumber;
uint16_t mFlags;
uint16_t mWindow;
uint16_t mChecksum;
uint16_t mUrgentPointer;
} OT_TOOL_PACKED_END;
/**
* This constructor initializes the object.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit Tcp(Instance &aInstance);
/**
* Processes a received TCP segment.
*
* @param[in] aMessage A reference to the message containing the TCP segment.
* @param[in] aMessageInfo A refernce to the message info associated with @p aMessage.
*
* @retval kErrorNone Successfully processed the TCP segment.
* @retval kErrorDrop Dropped the TCP segment due to an invalid checksum.
*
*/
Error ProcessReceivedSegment(Message &aMessage, MessageInfo &aMessageInfo);
};
} // namespace Ip6
} // namespace ot
#endif // TCP6_HPP_
+1 -1
View File
@@ -45,7 +45,7 @@
#include "net/ip6.hpp"
#include "net/ip6_filter.hpp"
#include "net/netif.hpp"
#include "net/tcp.hpp"
#include "net/tcp6.hpp"
#include "net/udp6.hpp"
#include "radio/radio.hpp"
#include "thread/mle.hpp"
+1 -1
View File
@@ -39,7 +39,7 @@
#include "common/logging.hpp"
#include "meshcop/meshcop.hpp"
#include "net/ip6.hpp"
#include "net/tcp.hpp"
#include "net/tcp6.hpp"
#include "net/udp6.hpp"
namespace ot {