2018-01-28 18:37:13 +01:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
|
|
// copyright notice and this permission notice is present in all copies. The
|
|
|
|
// full license for this software is available in the LICENSE file.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
#define HAVE_IRCD_NET_RESOLVER_H
|
|
|
|
|
|
|
|
// This file is not included with the IRCd standard include stack because
|
|
|
|
// it requires symbols we can't forward declare without boost headers. It
|
|
|
|
// is part of the <ircd/asio.h> stack which can be included in your
|
|
|
|
// definition file if you need low level access to this resolver API.
|
|
|
|
|
|
|
|
/// Internal resolver service
|
|
|
|
struct ircd::net::dns::resolver
|
|
|
|
{
|
2018-01-28 23:19:35 +01:00
|
|
|
struct tag;
|
|
|
|
using header = rfc1035::header;
|
2018-01-28 18:37:13 +01:00
|
|
|
|
2018-03-02 08:08:22 +01:00
|
|
|
static constexpr const size_t &MAX_COUNT{64};
|
2018-03-09 21:22:10 +01:00
|
|
|
static conf::item<milliseconds> timeout;
|
2018-03-12 20:14:21 +01:00
|
|
|
static conf::item<milliseconds> send_rate;
|
2018-03-02 08:08:22 +01:00
|
|
|
|
2018-01-28 18:37:13 +01:00
|
|
|
std::vector<ip::udp::endpoint> server; // The list of active servers
|
|
|
|
size_t server_next{0}; // Round-robin state to hit servers
|
2018-01-28 23:19:35 +01:00
|
|
|
void init_servers();
|
|
|
|
|
|
|
|
ctx::dock dock;
|
|
|
|
std::map<uint16_t, tag> tags; // The active requests
|
2018-03-12 20:14:21 +01:00
|
|
|
steady_point send_last; // Time of last send
|
|
|
|
using queued = std::pair<uint16_t, std::string>;
|
|
|
|
std::deque<queued> sendq; // Queue of frames for rate-limiting
|
2018-01-28 18:37:13 +01:00
|
|
|
|
2018-01-28 23:19:35 +01:00
|
|
|
ip::udp::socket ns; // A pollable activity object
|
2018-02-03 22:15:55 +01:00
|
|
|
ip::udp::endpoint reply_from; // Remote addr of recv
|
2018-04-29 02:21:30 +02:00
|
|
|
unique_buffer<mutable_buffer> reply; // Buffer for recv
|
2018-01-28 18:37:13 +01:00
|
|
|
|
2018-01-28 23:19:35 +01:00
|
|
|
bool handle_error(const error_code &ec) const;
|
2018-04-29 01:42:18 +02:00
|
|
|
bool handle_error(const header &, const rfc1035::question &, tag &);
|
2018-01-28 23:19:35 +01:00
|
|
|
void handle_reply(const header &, const const_buffer &body, tag &);
|
|
|
|
void handle_reply(const header &, const const_buffer &body);
|
2018-01-28 18:37:13 +01:00
|
|
|
void handle(const error_code &ec, const size_t &) noexcept;
|
|
|
|
void set_handle();
|
|
|
|
|
2018-03-12 20:14:21 +01:00
|
|
|
void queue_query(const const_buffer &, tag &);
|
|
|
|
void send_query(const ip::udp::endpoint &, const const_buffer &, tag &);
|
|
|
|
void send_query(const const_buffer &, tag &);
|
|
|
|
void submit(const const_buffer &, tag &);
|
2018-01-28 18:37:13 +01:00
|
|
|
|
2018-05-02 03:40:03 +02:00
|
|
|
template<class... A> tag &set_tag(A&&...);
|
2018-02-03 22:15:55 +01:00
|
|
|
const_buffer make_query(const mutable_buffer &buf, const tag &) const;
|
|
|
|
void operator()(const hostport &, const opts &, callback);
|
2018-01-28 23:19:35 +01:00
|
|
|
|
2018-03-02 11:02:13 +01:00
|
|
|
bool check_timeout(const uint16_t &id, tag &, const steady_point &expired);
|
2018-03-09 21:22:10 +01:00
|
|
|
void check_timeouts(const milliseconds &timeout);
|
2018-03-12 20:14:21 +01:00
|
|
|
void timeout_worker();
|
|
|
|
ctx::context timeout_context;
|
|
|
|
|
|
|
|
void flush(const queued &);
|
|
|
|
void sendq_worker();
|
|
|
|
ctx::context sendq_context;
|
2018-01-28 18:37:13 +01:00
|
|
|
|
|
|
|
resolver();
|
|
|
|
~resolver() noexcept;
|
|
|
|
};
|
2018-01-28 23:19:35 +01:00
|
|
|
|
|
|
|
struct ircd::net::dns::resolver::tag
|
|
|
|
{
|
2018-02-03 22:15:55 +01:00
|
|
|
uint16_t id {0};
|
2018-05-02 03:40:03 +02:00
|
|
|
hostport hp;
|
2018-03-02 08:08:22 +01:00
|
|
|
dns::opts opts; // note: invalid after query sent
|
2018-02-03 22:15:55 +01:00
|
|
|
callback cb;
|
2018-03-12 20:14:21 +01:00
|
|
|
steady_point last;
|
2018-01-28 23:19:35 +01:00
|
|
|
uint8_t tries {0};
|
2018-05-02 03:40:03 +02:00
|
|
|
char hostbuf[256];
|
2018-01-28 23:19:35 +01:00
|
|
|
|
2018-05-02 03:40:03 +02:00
|
|
|
tag(const hostport &, const dns::opts &, callback &&);
|
2018-01-28 23:19:35 +01:00
|
|
|
};
|
2018-02-03 22:15:55 +01:00
|
|
|
|
|
|
|
inline
|
|
|
|
ircd::net::dns::resolver::tag::tag(const hostport &hp,
|
|
|
|
const dns::opts &opts,
|
2018-05-02 03:40:03 +02:00
|
|
|
callback &&cb)
|
2018-02-03 22:15:55 +01:00
|
|
|
:hp{hp}
|
|
|
|
,opts{opts}
|
|
|
|
,cb{std::move(cb)}
|
2018-05-02 03:40:03 +02:00
|
|
|
{
|
|
|
|
this->hp.host = { hostbuf, copy(hostbuf, hp.host) };
|
|
|
|
}
|