215 lines
4.7 KiB
C++
215 lines
4.7 KiB
C++
|
// 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
|
||
|
);
|
||
|
}
|