// SPDX-FileCopyrightText: Matteo Settenvini // SPDX-License-Identifier: GPL-3.0-or-later #include "get_host.hh" #include "helpers.hh" #include "logger.hh" #include "resolver.hh" #include "wrapper.hh" #include #include #include #include #include #include #include #define DSO_EXPORT extern "C" __attribute__((visibility("default"))) // -------------- by host --------------- DSO_EXPORT auto _nss_malcontent_gethostbyname4_r( const char *name, gaih_addrtuple **pat, char *buffer_c, size_t buflen, int *errnop, HErrno *h_errnop, int32_t *ttlp ) -> nss_status { try { void *buffer = buffer_c; hostent he; auto local_buffer = std::make_unique(buflen); auto args = malcontent::ResolverArgs { name, 0, &he, local_buffer.get(), buflen, errnop, h_errnop, ttlp }; args.family = AF_INET; auto ret_a = malcontent::get_host::by_name(args); if (ret_a != NSS_STATUS_SUCCESS || pat == nullptr) { return ret_a; } *pat = malcontent::copy_hostent_to_gaih_addrtuple(he, nullptr, buffer, buflen); args.family = AF_INET6; auto ret_a6 = malcontent::get_host::by_name(args); if (ret_a6 != NSS_STATUS_SUCCESS) { return ret_a6; } *pat = malcontent::copy_hostent_to_gaih_addrtuple(he, *pat, buffer, buflen); set_if_valid(ttlp, 0); // We don't know which one to keep, so 0. return NSS_STATUS_SUCCESS; } catch(const std::bad_alloc&) { set_if_valid(errnop, ERANGE); set_if_valid(h_errnop, HErrno::Internal); return nss_status::NSS_STATUS_TRYAGAIN; } catch(const std::exception& e) { malcontent::Logger::error(std::string(__func__) + e.what()); set_if_valid(h_errnop, HErrno::Internal); return nss_status::NSS_STATUS_TRYAGAIN; } } DSO_EXPORT auto _nss_malcontent_gethostbyname3_r( const char *name, int af, hostent *host, char *buffer, size_t buflen, int *errnop, HErrno *h_errnop, int32_t *ttlp, char **canonp ) -> nss_status { try { auto args = malcontent::ResolverArgs { name, af, host, buffer, buflen, errnop, h_errnop, ttlp }; auto status = malcontent::get_host::by_name(args); if (host != nullptr) { set_if_valid(canonp, host->h_name); } return status; } catch(const std::exception& e) { malcontent::Logger::error(std::string(__func__) + e.what()); set_if_valid(h_errnop, HErrno::Internal); return nss_status::NSS_STATUS_TRYAGAIN; } } DSO_EXPORT auto _nss_malcontent_gethostbyname2_r( const char *name, int af, hostent *host, char *buffer, size_t buflen, int *errnop, HErrno *h_errnop ) -> nss_status { return _nss_malcontent_gethostbyname3_r( name, af, host, buffer, buflen, errnop, h_errnop, nullptr, nullptr ); } DSO_EXPORT auto _nss_malcontent_gethostbyname_r( const char *name, hostent *host, char *buffer, size_t buflen, int *errnop, HErrno *h_errnop ) -> nss_status { return _nss_malcontent_gethostbyname3_r( name, AF_INET, host, buffer, buflen, errnop, h_errnop, nullptr, nullptr ); } // ----------------- by addr ----------------- DSO_EXPORT auto _nss_malcontent_gethostbyaddr2_r( const void *addr, socklen_t len, int af, hostent *host, char *buffer, size_t buflen, int *errnop, HErrno *h_errnop, int32_t *ttlp ) -> nss_status { try { return malcontent::get_host::by_addr( addr, len, af, host, buffer, buflen, errnop, h_errnop, ttlp ); } catch(const std::exception& e) { malcontent::Logger::error(std::string(__func__) + e.what()); set_if_valid(h_errnop, HErrno::Internal); return nss_status::NSS_STATUS_TRYAGAIN; } } DSO_EXPORT auto _nss_malcontent_gethostbyaddr_r( const void *addr, socklen_t len, int af, hostent *host, char *buffer, size_t buflen, int *errnop, HErrno *h_errnop ) -> nss_status { return _nss_malcontent_gethostbyaddr2_r( addr, len, af, host, buffer, buflen, errnop, h_errnop, nullptr ); }