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