lokinet/daemon/dns.cpp

302 lines
8.1 KiB
C++
Raw Normal View History

#include <config.hpp>
#include <dns_dotlokilookup.hpp>
#include <dns_iptracker.hpp>
#include <dnsd.hpp>
#include <llarp.h>
#include <threading.hpp> // for multithreaded version (multiplatorm)
2018-07-13 13:13:38 +00:00
2018-09-29 10:28:24 +00:00
#include <signal.h> // Linux needs this for SIGINT
#include <unistd.h>
#ifdef _WIN32
#define uint UINT
#endif
2018-07-13 13:13:38 +00:00
#if(__FreeBSD__) || (__OpenBSD__) || (__NetBSD__)
#include <pthread_np.h>
#endif
// CHECK: is multiprocess still a thing?
#ifndef TESTNET
#define TESTNET 0
#endif
struct llarp_main *ctx = 0;
bool done = false;
2018-07-13 13:13:38 +00:00
void
handle_signal(int sig)
{
printf("got SIGINT\n");
done = true;
// if using router, signal it
if(ctx)
llarp_main_signal(ctx, sig);
2018-07-13 13:13:38 +00:00
}
struct dns_relay_config
{
std::string upstream_host;
uint16_t upstream_port;
void
dns_iter_config(const char *section, const char *key, const char *val)
{
if(!strcmp(section, "dns"))
{
if(!strcmp(key, "upstream-server"))
{
upstream_host = strdup(val);
llarp::LogDebug("Config file setting dns server to ", upstream_host);
}
if(!strcmp(key, "upstream-port"))
{
upstream_port = atoi(val);
llarp::LogDebug("Config file setting dns server port to ",
upstream_port);
}
}
}
};
2018-07-13 13:13:38 +00:00
int
main(int argc, char *argv[])
{
int code = 1;
char cwd[1024];
2018-11-08 12:42:55 +00:00
char *ptr = getcwd(cwd, sizeof(cwd));
llarp::LogInfo("Starting up server at ", ptr);
const char *conffname = handleBaseCmdLineArgs(argc, argv);
dns_relay_config dnsr_config;
dnsr_config.upstream_host = "8.8.8.8";
dnsr_config.upstream_port = 53;
llarp::Config config_reader;
if(config_reader.load(conffname))
{
llarp::LogError("failed to load config file ", conffname);
2018-08-13 08:47:24 +00:00
return 0;
}
using namespace std::placeholders;
config_reader.visit(
std::bind(&dns_relay_config::dns_iter_config, &dnsr_config, _1, _2, _3));
llarp::LogInfo("config [", conffname, "] loaded");
2018-07-13 13:13:38 +00:00
const uint16_t server_port = 53;
2018-07-13 13:13:38 +00:00
2018-08-08 12:50:03 +00:00
dns_iptracker_init();
// llarp::SetLogLevel(llarp::eLogDebug);
2018-11-22 00:39:09 +00:00
bool enableDLL = false;
2018-11-22 00:39:09 +00:00
bool useLlarp = true;
2018-07-21 13:24:47 +00:00
if(enableDLL)
{
// libev version w/router context
ctx = llarp_main_init(conffname, !TESTNET);
if(!ctx)
{
llarp::LogError("Cant set up context");
return 0;
}
llarp_main_setup(ctx);
signal(SIGINT, handle_signal);
// we can't programmatic force a client
// but we'll need to be one...
/*
struct dnsd_context dnsd;
2018-09-29 10:28:24 +00:00
llarp::Addr dnsd_sockaddr(127, 0, 0, 1, 53);
llarp::Addr dnsc_sockaddr(dnsr_config.upstream_host,
dnsr_config.upstream_port);
// server_port, (const char *)dnsr_config.upstream_host.c_str(),
// dnsr_config.upstream_port
if(!llarp_main_init_dnsd(ctx, &dnsd, dnsd_sockaddr, dnsc_sockaddr))
{
llarp::LogError("Couldnt init dns daemon");
}
// Configure intercept
2018-09-22 10:39:53 +00:00
dnsd.intercept = &llarp_dotlokilookup_handler;
dotLokiLookup dll;
*/
// should be a function...
// dll.tunEndpoint = main_router_getFirstTunEndpoint(ctx);
// dll.ip_tracker = &g_dns_iptracker;
/*
llarp_main_init_dotLokiLookup(ctx, &dll);
dnsd.user = &dll;
// check tun set up
llarp_tun_io *tun = main_router_getRange(ctx);
llarp::LogDebug("TunNetmask: ", tun->netmask);
llarp::LogDebug("TunIfAddr: ", tun->ifaddr);
// configure dns_ip_tracker to use this
// well our routes table should already be set up
// mark our TunIfAddr as used
if(tun)
{
dll.user = tun;
struct sockaddr_in addr;
addr.sin_addr.s_addr = inet_addr(tun->ifaddr);
addr.sin_family = AF_INET;
llarp::Addr tunIp(addr);
llarp::LogDebug("llarp::TunIfAddr: ", tunIp);
dns_iptracker_setup_dotLokiLookup(&dll, tunIp);
dns_iptracker_setup(tunIp);
}
else
{
llarp::LogWarn("No tun interface, can't look up .loki");
}
*/
// run system and wait
llarp_main_run(ctx);
llarp_main_free(ctx);
}
else if(useLlarp)
2018-07-13 13:13:38 +00:00
{
2018-07-16 12:48:04 +00:00
// libev version
2018-07-21 13:24:47 +00:00
llarp_ev_loop *netloop = nullptr;
2018-07-16 12:48:04 +00:00
llarp_threadpool *worker = nullptr;
2018-12-10 14:14:55 +00:00
llarp::Logic *logic = nullptr;
2018-07-21 13:24:47 +00:00
2018-08-08 12:50:03 +00:00
llarp_ev_loop_alloc(&netloop); // set up netio worker
worker = llarp_init_same_process_threadpool();
2018-12-10 14:14:55 +00:00
logic = new llarp::Logic(worker); // set up logic worker
2018-07-21 13:24:47 +00:00
2018-07-16 12:48:04 +00:00
// configure main netloop
struct dnsd_context dnsd;
2018-09-29 10:28:24 +00:00
llarp::Addr dnsd_sockaddr(127, 0, 0, 1, 53);
llarp::Addr dnsc_sockaddr(dnsr_config.upstream_host,
dnsr_config.upstream_port);
llarp::LogInfo("dnsd_sockaddr init: ", dnsd_sockaddr);
llarp::LogInfo("dnsc_sockaddr init: ", dnsc_sockaddr);
if(!llarp_dnsd_init(&dnsd, logic, netloop, dnsd_sockaddr, dnsc_sockaddr))
{
// llarp::LogError("failed to initialize dns subsystem");
llarp::LogError("Couldnt init dns daemon");
return 0;
}
// Configure intercept
2018-09-22 10:39:53 +00:00
dnsd.intercept = &llarp_dotlokilookup_handler;
2018-07-21 13:24:47 +00:00
llarp::LogInfo("singlethread start");
llarp_ev_loop_run_single_process(netloop, worker, logic);
llarp::LogInfo("singlethread end");
2018-07-16 12:48:04 +00:00
llarp_ev_loop_free(&netloop);
}
else
{
// need this for timer stuff
2018-12-10 14:14:55 +00:00
llarp_threadpool *worker = llarp_init_same_process_threadpool();
llarp::Logic *logic = new llarp::Logic(worker);
2018-08-01 09:04:40 +00:00
// configure main netloop
struct dnsd_context dnsd;
2018-09-29 10:28:24 +00:00
llarp::Addr dnsd_sockaddr(127, 0, 0, 1, 53);
llarp::Addr dnsc_sockaddr(dnsr_config.upstream_host,
dnsr_config.upstream_port);
if(!llarp_dnsd_init(&dnsd, logic, nullptr, dnsd_sockaddr, dnsc_sockaddr))
2018-08-01 09:04:40 +00:00
{
// llarp::LogError("failed to initialize dns subsystem");
llarp::LogError("Couldnt init dns daemon");
return 0;
}
// Configure intercept
2018-09-22 10:39:53 +00:00
dnsd.intercept = &llarp_dotlokilookup_handler;
2018-07-16 12:48:04 +00:00
struct sockaddr_in m_address;
int m_sockfd;
2018-07-21 13:24:47 +00:00
#ifndef _WIN32
m_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
#else
m_sockfd =
WSASocket(AF_INET, SOCK_DGRAM, 0, nullptr, 0, WSA_FLAG_OVERLAPPED);
#endif
2018-07-21 13:24:47 +00:00
m_address.sin_family = AF_INET;
2018-07-16 12:48:04 +00:00
m_address.sin_addr.s_addr = INADDR_ANY;
2018-09-20 10:08:07 +00:00
m_address.sin_port = htons(server_port);
2018-07-21 13:24:47 +00:00
int rbind = bind(m_sockfd, (struct sockaddr *)&m_address,
sizeof(struct sockaddr_in));
if(rbind != 0)
{
2018-07-16 12:48:04 +00:00
llarp::LogError("Could not bind: ", strerror(errno));
return 0;
}
2018-07-21 13:24:47 +00:00
2018-07-16 12:48:04 +00:00
const size_t BUFFER_SIZE = 1024;
2018-07-21 13:24:47 +00:00
char buffer[BUFFER_SIZE]; // 1024 is buffer size
2018-07-16 12:48:04 +00:00
struct sockaddr_in clientAddress;
2018-07-21 13:24:47 +00:00
socklen_t addrLen = sizeof(struct sockaddr_in);
2018-07-16 12:48:04 +00:00
struct timeval tv;
2018-07-21 13:24:47 +00:00
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000; // 1 sec
#ifndef _WIN32
2018-07-21 13:24:47 +00:00
if(setsockopt(m_sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
#else
2018-08-08 12:50:03 +00:00
if(setsockopt(m_sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv,
sizeof(tv))
< 0)
#endif
2018-07-21 13:24:47 +00:00
{
2018-07-16 12:48:04 +00:00
perror("Error");
}
2018-07-21 13:24:47 +00:00
2018-07-16 12:48:04 +00:00
signal(SIGINT, handle_signal);
while(!done)
{
// sigint quits after next packet
int nbytes = recvfrom(m_sockfd, buffer, BUFFER_SIZE, 0,
2018-07-21 13:24:47 +00:00
(struct sockaddr *)&clientAddress, &addrLen);
if(nbytes == -1)
continue;
2018-07-16 12:48:04 +00:00
llarp::LogInfo("Received Bytes ", nbytes);
2018-11-22 00:39:09 +00:00
llarp_buffer_t lbuffer;
lbuffer.base = (byte_t *)buffer;
lbuffer.cur = lbuffer.base;
lbuffer.sz = nbytes;
2018-11-22 00:39:09 +00:00
2018-12-01 14:35:11 +00:00
dns_msg_header hdr;
if(!decode_hdr(&lbuffer, &hdr))
{
llarp::LogError("failed to decode dns header");
continue;
}
// if we sent this out, then there's an id
struct dns_tracker *tracker = (struct dns_tracker *)dnsd.client.tracker;
2018-11-22 00:39:09 +00:00
struct dnsc_answer_request *request =
2018-12-01 14:35:11 +00:00
tracker->client_request[hdr.id].get();
2018-11-22 00:39:09 +00:00
if(request)
{
request->packet.header = hdr;
2018-12-01 14:35:11 +00:00
generic_handle_dnsc_recvfrom(tracker->client_request[hdr.id].get(),
lbuffer, &hdr);
}
else
{
2018-12-01 14:35:11 +00:00
llarp::LogWarn("Ignoring multiple responses on ID #", hdr.id);
}
2018-11-22 00:39:09 +00:00
// raw_handle_recvfrom(&m_sockfd, (const struct sockaddr *)&clientAddress,
// buffer, nbytes);
2018-07-16 12:48:04 +00:00
}
2018-07-13 13:13:38 +00:00
}
return code;
}