malcontent/nss/nss_adapters.cc

215 lines
4.7 KiB
C++
Raw Normal View History

2024-01-05 18:10:45 +01:00
// SPDX-FileCopyrightText: Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// 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 <cerrno>
#include <new>
#include <nss.h>
#include <sys/socket.h>
#include <exception>
#include <memory>
#include <string>
#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<char[]>(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
);
}