66
77/* libc headers */
88#include <stdlib.h>
9+ #include <ctype.h>
910
1011/* Zephyr headers */
1112#include <logging/log.h>
@@ -19,6 +20,13 @@ LOG_MODULE_REGISTER(net_sock_addr, CONFIG_NET_SOCKETS_LOG_LEVEL);
1920
2021#if defined(CONFIG_DNS_RESOLVER )
2122
23+ /* Helper macros which take into account the fact that ai_family as passed
24+ * into getaddrinfo() may take values AF_INET, AF_INET6, or AF_UNSPEC, where
25+ * AF_UNSPEC means resolve both AF_INET and AF_INET6.
26+ */
27+ #define RESOLVE_IPV4 (ai_family ) (IS_ENABLED(CONFIG_NET_IPV4) && (ai_family) != AF_INET6)
28+ #define RESOLVE_IPV6 (ai_family ) (IS_ENABLED(CONFIG_NET_IPV6) && (ai_family) != AF_INET)
29+
2230struct getaddrinfo_state {
2331 const struct zsock_addrinfo * hints ;
2432 struct k_sem sem ;
@@ -128,6 +136,7 @@ int z_impl_z_zsock_getaddrinfo_internal(const char *host, const char *service,
128136 struct zsock_addrinfo * res )
129137{
130138 int family = AF_UNSPEC ;
139+ int ai_flags = 0 ;
131140 long int port = 0 ;
132141 int st1 = DNS_EAI_ADDRFAMILY , st2 = DNS_EAI_ADDRFAMILY ;
133142 struct sockaddr * ai_addr ;
@@ -136,6 +145,7 @@ int z_impl_z_zsock_getaddrinfo_internal(const char *host, const char *service,
136145
137146 if (hints ) {
138147 family = hints -> ai_family ;
148+ ai_flags = hints -> ai_flags ;
139149 }
140150
141151 if (service ) {
@@ -155,6 +165,35 @@ int z_impl_z_zsock_getaddrinfo_internal(const char *host, const char *service,
155165 return getaddrinfo_null_host (port , hints , res );
156166 }
157167
168+ #define SIN_ADDR (ptr ) (((struct sockaddr_in *)(ptr))->sin_addr)
169+
170+ /* Check for IPv4 numeric address. Start with a quick heuristic check,
171+ * of first char of the address, then do long validating inet_pton()
172+ * call if needed.
173+ */
174+ if (RESOLVE_IPV4 (family )
175+ && isdigit ((int )* host )
176+ && zsock_inet_pton (AF_INET , host ,
177+ & SIN_ADDR (& res -> _ai_addr )) == 1 ) {
178+ struct sockaddr_in * addr =
179+ (struct sockaddr_in * )& res -> _ai_addr ;
180+
181+ addr -> sin_port = htons (port );
182+ addr -> sin_family = AF_INET ;
183+ INIT_ADDRINFO (res , addr );
184+ res -> ai_family = AF_INET ;
185+ res -> ai_socktype = SOCK_STREAM ;
186+ res -> ai_protocol = IPPROTO_TCP ;
187+ return 0 ;
188+ }
189+
190+ if (ai_flags & AI_NUMERICHOST ) {
191+ /* Asked to resolve host as numeric, but it wasn't possible
192+ * to do that.
193+ */
194+ return DNS_EAI_FAIL ;
195+ }
196+
158197 ai_state .hints = hints ;
159198 ai_state .idx = 0U ;
160199 ai_state .port = htons (port );
0 commit comments