Skip to content
API Documentation
BastionGuard™
dns_util.hpp
Go to the documentation of this file.
1/*
2 * BastionGuard™
3 * Copyright (C) 2025–2026 Calogero Scarnà
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 *
17 * BastionGuard™ is a trademark of Calogero Scarnà.
18 * The BastionGuard™ name and branding are not licensed under the GPL.
19 */
20
21#pragma once
22#include "dns_cache.hpp"
23#include <string>
24#include <vector>
25#include <netdb.h>
26#include <sys/socket.h>
27#include <arpa/inet.h>
28#include <chrono>
29#include <iostream>
30#include <cstring>
31
32
33inline bool resolve_with_cache(const std::string &host, std::vector<std::string> &addrs, int ttl_seconds = 0) {
34 if (DNSCache::instance().lookup(host, addrs)) {
35 return true;
36 }
37
38 struct addrinfo hints, *res = nullptr;
39 memset(&hints, 0, sizeof(hints));
40 hints.ai_family = AF_UNSPEC;
41 hints.ai_socktype = SOCK_STREAM;
42
43 auto t0 = std::chrono::steady_clock::now();
44 int err = getaddrinfo(host.c_str(), nullptr, &hints, &res);
45 auto t1 = std::chrono::steady_clock::now();
46 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count();
47
48 bool ok = false;
49 if (err == 0 && res) {
50 for (struct addrinfo *p = res; p != nullptr; p = p->ai_next) {
51 char addrbuf[INET6_ADDRSTRLEN] = {0};
52 if (p->ai_family == AF_INET) {
53 struct sockaddr_in *sa = (struct sockaddr_in *)p->ai_addr;
54 if (inet_ntop(AF_INET, &(sa->sin_addr), addrbuf, sizeof(addrbuf)))
55 addrs.emplace_back(addrbuf);
56 } else if (p->ai_family == AF_INET6) {
57 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)p->ai_addr;
58 if (inet_ntop(AF_INET6, &(sa6->sin6_addr), addrbuf, sizeof(addrbuf)))
59 addrs.emplace_back(addrbuf);
60 }
61 }
62 ok = !addrs.empty();
63 }
64 if (res) freeaddrinfo(res);
65 if (ok) DNSCache::instance().store(host, addrs, ttl_seconds);
66 return ok;
67}
#define AF_INET
Definition bsc_ebpf.c:56
#define AF_INET6
Definition bsc_ebpf.c:57
static DNSCache & instance()
Definition dns_cache.cpp:26
void store(const std::string &host, const std::vector< std::string > &addrs, int ttl_seconds=-1)
Definition dns_cache.cpp:53
bool resolve_with_cache(const std::string &host, std::vector< std::string > &addrs, int ttl_seconds=0)
Definition dns_util.hpp:33