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 * This file includes definitions for the SRP client buffers and service pool. 32 */ 33 34 #ifndef SRP_CLIENT_BUFFERS_HPP_ 35 #define SRP_CLIENT_BUFFERS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE 40 41 #include <openthread/srp_client_buffers.h> 42 43 #include "common/array.hpp" 44 #include "common/as_core_type.hpp" 45 #include "common/clearable.hpp" 46 #include "common/locator.hpp" 47 #include "common/non_copyable.hpp" 48 #include "common/pool.hpp" 49 #include "net/srp_client.hpp" 50 51 namespace ot { 52 namespace Utils { 53 54 #if !OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE 55 #error "OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE requires OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE feature." 56 #endif 57 58 /** 59 * This class represents the SRP client buffers and service pool. 60 * 61 */ 62 class SrpClientBuffers : public InstanceLocator, private NonCopyable 63 { 64 public: 65 /** 66 * Maximum number of service entries in the pool. 67 * 68 */ 69 static constexpr uint16_t kMaxServices = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_MAX_SERVICES; 70 71 /** 72 * Max number of host address entries. 73 * 74 */ 75 static constexpr uint16_t kMaxHostAddresses = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_MAX_HOST_ADDRESSES; 76 77 /** 78 * Size (number of char) of host name string (includes null `\0` termination char). 79 * 80 */ 81 static constexpr uint16_t kHostNameSize = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_HOST_NAME_SIZE; 82 83 /** 84 * Size (number of char) of service name string (includes null `\0` termination char). 85 * 86 */ 87 static constexpr uint16_t kServiceNameSize = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_SERVICE_NAME_SIZE; 88 89 /** 90 * Array length for service subtype label. 91 * 92 */ 93 static constexpr uint16_t kServiceMaxSubTypes = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_SERVICE_MAX_SUB_TYPES; 94 95 /** 96 * Size (number of char) of service instance name string (includes null `\0` termination char). 97 * 98 */ 99 static constexpr uint16_t kInstanceNameSize = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_SERVICE_INSTANCE_NAME_SIZE; 100 101 /** 102 * Size (number of bytes) of TXT record buffer. 103 * 104 */ 105 static constexpr uint16_t kTxtBufferSize = OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_TXT_BUFFER_SIZE; 106 107 /** 108 * This class represents a SRP client service entry from the pool. 109 * 110 */ 111 class ServiceEntry : public otSrpClientBuffersServiceEntry, public Clearable<ServiceEntry> 112 { 113 friend class SrpClientBuffers; 114 friend class LinkedList<ServiceEntry>; 115 116 public: 117 /** 118 * This method gets the string buffer for the service name from the service entry. 119 * 120 * @param[out] aSize Reference to a variable to return the size (number of bytes) of the string buffer. 121 * 122 * @returns A pointer to the string buffer. 123 * 124 */ GetServiceNameString(uint16_t & aSize)125 char *GetServiceNameString(uint16_t &aSize) 126 { 127 aSize = sizeof(mServiceName); 128 return mServiceName; 129 } 130 131 /** 132 * This method gets the string buffer for the instance name from the service entry. 133 * 134 * @param[out] aSize Reference to a variable to return the size (number of bytes) of the string buffer. 135 * 136 * @returns A pointer to the string buffer. 137 * 138 */ GetInstanceNameString(uint16_t & aSize)139 char *GetInstanceNameString(uint16_t &aSize) 140 { 141 aSize = sizeof(mInstanceName); 142 return mInstanceName; 143 } 144 145 /** 146 * This method gets the buffer for the TXT value from the service entry. 147 * 148 * @param[out] aSize Reference to a variable to return the size (number of bytes) of the buffer. 149 * 150 * @returns A pointer to the buffer. 151 * 152 */ GetTxtBuffer(uint16_t & aSize)153 uint8_t *GetTxtBuffer(uint16_t &aSize) 154 { 155 aSize = sizeof(mTxtBuffer); 156 return mTxtBuffer; 157 } 158 159 /** 160 * This method gets the array for service subtype labels from the service entry. 161 * 162 * @param[out] aArrayLength Reference to a variable to return the array length. 163 * 164 * @returns A pointer to the array. 165 * 166 */ GetSubTypeLabelsArray(uint16_t & aArrayLength)167 const char **GetSubTypeLabelsArray(uint16_t &aArrayLength) 168 { 169 aArrayLength = GetArrayLength(mSubTypeLabels); 170 return mSubTypeLabels; 171 } 172 173 private: GetNext(void)174 ServiceEntry * GetNext(void) { return reinterpret_cast<ServiceEntry *>(mService.mNext); } GetNext(void) const175 const ServiceEntry *GetNext(void) const { return reinterpret_cast<const ServiceEntry *>(mService.mNext); } SetNext(ServiceEntry * aEntry)176 void SetNext(ServiceEntry *aEntry) { mService.mNext = reinterpret_cast<Srp::Client::Service *>(aEntry); } 177 178 char mServiceName[kServiceNameSize]; 179 char mInstanceName[kInstanceNameSize]; 180 uint8_t mTxtBuffer[kTxtBufferSize]; 181 const char *mSubTypeLabels[kServiceMaxSubTypes + 1]; 182 }; 183 184 /** 185 * This constructor initializes the `SrpClientBuffers` object. 186 * 187 * @param[in] aInstance A reference to the OpenThread instance. 188 * 189 */ 190 explicit SrpClientBuffers(Instance &aInstance); 191 192 /** 193 * This method gets the string buffer to use for SRP client host name. 194 * 195 * @param[out] aSize Reference to a variable to return the size (number of bytes) of the string buffer. 196 * 197 * @returns A pointer to char buffer to use for SRP client host name. 198 * 199 */ GetHostNameString(uint16_t & aSize)200 char *GetHostNameString(uint16_t &aSize) 201 { 202 aSize = sizeof(mHostName); 203 return mHostName; 204 } 205 206 /** 207 * This method gets the array of IPv6 address entries to use as SRP client host address list. 208 * 209 * @param[out] aArrayLength Reference to a variable to return the array length (number of IPv6 address entries in 210 * * the array). 211 * 212 * @returns A pointer to an array of `Ip6::Address` entries (number of entries is returned in @p aArrayLength). 213 * 214 */ GetHostAddressesArray(uint8_t & aArrayLength)215 Ip6::Address *GetHostAddressesArray(uint8_t &aArrayLength) 216 { 217 aArrayLength = static_cast<uint8_t>(GetArrayLength(mHostAddresses)); 218 return &mHostAddresses[0]; 219 } 220 221 /** 222 * This method allocates a new service entry from the pool. 223 * 224 * The returned service entry instance will be initialized as follows: 225 * 226 * - `mService.mName` points to a string buffer which can be retrieved using `GetServiceNameString()`. 227 * - `mService.mInstanceName` points to a string buffer which can be retrieved using `GetInstanceNameString()`. 228 * - `mService.mSubTypeLabels` points to array which can be retrieved using `GetSubTypeLabelsArray()`. 229 * - `mService.mTxtEntries` points to `mTxtEntry`. 230 * - `mService.mNumTxtEntries` is set to one (one entry in the list). 231 * - Other `mService` fields (port, priority, weight) are set to zero. 232 * - `mTxtEntry.mKey` is set to `nullptr` (value is treated as already encoded data). 233 * - `mTxtEntry.mValue` points to a buffer which can be retrieved using `GetTxtBuffer()` 234 * - `mTxtEntry.mValueLength` is set to zero. 235 * - All related data/string buffers and arrays are cleared to all zero. 236 * 237 * @returns A pointer to the newly allocated service entry or `nullptr` if not more entry available in the pool. 238 * 239 */ 240 ServiceEntry *AllocateService(void); 241 242 /** 243 * This method frees a previously allocated service entry. 244 * 245 * The @p aService MUST be previously allocated using `AllocateService()` and not yet freed. Otherwise the behavior 246 * of this method is undefined. 247 * 248 * @param[in] aServiceEntry A service entry to free. 249 * 250 */ FreeService(ServiceEntry & aServiceEntry)251 void FreeService(ServiceEntry &aServiceEntry) { mServicePool.Free(aServiceEntry); } 252 253 /** 254 * This method frees all previously allocated service entries. 255 * 256 */ FreeAllServices(void)257 void FreeAllServices(void) { mServicePool.FreeAll(); } 258 259 private: 260 char mHostName[kHostNameSize]; 261 Ip6::Address mHostAddresses[kMaxHostAddresses]; 262 Pool<ServiceEntry, kMaxServices> mServicePool; 263 }; 264 265 } // namespace Utils 266 267 DefineCoreType(otSrpClientBuffersServiceEntry, Utils::SrpClientBuffers::ServiceEntry); 268 269 } // namespace ot 270 271 #endif // OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE 272 273 #endif // SRP_CLIENT_BUFFERS_HPP_ 274