xref: /FreeRTOS-Plus-TCP-v3.1.0/source/FreeRTOS_DNS_Networking.c (revision 37bdfe577f3b728058de714e2e747d3c78803f26)
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