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 "common/as_core_type.hpp"
41 #include "common/locator_getters.hpp"
42 #include "net/tcp6_ext.hpp"
43
44 #if OPENTHREAD_CONFIG_TLS_ENABLE
45
46 #include <mbedtls/ssl.h>
47
48 #endif
49
50 using namespace ot;
51
otTcpCircularSendBufferInitialize(otTcpCircularSendBuffer * aSendBuffer,void * aDataBuffer,size_t aCapacity)52 void otTcpCircularSendBufferInitialize(otTcpCircularSendBuffer *aSendBuffer, void *aDataBuffer, size_t aCapacity)
53 {
54 AsCoreType(aSendBuffer).Initialize(aDataBuffer, aCapacity);
55 }
56
otTcpCircularSendBufferWrite(otTcpEndpoint * aEndpoint,otTcpCircularSendBuffer * aSendBuffer,const void * aData,size_t aLength,size_t * aWritten,uint32_t aFlags)57 otError otTcpCircularSendBufferWrite(otTcpEndpoint *aEndpoint,
58 otTcpCircularSendBuffer *aSendBuffer,
59 const void *aData,
60 size_t aLength,
61 size_t *aWritten,
62 uint32_t aFlags)
63 {
64 AssertPointerIsNotNull(aWritten);
65 return AsCoreType(aSendBuffer).Write(AsCoreType(aEndpoint), aData, aLength, *aWritten, aFlags);
66 }
67
otTcpCircularSendBufferHandleForwardProgress(otTcpCircularSendBuffer * aSendBuffer,size_t aInSendBuffer)68 void otTcpCircularSendBufferHandleForwardProgress(otTcpCircularSendBuffer *aSendBuffer, size_t aInSendBuffer)
69 {
70 AsCoreType(aSendBuffer).HandleForwardProgress(aInSendBuffer);
71 }
72
otTcpCircularSendBufferGetFreeSpace(const otTcpCircularSendBuffer * aSendBuffer)73 size_t otTcpCircularSendBufferGetFreeSpace(const otTcpCircularSendBuffer *aSendBuffer)
74 {
75 return AsCoreType(aSendBuffer).GetFreeSpace();
76 }
77
otTcpCircularSendBufferForceDiscardAll(otTcpCircularSendBuffer * aSendBuffer)78 void otTcpCircularSendBufferForceDiscardAll(otTcpCircularSendBuffer *aSendBuffer)
79 {
80 AsCoreType(aSendBuffer).ForceDiscardAll();
81 }
82
otTcpCircularSendBufferDeinitialize(otTcpCircularSendBuffer * aSendBuffer)83 otError otTcpCircularSendBufferDeinitialize(otTcpCircularSendBuffer *aSendBuffer)
84 {
85 return AsCoreType(aSendBuffer).Deinitialize();
86 }
87
88 #if OPENTHREAD_CONFIG_TLS_ENABLE
89
otTcpMbedTlsSslSendCallback(void * aCtx,const unsigned char * aBuf,size_t aLen)90 int otTcpMbedTlsSslSendCallback(void *aCtx, const unsigned char *aBuf, size_t aLen)
91 {
92 otTcpEndpointAndCircularSendBuffer *pair = static_cast<otTcpEndpointAndCircularSendBuffer *>(aCtx);
93 otTcpEndpoint *endpoint = pair->mEndpoint;
94 otTcpCircularSendBuffer *sendBuffer = pair->mSendBuffer;
95 size_t bytes_written;
96 int result;
97 otError error;
98
99 error = otTcpCircularSendBufferWrite(endpoint, sendBuffer, aBuf, aLen, &bytes_written, 0);
100 VerifyOrExit(error == OT_ERROR_NONE, result = MBEDTLS_ERR_SSL_INTERNAL_ERROR);
101 VerifyOrExit(aLen == 0 || bytes_written != 0, result = MBEDTLS_ERR_SSL_WANT_WRITE);
102 result = static_cast<int>(bytes_written);
103
104 exit:
105 return result;
106 }
107
otTcpMbedTlsSslRecvCallback(void * aCtx,unsigned char * aBuf,size_t aLen)108 int otTcpMbedTlsSslRecvCallback(void *aCtx, unsigned char *aBuf, size_t aLen)
109 {
110 otTcpEndpointAndCircularSendBuffer *pair = static_cast<otTcpEndpointAndCircularSendBuffer *>(aCtx);
111 otTcpEndpoint *endpoint = pair->mEndpoint;
112 size_t bytes_read = 0;
113 const otLinkedBuffer *buffer;
114 int result;
115 otError error;
116
117 error = otTcpReceiveByReference(endpoint, &buffer);
118 VerifyOrExit(error == OT_ERROR_NONE, result = MBEDTLS_ERR_SSL_INTERNAL_ERROR);
119 while (bytes_read != aLen && buffer != nullptr)
120 {
121 size_t to_copy = OT_MIN(aLen - bytes_read, buffer->mLength);
122 memcpy(&aBuf[bytes_read], buffer->mData, to_copy);
123 bytes_read += to_copy;
124 buffer = buffer->mNext;
125 }
126 VerifyOrExit(aLen == 0 || bytes_read != 0, result = MBEDTLS_ERR_SSL_WANT_READ);
127 IgnoreReturnValue(otTcpCommitReceive(endpoint, bytes_read, 0));
128 result = static_cast<int>(bytes_read);
129
130 exit:
131 return result;
132 }
133
134 #endif // OPENTHREAD_CONFIG_TLS_ENABLE
135
136 #endif // OPENTHREAD_CONFIG_TCP_ENABLE
137