1 /* 2 * Copyright (c) 2021, 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 * @brief 32 * This file includes the platform abstraction for DNS Stateful Operations (DSO) transport. 33 */ 34 35 #ifndef OPENTHREAD_PLATFORM_DSO_TRANSPORT_H_ 36 #define OPENTHREAD_PLATFORM_DSO_TRANSPORT_H_ 37 38 #include <stdint.h> 39 40 #include <openthread/error.h> 41 #include <openthread/instance.h> 42 #include <openthread/ip6.h> 43 #include <openthread/message.h> 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 /** 50 * Represents a DSO connection. 51 * 52 * It is an opaque struct (the platform implementation only deals with pointers to this struct). 53 * 54 */ 55 typedef struct otPlatDsoConnection otPlatDsoConnection; 56 57 /** 58 * Can be used by DSO platform implementation to get the the OpenThread instance associated with a 59 * connection instance. 60 * 61 * @param[in] aConnection A pointer to the DSO connection. 62 * 63 * @returns A pointer to the `otInstance`. 64 * 65 */ 66 extern otInstance *otPlatDsoGetInstance(otPlatDsoConnection *aConnection); 67 68 /** 69 * Starts or stops listening for incoming connection requests on transport layer. 70 * 71 * For DNS-over-TLS, the transport layer MUST listen on port 853 and follow RFC 7858. 72 * 73 * While listening is enabled, if a connection request is received, the `otPlatDsoAccept()` callback MUST be called. 74 * 75 * @param[in] aInstance The OpenThread instance. 76 * @param[in] aEnable TRUE to start listening, FALSE to stop listening. 77 * 78 */ 79 void otPlatDsoEnableListening(otInstance *aInstance, bool aEnable); 80 81 /** 82 * Is a callback from the DSO platform to indicate an incoming connection request when listening is 83 * enabled. 84 * 85 * Determines whether or not to accept the connection request. It returns a non-null `otPlatDsoConnection` 86 * pointer if the request is to be accepted, or `NULL` if the request is to be rejected. 87 * 88 * If a non-null connection pointer is returned, the platform layer MUST continue establishing the connection with the 89 * peer. The platform reports the outcome by invoking `otPlatDsoHandleConnected()` callback on success or 90 * `otPlatDsoHandleDisconnected()` callback on failure. 91 * 92 * @param[in] aInstance The OpenThread instance. 93 * @param[in] aPeerSockAddr The socket address (IPv6 address and port number) of the peer requesting connection. 94 * 95 * @returns A pointer to the `otPlatDsoConnection` to use if to accept, or `NULL` if to reject. 96 * 97 */ 98 extern otPlatDsoConnection *otPlatDsoAccept(otInstance *aInstance, const otSockAddr *aPeerSockAddr); 99 100 /** 101 * Requests the platform layer to initiate establishing a connection with a peer. 102 * 103 * The platform reports the outcome by invoking `otPlatDsoHandleConnected()` callback on success or 104 * `otPlatDsoHandleDisconnected()` callback (on failure). 105 * 106 * @param[in] aConnection The connection. 107 * @param[in] aPeerSockAddr The socket address (IPv6 address and port number) of the peer to connect to. 108 * 109 */ 110 void otPlatDsoConnect(otPlatDsoConnection *aConnection, const otSockAddr *aPeerSockAddr); 111 112 /** 113 * Is a callback from the platform layer to indicate that a connection is successfully established. 114 * 115 * It MUST be called either after accepting an incoming connection (`otPlatDsoAccept`) or after a `otPlatDsoConnect()` 116 * call. 117 * 118 * Only after this callback, the connection can be used to send and receive messages. 119 * 120 * @param[in] aConnection The connection. 121 * 122 */ 123 extern void otPlatDsoHandleConnected(otPlatDsoConnection *aConnection); 124 125 /** 126 * Sends a DSO message to the peer on a connection. 127 * 128 * Is used only after the connection is successfully established (after `otPlatDsoHandleConnected()` 129 * callback). 130 * 131 * Passes the ownership of the @p aMessage to the DSO platform layer, and the platform implementation is 132 * expected to free the message once it is no longer needed. 133 * 134 * The @p aMessage contains the DNS message (starting with DNS header). Note that it does not contain the the length 135 * field that is needed when sending over TLS/TCP transport. The platform layer MUST therefore include the length 136 * field when passing the message to TLS/TCP layer. 137 * 138 * @param[in] aConnection The connection to send on. 139 * @param[in] aMessage The message to send. 140 * 141 */ 142 void otPlatDsoSend(otPlatDsoConnection *aConnection, otMessage *aMessage); 143 144 /** 145 * Is a callback from the platform layer to indicate that a DNS message was received over a connection. 146 * 147 * The platform MUST call this function only after the connection is successfully established (after callback 148 * `otPlatDsoHandleConnected()` is invoked). 149 * 150 * Passes the ownership of the @p aMessage from the DSO platform layer to OpenThread. OpenThread will 151 * free the message when no longer needed. 152 * 153 * The @p aMessage MUST contain the DNS message (starting with DNS header) and not include the length field that may 154 * be included in TCP/TLS exchange. 155 * 156 * @param[in] aConnection The connection on which the message was received. 157 * @param[in] aMessage The received message. 158 * 159 */ 160 extern void otPlatDsoHandleReceive(otPlatDsoConnection *aConnection, otMessage *aMessage); 161 162 /** 163 * Defines disconnect modes. 164 * 165 */ 166 typedef enum 167 { 168 OT_PLAT_DSO_DISCONNECT_MODE_GRACEFULLY_CLOSE, ///< Gracefully close the connection. 169 OT_PLAT_DSO_DISCONNECT_MODE_FORCIBLY_ABORT, ///< Forcibly abort the connection. 170 } otPlatDsoDisconnectMode; 171 172 /** 173 * Requests a connection to be disconnected. 174 * 175 * After calling this function, the DSO platform implementation MUST NOT maintain `aConnection` pointer (platform 176 * MUST NOT call any callbacks using this `Connection` pointer anymore). In particular, calling `otPlatDsoDisconnect()` 177 * MUST NOT trigger the callback `otPlatDsoHandleDisconnected()`. 178 * 179 * @param[in] aConnection The connection to disconnect 180 * @param[in] aMode The disconnect mode (close gracefully or forcibly abort). 181 * 182 */ 183 void otPlatDsoDisconnect(otPlatDsoConnection *aConnection, otPlatDsoDisconnectMode aMode); 184 185 /** 186 * Is a callback from the platform layer to indicate that peer closed/aborted the connection or the 187 * connection establishment failed (e.g., peer rejected a connection request). 188 * 189 * After calling this function, the DSO platform implementation MUST NOT maintain `aConnection` pointer (platform 190 * MUST NOT call any callbacks using this `Connection` pointer anymore). 191 * 192 * @param[in] aConnection The connection which disconnected. 193 * @param[in] aMode The disconnect mode (closed gracefully or forcibly aborted). 194 * 195 */ 196 extern void otPlatDsoHandleDisconnected(otPlatDsoConnection *aConnection, otPlatDsoDisconnectMode aMode); 197 198 #ifdef __cplusplus 199 } // extern "C" 200 #endif 201 202 #endif // OPENTHREAD_PLATFORM_DSO_TRANSPORT_H_ 203