1 /*
2 * Copyright (c) 2022, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /**
30 * @file
31 * This file implements extensions to the OpenThread TCP API.
32 */
33
34 #include "openthread-core-config.h"
35
36 #if OPENTHREAD_CONFIG_TCP_ENABLE
37
38 #include <openthread/tcp_ext.h>
39
40 #include "instance/instance.hpp"
41 #include "net/tcp6_ext.hpp"
42
43 #if OPENTHREAD_CONFIG_TLS_ENABLE
44
45 #include <mbedtls/ssl.h>
46
47 #endif
48
49 using namespace ot;
50
otTcpCircularSendBufferInitialize(otTcpCircularSendBuffer * aSendBuffer,void * aDataBuffer,size_t aCapacity)51 void otTcpCircularSendBufferInitialize(otTcpCircularSendBuffer *aSendBuffer, void *aDataBuffer, size_t aCapacity)
52 {
53 AsCoreType(aSendBuffer).Initialize(aDataBuffer, aCapacity);
54 }
55
otTcpCircularSendBufferWrite(otTcpEndpoint * aEndpoint,otTcpCircularSendBuffer * aSendBuffer,const void * aData,size_t aLength,size_t * aWritten,uint32_t aFlags)56 otError otTcpCircularSendBufferWrite(otTcpEndpoint *aEndpoint,
57 otTcpCircularSendBuffer *aSendBuffer,
58 const void *aData,
59 size_t aLength,
60 size_t *aWritten,
61 uint32_t aFlags)
62 {
63 AssertPointerIsNotNull(aWritten);
64 return AsCoreType(aSendBuffer).Write(AsCoreType(aEndpoint), aData, aLength, *aWritten, aFlags);
65 }
66
otTcpCircularSendBufferHandleForwardProgress(otTcpCircularSendBuffer * aSendBuffer,size_t aInSendBuffer)67 void otTcpCircularSendBufferHandleForwardProgress(otTcpCircularSendBuffer *aSendBuffer, size_t aInSendBuffer)
68 {
69 AsCoreType(aSendBuffer).HandleForwardProgress(aInSendBuffer);
70 }
71
otTcpCircularSendBufferGetFreeSpace(const otTcpCircularSendBuffer * aSendBuffer)72 size_t otTcpCircularSendBufferGetFreeSpace(const otTcpCircularSendBuffer *aSendBuffer)
73 {
74 return AsCoreType(aSendBuffer).GetFreeSpace();
75 }
76
otTcpCircularSendBufferForceDiscardAll(otTcpCircularSendBuffer * aSendBuffer)77 void otTcpCircularSendBufferForceDiscardAll(otTcpCircularSendBuffer *aSendBuffer)
78 {
79 AsCoreType(aSendBuffer).ForceDiscardAll();
80 }
81
otTcpCircularSendBufferDeinitialize(otTcpCircularSendBuffer * aSendBuffer)82 otError otTcpCircularSendBufferDeinitialize(otTcpCircularSendBuffer *aSendBuffer)
83 {
84 return AsCoreType(aSendBuffer).Deinitialize();
85 }
86
87 #if OPENTHREAD_CONFIG_TLS_ENABLE
88
otTcpMbedTlsSslSendCallback(void * aCtx,const unsigned char * aBuf,size_t aLen)89 int otTcpMbedTlsSslSendCallback(void *aCtx, const unsigned char *aBuf, size_t aLen)
90 {
91 otTcpEndpointAndCircularSendBuffer *pair = static_cast<otTcpEndpointAndCircularSendBuffer *>(aCtx);
92 otTcpEndpoint *endpoint = pair->mEndpoint;
93 otTcpCircularSendBuffer *sendBuffer = pair->mSendBuffer;
94 size_t bytes_written;
95 int result;
96 otError error;
97
98 error = otTcpCircularSendBufferWrite(endpoint, sendBuffer, aBuf, aLen, &bytes_written, 0);
99 VerifyOrExit(error == OT_ERROR_NONE, result = MBEDTLS_ERR_SSL_INTERNAL_ERROR);
100 VerifyOrExit(aLen == 0 || bytes_written != 0, result = MBEDTLS_ERR_SSL_WANT_WRITE);
101 result = static_cast<int>(bytes_written);
102
103 exit:
104 return result;
105 }
106
otTcpMbedTlsSslRecvCallback(void * aCtx,unsigned char * aBuf,size_t aLen)107 int otTcpMbedTlsSslRecvCallback(void *aCtx, unsigned char *aBuf, size_t aLen)
108 {
109 otTcpEndpointAndCircularSendBuffer *pair = static_cast<otTcpEndpointAndCircularSendBuffer *>(aCtx);
110 otTcpEndpoint *endpoint = pair->mEndpoint;
111 size_t bytes_read = 0;
112 const otLinkedBuffer *buffer;
113 int result;
114 otError error;
115
116 error = otTcpReceiveByReference(endpoint, &buffer);
117 VerifyOrExit(error == OT_ERROR_NONE, result = MBEDTLS_ERR_SSL_INTERNAL_ERROR);
118 while (bytes_read != aLen && buffer != nullptr)
119 {
120 size_t to_copy = OT_MIN(aLen - bytes_read, buffer->mLength);
121 memcpy(&aBuf[bytes_read], buffer->mData, to_copy);
122 bytes_read += to_copy;
123 buffer = buffer->mNext;
124 }
125 VerifyOrExit(aLen == 0 || bytes_read != 0, result = MBEDTLS_ERR_SSL_WANT_READ);
126 IgnoreReturnValue(otTcpCommitReceive(endpoint, bytes_read, 0));
127 result = static_cast<int>(bytes_read);
128
129 exit:
130 return result;
131 }
132
133 #endif // OPENTHREAD_CONFIG_TLS_ENABLE
134
135 #endif // OPENTHREAD_CONFIG_TCP_ENABLE
136