From db9a22637501555f5437a032c61b841b4edec140 Mon Sep 17 00:00:00 2001 From: Lubos Dolezel Date: Fri, 4 Dec 2015 00:12:09 +0100 Subject: [PATCH] Initial code for darling-resolver (gethostbyname() now works, rest remains to be done) --- src/libinfo/CMakeLists.txt | 2 + src/libinfo/darling-resolver/CMakeLists.txt | 21 ++ src/libinfo/darling-resolver/LICENSE | 165 +++++++++++++++ src/libinfo/darling-resolver/resolver.c | 221 ++++++++++++++++++++ src/libinfo/dns.subproj/res_query.c | 3 + src/libinfo/lookup.subproj/search_module.c | 3 +- src/libinfo/lookup.subproj/si_module.c | 4 +- src/libinfo/lookup.subproj/si_module.h | 1 + 8 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 src/libinfo/darling-resolver/CMakeLists.txt create mode 100644 src/libinfo/darling-resolver/LICENSE create mode 100644 src/libinfo/darling-resolver/resolver.c diff --git a/src/libinfo/CMakeLists.txt b/src/libinfo/CMakeLists.txt index 2e1f351ae..8a77714fe 100644 --- a/src/libinfo/CMakeLists.txt +++ b/src/libinfo/CMakeLists.txt @@ -27,6 +27,7 @@ add_subdirectory(nis.subproj) add_subdirectory(rpc.subproj) add_subdirectory(lookup.subproj) add_subdirectory(membership.subproj) +add_subdirectory(darling-resolver) SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib${SUFFIX}/darling") SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) @@ -39,6 +40,7 @@ add_library(system_info SHARED $ $ $ $ + $ ) target_link_libraries(system_info system_c resolv-darwin) diff --git a/src/libinfo/darling-resolver/CMakeLists.txt b/src/libinfo/darling-resolver/CMakeLists.txt new file mode 100644 index 000000000..4dcb3951a --- /dev/null +++ b/src/libinfo/darling-resolver/CMakeLists.txt @@ -0,0 +1,21 @@ +project(darling-resolver) + +cmake_minimum_required(VERSION 2.4.0) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../libc/locale) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../libc/locale/FreeBSD) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../libc/pthreads) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../libc/stdtime/FreeBSD) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../external/libdispatch/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../external/libdispatch/private) +include_directories(${DARLING_TOP_DIRECTORY}/src/libresolv) +include_directories(${DARLING_TOP_DIRECTORY}/src/libresolv/dnsinfo) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../lookup.subproj) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fblocks") + +set(dr_sources + resolver.c +) + +add_library(darling-resolver OBJECT ${dr_sources}) diff --git a/src/libinfo/darling-resolver/LICENSE b/src/libinfo/darling-resolver/LICENSE new file mode 100644 index 000000000..65c5ca88a --- /dev/null +++ b/src/libinfo/darling-resolver/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/src/libinfo/darling-resolver/resolver.c b/src/libinfo/darling-resolver/resolver.c new file mode 100644 index 000000000..0b4d000d8 --- /dev/null +++ b/src/libinfo/darling-resolver/resolver.c @@ -0,0 +1,221 @@ +/* + * Darling - DNS resolver module + * Copyright (c) 2015 Lubos Dolezel, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ + +#include "../lookup.subproj/si_module.h" +#include +#include +#include + +static int +dr_is_valid(si_mod_t *si, si_item_t *item) +{ + return 0; +} + +static void +dr_close(si_mod_t *si) +{ +} + +static si_item_t * +dr_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err) +{ + int type, l, i, elem_length; + unsigned char buf[4096]; + ns_msg msg; + ns_rr rr; + char* addr_buf; + void** addr_ptrs; + uint64_t ttl_end; + + if (af == AF_INET) + { + elem_length = 4; + type = ns_t_a; + } + else if (af == AF_INET6) + { + elem_length = 16; + type = ns_t_aaaa; + } + else + return NULL; + + l = res_query(name, ns_c_any, type, buf, sizeof(buf)); + if (l < 0) + return NULL; + + ns_initparse(buf, l, &msg); + l = ns_msg_count(msg, ns_s_an); + + addr_buf = (char*) __builtin_alloca(l * elem_length); + addr_ptrs = (void**) __builtin_alloca((l+1) * sizeof(void*)); + addr_ptrs[l] = NULL; + + for (i = 0; i < l; i++) + { + const unsigned char* data; + int type; + + ns_parserr(&msg, ns_s_an, i, &rr); + data = ns_rr_rdata(rr); + type = ns_rr_type(rr); + + if ((af == AF_INET && type == ns_t_a) + || (af == AF_INET6 && type == ns_t_aaaa)) + { + memcpy(addr_buf + (i*elem_length), data, elem_length); + addr_ptrs[i] = addr_buf + (i*elem_length); + } + } + + ttl_end = time(NULL) + rr.ttl; + if (af == AF_INET) + { + return (si_item_t *)LI_ils_create("L4488s*44a", (unsigned long)si, CATEGORY_HOST_IPV4, 1, ttl_end, + 0LL, name, NULL, af, elem_length, addr_ptrs); + } + else if (af == AF_INET6) + { + return (si_item_t *)LI_ils_create("L4488s*44c", (unsigned long)si, CATEGORY_HOST_IPV6, 1, ttl_end, + 0LL, name, NULL, af, elem_length, addr_ptrs); + } + return NULL; +} + +static si_item_t * +dr_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err) +{ + char ptr[100]; + unsigned char buf[4096]; + int l, i; + ns_msg msg; + ns_rr rr; + char** name_ptrs; + + if (af == AF_INET) + { + const unsigned char* ip = (const unsigned char*) addr; + sprintf(ptr, "%d.%d.%d.%d.in-addr.arpa", ip[3], ip[2], ip[1], ip[0]); + } + else if (af == AF_INET6) + { + if (memcmp(addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12) == 0) + { + // This is a mapped IPv4 address + const unsigned char* ip = ((const unsigned char*) addr) + 12; + sprintf(ptr, "%d.%d.%d.%d.in-addr.arpa", ip[3], ip[2], ip[1], ip[0]); + } + else + { + const unsigned char* ip = (const unsigned char*) addr; + const char* dig = "0123456789abcdef"; + int i; + + for (i = 0; i < 16; i++) + { + ptr[i*4] = dig[ip[i] & 0xf]; + ptr[i*4+1] = '.'; + ptr[i*4+2] = dig[ip[i] >> 4]; + ptr[i*4+3] = '.'; + } + strcpy(&ptr[64], "ip6.arpa"); + } + } + else + return NULL; + + l = res_query(ptr, ns_c_any, ns_t_ptr, buf, sizeof(buf)); + if (l < 0) + return NULL; + + ns_initparse(buf, l, &msg); + l = ns_msg_count(msg, ns_s_an); + + name_ptrs = (char**) __builtin_alloca((l+1) * sizeof(char*)); + name_ptrs[l] = NULL; + + for (i = 0; i < l; i++) + { + const unsigned char* data; + int type; + + ns_parserr(&msg, ns_s_an, i, &rr); + data = ns_rr_rdata(rr); + type = ns_rr_type(rr); + + if (type == ns_t_ptr) + { + // TODO + } + } + + return NULL; +} + +static si_list_t * +dr_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err) +{ + return NULL; +} + +static si_item_t * +dr_item_call(si_mod_t *si, int call, const char *name, const char *ignored, const char *interface, uint32_t class, uint32_t type, uint32_t *err) +{ + return NULL; +} + +static si_list_t * +dr_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_t *err) +{ + return NULL; +} + +si_mod_t *si_module_static_darling(void) +{ + static const struct si_mod_vtable_s dr_vtable = + { + .sim_close = &dr_close, + .sim_is_valid = &dr_is_valid, + .sim_host_byname = &dr_hostbyname, + .sim_host_byaddr = &dr_hostbyaddr, + .sim_item_call = &dr_item_call, + .sim_addrinfo = &dr_addrinfo, + .sim_srv_byname = &dr_srv_byname, + }; + + static si_mod_t si = + { + .vers = 1, + .refcount = 1, + .flags = SI_MOD_FLAG_STATIC, + + .private = NULL, + .vtable = &dr_vtable, + }; + + static dispatch_once_t once; + + dispatch_once(&once, ^{ + si.name = strdup("darling-resolver"); + }); + + return (si_mod_t*)&si; + +} + diff --git a/src/libinfo/dns.subproj/res_query.c b/src/libinfo/dns.subproj/res_query.c index 3b048ef5c..c075efe55 100644 --- a/src/libinfo/dns.subproj/res_query.c +++ b/src/libinfo/dns.subproj/res_query.c @@ -1,3 +1,4 @@ +// Modified by Lubos Dolezel for Darling /* * Copyright (c) 1999, 2012 Apple Inc. All rights reserved. * @@ -44,6 +45,7 @@ extern int h_errno; #endif char _res[RES_9_STATE_SIZE] = {0}; +#ifndef DARLING int res_init(void) { @@ -128,3 +130,4 @@ res_search(const char *name, int class, int type, u_char *answer, int anslen) { return _mdns_query(SI_CALL_DNS_SEARCH, name, class, type, answer, anslen); } +#endif diff --git a/src/libinfo/lookup.subproj/search_module.c b/src/libinfo/lookup.subproj/search_module.c index 7d4f0ece3..a22ec441c 100644 --- a/src/libinfo/lookup.subproj/search_module.c +++ b/src/libinfo/lookup.subproj/search_module.c @@ -955,7 +955,8 @@ si_module_static_search(void) #ifdef DS_AVAILABLE "ds", #endif - "mdns", + // "mdns", + "darling-resolver", "file", }; diff --git a/src/libinfo/lookup.subproj/si_module.c b/src/libinfo/lookup.subproj/si_module.c index 86c00164f..0eebcab5a 100644 --- a/src/libinfo/lookup.subproj/si_module.c +++ b/src/libinfo/lookup.subproj/si_module.c @@ -83,6 +83,7 @@ si_mod_t *si_module_static_file(void); si_mod_t *si_module_static_ds(void); #endif si_mod_t *si_module_static_mdns(void); +si_mod_t *si_module_static_darling(void); static void * si_mod_dlsym(void *so, const char *name, const char *sym) @@ -182,7 +183,8 @@ si_module_with_name(const char *name) #ifdef DS_AVAILABLE { "ds", si_module_static_ds, NULL }, #endif - { "mdns", si_module_static_mdns, NULL }, + // { "mdns", si_module_static_mdns, NULL }, + { "darling-resolver", si_module_static_darling, NULL }, { NULL, NULL }, }; diff --git a/src/libinfo/lookup.subproj/si_module.h b/src/libinfo/lookup.subproj/si_module.h index a87c6292b..0add3d43a 100644 --- a/src/libinfo/lookup.subproj/si_module.h +++ b/src/libinfo/lookup.subproj/si_module.h @@ -1,3 +1,4 @@ +// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2008-2011 Apple Inc. All rights reserved. * -- 2.51.2