blob: cfd01d6f8d1401616e164cdba089e76766c7ec23 [file] [log] [blame]
/** @file
A brief file description
@section license License
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include "tscore/ink_resolver.h"
#include "I_EventSystem.h"
#include "SRV.h"
// Events
#define DNS_EVENT_LOOKUP DNS_EVENT_EVENTS_START
const int DOMAIN_SERVICE_PORT = NAMESERVER_PORT;
const int MAX_DNS_REQUEST_LEN = NS_PACKETSZ;
const int MAX_DNS_RESPONSE_LEN = 65536;
const int DNS_RR_MAX_COUNT = (MAX_DNS_RESPONSE_LEN - HFIXEDSZ + RRFIXEDSZ - 1) / RRFIXEDSZ;
const int DNS_MAX_ALIASES = DNS_RR_MAX_COUNT;
const int DNS_MAX_ADDRS = DNS_RR_MAX_COUNT;
const int DNS_HOSTBUF_SIZE = MAX_DNS_RESPONSE_LEN;
/**
All buffering required to handle a DNS receipt. For asynchronous DNS,
only one HostEntBuf will exist in the system. For synchronous DNS,
one will exist per call until the user deletes them.
*/
struct HostEnt : RefCountObj {
struct hostent ent = {.h_name = nullptr, .h_aliases = nullptr, .h_addrtype = 0, .h_length = 0, .h_addr_list = nullptr};
uint32_t ttl = 0;
int packet_size = 0;
char buf[MAX_DNS_RESPONSE_LEN] = {0};
u_char *host_aliases[DNS_MAX_ALIASES] = {nullptr};
u_char *h_addr_ptrs[DNS_MAX_ADDRS + 1] = {nullptr};
u_char hostbuf[DNS_HOSTBUF_SIZE] = {0};
SRVHosts srv_hosts;
bool good = true;
bool isNameError();
void free() override;
};
extern EventType ET_DNS;
struct DNSHandler;
/** Data for a DNS query.
* This is either a name for a standard query or an IP address for reverse DNS.
* Its type should be indicated by other parameters, generally the query type.
* - T_PTR: IP Address
* - T_A, T_SRV: Name
*/
union DNSQueryData {
std::string_view name; ///< Look up a name.
IpAddr const *addr; ///< Reverse DNS lookup.
DNSQueryData(std::string_view tv) : name(tv) {}
DNSQueryData(IpAddr const *a) : addr(a) {}
};
struct DNSProcessor : public Processor {
// Public Interface
//
/// Options for host name resolution.
struct Options {
using self_type = Options; ///< Self reference type.
/// Query handler to use.
/// Default: single threaded handler.
DNSHandler *handler = nullptr;
/// Query timeout value.
/// Default: @c DEFAULT_DNS_TIMEOUT (or as set in records.config)
int timeout = 0; ///< Timeout value for request.
/// Host resolution style.
/// Default: IPv4, IPv6 ( @c HOST_RES_IPV4 )
HostResStyle host_res_style = HOST_RES_IPV4;
/// Default constructor.
Options();
/// Set @a handler option.
/// @return This object.
self_type &setHandler(DNSHandler *handler);
/// Set @a timeout option.
/// @return This object.
self_type &setTimeout(int timeout);
/// Set host query @a style option.
/// @return This object.
self_type &setHostResStyle(HostResStyle style);
/// Reset to default constructed values.
/// @return This object.
self_type &reset();
};
// DNS lookup
// calls: cont->handleEvent( DNS_EVENT_LOOKUP, HostEnt *ent) on success
// cont->handleEvent( DNS_EVENT_LOOKUP, nullptr) on failure
// NOTE: the HostEnt *block is freed when the function returns
//
Action *gethostbyname(Continuation *cont, const char *name, Options const &opt);
Action *gethostbyname(Continuation *cont, std::string_view name, Options const &opt);
Action *getSRVbyname(Continuation *cont, const char *name, Options const &opt);
Action *getSRVbyname(Continuation *cont, std::string_view name, Options const &opt);
Action *gethostbyaddr(Continuation *cont, IpAddr const *ip, Options const &opt);
// Processor API
//
/* currently dns system uses event threads
* dont pass any value to the call */
int start(int no_of_extra_dns_threads = 0, size_t stacksize = DEFAULT_STACKSIZE) override;
// Open/close a link to a 'named' (done in start())
//
void open(sockaddr const *ns = nullptr);
DNSProcessor();
// private:
//
EThread *thread = nullptr;
DNSHandler *handler = nullptr;
ts_imp_res_state l_res;
IpEndpoint local_ipv6;
IpEndpoint local_ipv4;
/** Internal implementation for all getXbyY methods.
For host resolution queries pass @c T_A for @a type. It will be adjusted
as needed based on @a opt.host_res_style.
For address resolution ( @a type is @c T_PTR ), @a x should be a
@c sockaddr cast to @c char @c const* .
*/
Action *getby(DNSQueryData x, int type, Continuation *cont, Options const &opt);
void dns_init();
};
//
// Global data
//
extern DNSProcessor dnsProcessor;
//
// Inline Functions
//
inline Action *
DNSProcessor::getSRVbyname(Continuation *cont, const char *name, Options const &opt)
{
return getby(std::string_view(name), T_SRV, cont, opt);
}
inline Action *
DNSProcessor::getSRVbyname(Continuation *cont, std::string_view name, Options const &opt)
{
return getby(name, T_SRV, cont, opt);
}
inline Action *
DNSProcessor::gethostbyname(Continuation *cont, const char *name, Options const &opt)
{
return getby(std::string_view(name), T_A, cont, opt);
}
inline Action *
DNSProcessor::gethostbyname(Continuation *cont, std::string_view name, Options const &opt)
{
return getby(name, T_A, cont, opt);
}
inline Action *
DNSProcessor::gethostbyaddr(Continuation *cont, IpAddr const *addr, Options const &opt)
{
return getby(addr, T_PTR, cont, opt);
}
inline DNSProcessor::Options::Options() {}
inline DNSProcessor::Options &
DNSProcessor::Options::setHandler(DNSHandler *h)
{
handler = h;
return *this;
}
inline DNSProcessor::Options &
DNSProcessor::Options::setTimeout(int t)
{
timeout = t;
return *this;
}
inline DNSProcessor::Options &
DNSProcessor::Options::setHostResStyle(HostResStyle style)
{
host_res_style = style;
return *this;
}
inline DNSProcessor::Options &
DNSProcessor::Options::reset()
{
*this = Options();
return *this;
}
void ink_dns_init(ts::ModuleVersion version);