1 /* 2 * FreeRTOS+TCP V3.1.0 3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 * 5 * SPDX-License-Identifier: MIT 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 * this software and associated documentation files (the "Software"), to deal in 9 * the Software without restriction, including without limitation the rights to 10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 * the Software, and to permit persons to whom the Software is furnished to do so, 12 * subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * http://aws.amazon.com/freertos 25 * http://www.FreeRTOS.org 26 */ 27 28 /** 29 * @file FreeRTOS_DNS_Networking.c 30 * @brief Implements the Domain Name System Networking 31 * for the FreeRTOS+TCP network stack. 32 */ 33 34 #include "FreeRTOS.h" 35 36 #include "FreeRTOS_DNS_Networking.h" 37 38 #if ( ipconfigUSE_DNS != 0 ) 39 40 /** 41 * @brief Create a socket and bind it to the standard DNS port number. 42 * 43 * @return The created socket - or NULL if the socket could not be created or could not be bound. 44 */ DNS_CreateSocket(TickType_t uxReadTimeOut_ticks)45 Socket_t DNS_CreateSocket( TickType_t uxReadTimeOut_ticks ) 46 { 47 Socket_t xSocket; 48 struct freertos_sockaddr xAddress; 49 TickType_t uxWriteTimeOut_ticks = ipconfigDNS_SEND_BLOCK_TIME_TICKS; 50 BaseType_t xReturn; 51 52 /* This must be the first time this function has been called. Create 53 * the socket. */ 54 xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); 55 56 if( xSocketValid( xSocket ) == pdFALSE ) 57 { 58 /* There was an error, return NULL. */ 59 xSocket = NULL; 60 } 61 else 62 { 63 /* Auto bind the port. */ 64 xAddress.sin_port = 0U; 65 xReturn = FreeRTOS_bind( xSocket, &xAddress, ( socklen_t ) sizeof( xAddress ) ); 66 67 /* Check the bind was successful, and clean up if not. */ 68 if( xReturn != 0 ) 69 { 70 ( void ) FreeRTOS_closesocket( xSocket ); 71 xSocket = NULL; 72 } 73 else 74 { 75 /* Ideally we should check for the return value. But since we are passing 76 * correct parameters, and xSocket is != NULL, the return value is 77 * going to be '0' i.e. success. Thus, return value is discarded */ 78 ( void ) FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &( uxWriteTimeOut_ticks ), sizeof( TickType_t ) ); 79 ( void ) FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &( uxReadTimeOut_ticks ), sizeof( TickType_t ) ); 80 } 81 } 82 83 return xSocket; 84 } 85 86 /** 87 * @brief perform a DNS network request 88 * @param xDNSSocket Created socket 89 * @param xAddress address structure (ip, port etc) 90 * @param pxDNSBuf buffer to send 91 * @return xReturn: true if the message could be sent 92 * false otherwise 93 * 94 */ DNS_SendRequest(Socket_t xDNSSocket,const struct freertos_sockaddr * xAddress,const struct xDNSBuffer * pxDNSBuf)95 BaseType_t DNS_SendRequest( Socket_t xDNSSocket, 96 const struct freertos_sockaddr * xAddress, 97 const struct xDNSBuffer * pxDNSBuf ) 98 { 99 BaseType_t xReturn = pdFALSE; 100 101 iptraceSENDING_DNS_REQUEST(); 102 103 /* Send the DNS message. */ 104 if( FreeRTOS_sendto( xDNSSocket, 105 pxDNSBuf->pucPayloadBuffer, 106 pxDNSBuf->uxPayloadLength, 107 FREERTOS_ZERO_COPY, 108 xAddress, 109 ( socklen_t ) sizeof( *xAddress ) ) != 0 ) 110 { 111 xReturn = pdTRUE; 112 } 113 else 114 { 115 /* The message was not sent so the stack will not be 116 * releasing the zero copy - it must be released here. */ 117 xReturn = pdFALSE; 118 } 119 120 return xReturn; 121 } 122 123 /** 124 * @brief perform a DNS network read 125 * @param xDNSSocket socket 126 * @param xAddress address to read from 127 * @param pxReceiveBuffer buffer to fill with received data 128 */ DNS_ReadReply(const ConstSocket_t xDNSSocket,struct freertos_sockaddr * xAddress,struct xDNSBuffer * pxReceiveBuffer)129 void DNS_ReadReply( const ConstSocket_t xDNSSocket, 130 struct freertos_sockaddr * xAddress, 131 struct xDNSBuffer * pxReceiveBuffer ) 132 { 133 uint32_t ulAddressLength = ( uint32_t ) sizeof( struct freertos_sockaddr ); 134 135 /* Wait for the reply. */ 136 pxReceiveBuffer->uxPayloadLength = ( size_t ) FreeRTOS_recvfrom( xDNSSocket, 137 &pxReceiveBuffer->pucPayloadBuffer, 138 0, 139 FREERTOS_ZERO_COPY, 140 xAddress, 141 &ulAddressLength ); 142 pxReceiveBuffer->uxPayloadSize = pxReceiveBuffer->uxPayloadLength; 143 } 144 145 /** 146 * @brief perform a DNS network close 147 * @param xDNSSocket 148 */ DNS_CloseSocket(Socket_t xDNSSocket)149 void DNS_CloseSocket( Socket_t xDNSSocket ) 150 { 151 ( void ) FreeRTOS_closesocket( xDNSSocket ); 152 } 153 #endif /* if ( ipconfigUSE_DNS != 0 ) */ 154