xref: /FreeRTOS-Plus-TCP-v4.0.0/source/FreeRTOS_DNS_Networking.c (revision 2d3f4daa567ffe71aeda2e0f6d0bc02850db0627)
1 /*
2  * FreeRTOS+TCP <DEVELOPMENT BRANCH>
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 Bind the socket to a port number.
42  * @param[in] xSocket the socket that must be bound.
43  * @param[in] usPort the port number to bind to.
44  * @return The created socket - or NULL if the socket could not be created or could not be bound.
45  */
DNS_BindSocket(Socket_t xSocket,uint16_t usPort)46     BaseType_t DNS_BindSocket( Socket_t xSocket,
47                                uint16_t usPort )
48     {
49         struct freertos_sockaddr xAddress;
50         BaseType_t xReturn;
51 
52         ( void ) memset( &( xAddress ), 0, sizeof( xAddress ) );
53         xAddress.sin_family = FREERTOS_AF_INET;
54         xAddress.sin_port = usPort;
55 
56         xReturn = FreeRTOS_bind( xSocket, &xAddress, ( socklen_t ) sizeof( xAddress ) );
57 
58         return xReturn;
59     }
60 
61 /**
62  * @brief Create a socket and bind it to the standard DNS port number.
63  *
64  * @return The created socket - or NULL if the socket could not be created or could not be bound.
65  */
DNS_CreateSocket(TickType_t uxReadTimeOut_ticks)66     Socket_t DNS_CreateSocket( TickType_t uxReadTimeOut_ticks )
67     {
68         Socket_t xSocket;
69         TickType_t uxWriteTimeOut_ticks = ipconfigDNS_SEND_BLOCK_TIME_TICKS;
70 
71         /* This must be the first time this function has been called.  Create
72          * the socket. */
73         xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
74 
75         if( xSocketValid( xSocket ) == pdFALSE )
76         {
77             /* There was an error, return NULL. */
78             xSocket = NULL;
79         }
80         else
81         {
82             /* Ideally we should check for the return value. But since we are passing
83              * correct parameters, and xSocket is != NULL, the return value is
84              * going to be '0' i.e. success. Thus, return value is discarded */
85             ( void ) FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &( uxWriteTimeOut_ticks ), sizeof( TickType_t ) );
86             ( void ) FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &( uxReadTimeOut_ticks ), sizeof( TickType_t ) );
87         }
88 
89         return xSocket;
90     }
91 
92 /**
93  * @brief perform a DNS network request
94  * @param xDNSSocket Created socket
95  * @param xAddress address structure (ip, port etc)
96  * @param pxDNSBuf buffer to send
97  * @return xReturn: true if the message could be sent
98  *                  false otherwise
99  *
100  */
DNS_SendRequest(Socket_t xDNSSocket,const struct freertos_sockaddr * xAddress,const struct xDNSBuffer * pxDNSBuf)101     BaseType_t DNS_SendRequest( Socket_t xDNSSocket,
102                                 const struct freertos_sockaddr * xAddress,
103                                 const struct xDNSBuffer * pxDNSBuf )
104     {
105         BaseType_t xReturn = pdFALSE;
106         BaseType_t xSent;
107 
108         iptraceSENDING_DNS_REQUEST();
109 
110         /* Send the DNS message. */
111         xSent = FreeRTOS_sendto( xDNSSocket,
112                                  pxDNSBuf->pucPayloadBuffer,
113                                  pxDNSBuf->uxPayloadLength,
114                                  FREERTOS_ZERO_COPY,
115                                  xAddress,
116                                  ( socklen_t ) sizeof( *xAddress ) );
117 
118         if( xSent == ( BaseType_t ) pxDNSBuf->uxPayloadLength )
119         {
120             xReturn = pdPASS;
121         }
122         else
123         {
124             /* The message was not sent so the stack will not be
125              * releasing the zero copy - it must be released here. */
126             xReturn = pdFAIL;
127         }
128 
129         return xReturn;
130     }
131 /*-----------------------------------------------------------*/
132 
133 /**
134  * @brief perform a DNS network read
135  * @param xDNSSocket socket
136  * @param xAddress address to read from
137  * @param pxReceiveBuffer buffer to fill with received data
138  */
DNS_ReadReply(ConstSocket_t xDNSSocket,struct freertos_sockaddr * xAddress,struct xDNSBuffer * pxReceiveBuffer)139     BaseType_t DNS_ReadReply( ConstSocket_t xDNSSocket,
140                               struct freertos_sockaddr * xAddress,
141                               struct xDNSBuffer * pxReceiveBuffer )
142     {
143         BaseType_t xReturn;
144         uint32_t ulAddressLength = ( uint32_t ) sizeof( struct freertos_sockaddr );
145 
146         /* Wait for the reply. */
147         xReturn = FreeRTOS_recvfrom( xDNSSocket,
148                                      &pxReceiveBuffer->pucPayloadBuffer,
149                                      0,
150                                      FREERTOS_ZERO_COPY,
151                                      xAddress,
152                                      &ulAddressLength );
153 
154         if( xReturn <= 0 )
155         {
156             /* 'pdFREERTOS_ERRNO_EWOULDBLOCK' is returned in case of a timeout. */
157             FreeRTOS_printf( ( "DNS_ReadReply returns %d\n", ( int ) xReturn ) );
158         }
159 
160         return xReturn;
161     }
162 /*-----------------------------------------------------------*/
163 
164 /**
165  * @brief perform a DNS network close
166  * @param xDNSSocket the DNS socket to close
167  */
DNS_CloseSocket(Socket_t xDNSSocket)168     void DNS_CloseSocket( Socket_t xDNSSocket )
169     {
170         ( void ) FreeRTOS_closesocket( xDNSSocket );
171     }
172 #endif /* if ( ipconfigUSE_DNS != 0 ) */
173 /*-----------------------------------------------------------*/
174