]> xenbits.xensource.com Git - unikraft/libs/musl.git/commitdiff
getnameinfo: Copy lwip adapter code from `lib/newlib`
authorSimon Kuenzer <simon@unikraft.io>
Tue, 6 Feb 2024 10:11:18 +0000 (11:11 +0100)
committerRazvan Deaconescu <razvan.deaconescu@upb.ro>
Fri, 9 Feb 2024 20:32:59 +0000 (22:32 +0200)
This commit copies the lwip glue code for `getnameinfo()` from `lib/newlib`
(https://github.com/unikraft/lib-newlib/commit/727d5eabd48f329df179be4a37dd40dd5d71151b,
 Commit 727d5ea) to musl. It is only enabled if musl is configured to
forward DNS related requests to lwIP.

Signed-off-by: Simon Kuenzer <simon@unikraft.io>
Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com>
Reviewed-by: Mihnea Firoiu <mihneafiroiu0@gmail.com>
Reviewed-by: Razvan Deaconescu <razvand@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #74

Makefile.uk.musl.network
lwip/getnameinfo.c [new file with mode: 0644]

index 6d9e0dfc78f97545a4b226f4ea5c82d768e04d03..8914fbf17614bc3a58b659d758569702298412bf 100644 (file)
@@ -67,8 +67,10 @@ LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/gai_strerror.c
 ifeq ($(filter y,$(CONFIG_LIBMUSL_NETWORK_LWIP_DNS)),)
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/getaddrinfo.c
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/freeaddrinfo.c
+LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/getnameinfo.c
 else
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL_BASE)/lwip/getaddrinfo.c
+LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL_BASE)/lwip/getnameinfo.c
 endif
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/gethostbyaddr.c
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/gethostbyaddr_r.c
@@ -77,7 +79,6 @@ LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/gethostbyname2.c
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/gethostbyname2_r.c
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/gethostbyname_r.c
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/getifaddrs.c
-LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/getnameinfo.c
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/getservbyname.c
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/getservbyname_r.c
 LIBMUSL_NETWORK_SRCS-y += $(LIBMUSL)/src/network/getservbyport.c
diff --git a/lwip/getnameinfo.c b/lwip/getnameinfo.c
new file mode 100644 (file)
index 0000000..ffa4b4f
--- /dev/null
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: BSD-3-Clause AND MIT */
+/*
+ * Copyright (C) 2014, Cloudius Systems, Ltd.
+ * Copyright (c) 2019, University Politehnica of Bucharest.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* For the parts taken from musl (marked as such below), the MIT licence
+ * applies instead:
+ * ----------------------------------------------------------------------
+ * Copyright (c) 2005-2014 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * ----------------------------------------------------------------------
+ */
+#include <lwip/opt.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
+       char *restrict node, socklen_t nodelen,
+       char *restrict serv, socklen_t servlen,
+       int flags)
+{
+       char buf[256];
+       /*unsigned char reply[512]; TODO used in DNS reply */
+       int af = sa->sa_family;
+       char line[512];
+       FILE *f;
+       unsigned char *a;
+
+       switch (af) {
+       case AF_INET:
+               a = (void *) &((struct sockaddr_in *) sa)->sin_addr;
+               if (sl != sizeof(struct sockaddr_in))
+                       return EAI_FAMILY;
+               break;
+#if CONFIG_LWIP_IPV6
+       case AF_INET6:
+               a = (void *) &((struct sockaddr_in6 *) sa)->sin6_addr;
+               if (sl != sizeof(struct sockaddr_in6))
+                       return EAI_FAMILY;
+               break;
+#endif
+       default:
+               return EAI_FAMILY;
+       }
+
+       /* Try to find ip within /etc/hosts */
+       if ((node && nodelen) && (af == AF_INET)) {
+               const char *ipstr;
+               size_t l;
+
+               ipstr = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
+               l = strlen(ipstr);
+               f = fopen("/etc/hosts", "r");
+               if (f)
+                       while (fgets(line, sizeof(line), f)) {
+                               char *domain;
+
+                               if (strncmp(line, ipstr, l) != 0)
+                                       continue;
+
+                               domain = strtok(line, " ");
+                               if (!domain)
+                                       continue;
+                               domain = strtok(NULL, " ");
+                               if (!domain)
+                                       continue;
+
+                               if (strlen(domain) >= nodelen)
+                                       return EAI_OVERFLOW;
+                               strcpy(node, domain);
+                               fclose(f);
+                               return 0;
+                       }
+               if (f)
+                       fclose(f);
+       }
+
+       if (node && nodelen) {
+               if ((flags & NI_NUMERICHOST)
+#if 0
+                       /* TODO we currently don't support name requests */
+                       || __dns_query(reply, a, af, 1) <= 0
+                       || __dns_get_rr(buf, 0, 256, 1, reply, RR_PTR, 1) <= 0) {
+#else
+                       || 1) {
+#endif
+                       if (flags & NI_NAMEREQD)
+                               return EAI_NONAME;
+                       inet_ntop(af, a, buf, sizeof(buf));
+               }
+               if (strlen(buf) >= nodelen)
+                       return EAI_OVERFLOW;
+               strcpy(node, buf);
+       }
+
+       if (serv && servlen) {
+               if (snprintf(buf, sizeof(buf), "%d",
+                       ntohs(((struct sockaddr_in *) sa)->sin_port)) >= (int) servlen)
+                       return EAI_OVERFLOW;
+               strcpy(serv, buf);
+       }
+
+       return 0;
+}