DNS changes, mostly work?
This commit is contained in:
@ -42,6 +42,9 @@
|
||||
|
||||
#include "../uicmd.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
/* Used to send a message to the bw's status bar */
|
||||
#define MSG_BW(web, root, ...) \
|
||||
D_STMT_START { \
|
||||
@ -58,18 +61,18 @@ static const int HTTP_SOCKET_TLS = 0x8;
|
||||
static const int HTTP_SOCKET_IOWATCH_ACTIVE = 0x10;
|
||||
|
||||
/* 'web' is just a reference (no need to deallocate it here). */
|
||||
typedef struct {
|
||||
struct SocketData_t {
|
||||
int SockFD;
|
||||
uint_t flags;
|
||||
DilloWeb *web; /* reference to client's web structure */
|
||||
DilloUrl *url;
|
||||
Dlist *addr_list; /* Holds the DNS answer */
|
||||
std::vector< std::shared_ptr< DilloHost > > addr_list; /* Holds the DNS answer */
|
||||
int addr_list_idx;
|
||||
ChainLink *Info; /* Used for CCC asynchronous operations */
|
||||
char *connected_to; /* Used for per-server connection limit */
|
||||
uint_t connect_port;
|
||||
Dstr *https_proxy_reply;
|
||||
} SocketData_t;
|
||||
};
|
||||
|
||||
/* Data structures and functions to queue sockets that need to be
|
||||
* delayed due to the per host connection limit.
|
||||
@ -569,7 +572,9 @@ static void Http_connect_socket(ChainLink *Info)
|
||||
DilloHost *dh;
|
||||
SocketData_t *S = reinterpret_cast< SocketData_t * >( a_Klist_get_data(ValidSocks, VOIDP2INT(Info->LocalKey)) );
|
||||
|
||||
for (; (dh = reinterpret_cast< DilloHost * >( dList_nth_data(S->addr_list, S->addr_list_idx) ));
|
||||
std::cerr << "I see " << S->addr_list.size() << " addresses to try." << std::endl;
|
||||
std::cerr << "I see " << S->addr_list_idx << " as the starting index." << std::endl;
|
||||
for (; (S->addr_list_idx < S->addr_list.size() and ( dh = S->addr_list.at( S->addr_list_idx ).get() ) );
|
||||
S->addr_list_idx++) {
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 name;
|
||||
@ -578,6 +583,14 @@ static void Http_connect_socket(ChainLink *Info)
|
||||
#endif
|
||||
socklen_t socket_len = 0;
|
||||
|
||||
std::cerr << "Going to try ";
|
||||
for( int ii= 0; ii < dh->alen; ++ii )
|
||||
{
|
||||
std::cerr << std::hex << std::setw( 2 ) << std::setfill( '0' ) << (int) ( dh->data[ ii ] & 0xFF );
|
||||
if( ii % 2 and ii != ( dh->alen - 1 ) ) std::cerr << ":";
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
|
||||
if (S->addr_list_idx > 0 && S->SockFD >= 0) {
|
||||
/* clean up the previous one that failed */
|
||||
Http_fd_map_remove_entry(S->SockFD);
|
||||
@ -654,7 +667,7 @@ static void Http_connect_socket(ChainLink *Info)
|
||||
}
|
||||
} /* for */
|
||||
|
||||
if (S->addr_list_idx >= dList_length(S->addr_list) ) {
|
||||
if (S->addr_list_idx >= S->addr_list.size() ) {
|
||||
MSG("Http_connect_socket ran out of IP addrs to try.\n");
|
||||
a_Http_connect_done(S->SockFD, FALSE);
|
||||
}
|
||||
@ -737,7 +750,7 @@ static char *Http_get_connect_str(const DilloUrl *url)
|
||||
* Continue connecting the socket, or abort upon error condition.
|
||||
* S->web is checked to assert the operation wasn't aborted while waiting.
|
||||
*/
|
||||
static void Http_dns_cb(int Status, Dlist *addr_list, void *data)
|
||||
static void Http_dns_cb(int Status, std::optional< std::vector< std::shared_ptr< DilloHost > > > &addr_list, void *data)
|
||||
{
|
||||
int SKey = VOIDP2INT(data);
|
||||
bool_t clean_up = TRUE;
|
||||
@ -749,10 +762,10 @@ static void Http_dns_cb(int Status, Dlist *addr_list, void *data)
|
||||
const char *host = URL_HOST((S->flags & HTTP_SOCKET_USE_PROXY) ?
|
||||
HTTP_Proxy : S->url);
|
||||
if (a_Web_valid(S->web)) {
|
||||
if (Status == 0 && addr_list) {
|
||||
if (Status == 0 && addr_list.has_value()) {
|
||||
|
||||
/* Successful DNS answer; save the IP */
|
||||
S->addr_list = addr_list;
|
||||
S->addr_list = addr_list.value();
|
||||
S->addr_list_idx = 0;
|
||||
clean_up = FALSE;
|
||||
srv = Http_server_get(host, S->connect_port,
|
||||
|
140
src/dns.cc
140
src/dns.cc
@ -42,6 +42,10 @@
|
||||
#include "list.h"
|
||||
#include "IO/iowatch.hh"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
|
||||
/* Maximum dns resolving threads */
|
||||
#ifdef D_DNS_THREADED
|
||||
@ -56,28 +60,28 @@ typedef enum {
|
||||
DNS_SERVER_RESOLVED,
|
||||
} DnsServerState_t;
|
||||
|
||||
typedef struct {
|
||||
struct DnsServer {
|
||||
int channel; /**< Index of this channel [0 based] */
|
||||
DnsServerState_t state;
|
||||
Dlist *addr_list; /**< IP address */
|
||||
HostList addr_list; /**< IP address */
|
||||
char *hostname; /**< Address to resolve */
|
||||
int status; /**< errno code for resolving function */
|
||||
#ifdef D_DNS_THREADED
|
||||
pthread_t th1; /**< Thread id */
|
||||
#endif
|
||||
} DnsServer;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *hostname; /**< host name for cache */
|
||||
Dlist *addr_list; /**< addresses of host */
|
||||
} GDnsCache;
|
||||
struct GDnsCache {
|
||||
std::string hostname; /**< host name for cache */
|
||||
HostList addr_list; /**< addresses of host */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GDnsQueue {
|
||||
int channel; /**< -2 if waiting, otherwise index to dns_server[] */
|
||||
char *hostname; /**< The one we're resolving */
|
||||
std::string hostname; /**< The one we're resolving */
|
||||
DnsCallback_t cb_func; /**< callback function */
|
||||
void *cb_data; /**< extra data for the callback function */
|
||||
} GDnsQueue;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@ -90,10 +94,8 @@ static void Dns_timeout_client(int fd, void *data);
|
||||
*/
|
||||
static DnsServer dns_server[D_DNS_MAX_SERVERS];
|
||||
static int num_servers;
|
||||
static GDnsCache *dns_cache;
|
||||
static int dns_cache_size, dns_cache_size_max;
|
||||
static GDnsQueue *dns_queue;
|
||||
static int dns_queue_size, dns_queue_size_max;
|
||||
static std::vector< GDnsCache > dns_cache;
|
||||
static std::vector< GDnsQueue > dns_queue;
|
||||
static int dns_notify_pipe[2];
|
||||
|
||||
|
||||
@ -103,12 +105,12 @@ static int dns_notify_pipe[2];
|
||||
static void Dns_queue_add(int channel, const char *hostname,
|
||||
DnsCallback_t cb_func, void *cb_data)
|
||||
{
|
||||
a_List_add(dns_queue, dns_queue_size, dns_queue_size_max, GDnsQueue);
|
||||
dns_queue[dns_queue_size].channel = channel;
|
||||
dns_queue[dns_queue_size].hostname = dStrdup(hostname);
|
||||
dns_queue[dns_queue_size].cb_func = cb_func;
|
||||
dns_queue[dns_queue_size].cb_data = cb_data;
|
||||
dns_queue_size++;
|
||||
GDnsQueue entry;
|
||||
entry.channel = channel;
|
||||
entry.hostname = hostname;
|
||||
entry.cb_func = cb_func;
|
||||
entry.cb_data = cb_data;
|
||||
dns_queue.push_back( entry );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,8 +121,8 @@ static int Dns_queue_find(const char *hostname)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dns_queue_size; i++)
|
||||
if (!dStrAsciiCasecmp(hostname, dns_queue[i].hostname))
|
||||
for (i = 0; i < dns_queue.size(); i++)
|
||||
if (!dStrAsciiCasecmp(hostname, dns_queue[i].hostname.c_str()))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
@ -131,17 +133,10 @@ static int Dns_queue_find(const char *hostname)
|
||||
*/
|
||||
static void Dns_queue_remove(int index)
|
||||
{
|
||||
int i;
|
||||
|
||||
_MSG("Dns_queue_remove: deleting client [%d] [queue_size=%d]\n",
|
||||
index, dns_queue_size);
|
||||
index, dns_queue.size());
|
||||
|
||||
if (index < dns_queue_size) {
|
||||
dFree(dns_queue[index].hostname);
|
||||
--dns_queue_size; /* you'll find out why ;-) */
|
||||
for (i = index; i < dns_queue_size; i++)
|
||||
dns_queue[i] = dns_queue[i + 1];
|
||||
}
|
||||
if (index < dns_queue.size()) dns_queue.erase( begin( dns_queue ) + index );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -161,13 +156,13 @@ void Dns_queue_print()
|
||||
/**
|
||||
* Add an IP/hostname pair to Dns-cache
|
||||
*/
|
||||
static void Dns_cache_add(char *hostname, Dlist *addr_list)
|
||||
static void Dns_cache_add(char *hostname, std::optional< std::vector< std::shared_ptr< DilloHost > > > addr_list)
|
||||
{
|
||||
a_List_add(dns_cache, dns_cache_size, dns_cache_size_max, GDnsCache);
|
||||
dns_cache[dns_cache_size].hostname = dStrdup(hostname);
|
||||
dns_cache[dns_cache_size].addr_list = addr_list;
|
||||
++dns_cache_size;
|
||||
_MSG("Cache objects: %d\n", dns_cache_size);
|
||||
GDnsCache entry;
|
||||
entry.hostname = hostname;
|
||||
entry.addr_list = std::move( addr_list );
|
||||
dns_cache.push_back( entry );
|
||||
_MSG("Cache objects: %d\n", dns_cache.size());
|
||||
}
|
||||
|
||||
|
||||
@ -184,13 +179,13 @@ void a_Dns_init(void)
|
||||
MSG("dillo_dns_init: Here we go! (not threaded)\n");
|
||||
#endif
|
||||
|
||||
dns_queue_size = 0;
|
||||
dns_queue_size_max = 16;
|
||||
dns_queue = dNew(GDnsQueue, dns_queue_size_max);
|
||||
//dns_queue_size = 0;
|
||||
//dns_queue_size_max = 16;
|
||||
//dns_queue = dNew(GDnsQueue, dns_queue_size_max);
|
||||
|
||||
dns_cache_size = 0;
|
||||
dns_cache_size_max = 16;
|
||||
dns_cache = dNew(GDnsCache, dns_cache_size_max);
|
||||
//dns_cache_size = 0;
|
||||
//dns_cache_size_max = 16;
|
||||
//dns_cache = dNew(GDnsCache, dns_cache_size_max);
|
||||
|
||||
num_servers = D_DNS_MAX_SERVERS;
|
||||
|
||||
@ -203,7 +198,7 @@ void a_Dns_init(void)
|
||||
for (i = 0; i < num_servers; ++i) {
|
||||
dns_server[i].channel = i;
|
||||
dns_server[i].state = DNS_SERVER_IDLE;
|
||||
dns_server[i].addr_list = NULL;
|
||||
//dns_server[i].addr_list = NULL;
|
||||
dns_server[i].hostname = NULL;
|
||||
dns_server[i].status = 0;
|
||||
#ifdef D_DNS_THREADED
|
||||
@ -216,10 +211,10 @@ void a_Dns_init(void)
|
||||
* Allocate a host structure and add it to the list
|
||||
*/
|
||||
|
||||
static void Dns_note_hosts(Dlist *list, struct addrinfo *res0)
|
||||
static void Dns_note_hosts(std::vector< std::shared_ptr< DilloHost > > &list, struct addrinfo *res0)
|
||||
{
|
||||
struct addrinfo *res;
|
||||
DilloHost *dh;
|
||||
std::unique_ptr< DilloHost > dh;
|
||||
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
|
||||
@ -230,14 +225,14 @@ static void Dns_note_hosts(Dlist *list, struct addrinfo *res0)
|
||||
continue;
|
||||
}
|
||||
|
||||
dh = dNew0(DilloHost, 1);
|
||||
dh = std::make_unique< DilloHost >();
|
||||
dh->af = AF_INET;
|
||||
|
||||
in_addr = (struct sockaddr_in*) res->ai_addr;
|
||||
dh->alen = sizeof (struct in_addr);
|
||||
memcpy(&dh->data[0], &in_addr->sin_addr.s_addr, dh->alen);
|
||||
|
||||
dList_append(list, dh);
|
||||
list.push_back( std::move( dh ) );
|
||||
#ifdef ENABLE_IPV6
|
||||
} else if (res->ai_family == AF_INET6) {
|
||||
struct sockaddr_in6 *in6_addr;
|
||||
@ -246,14 +241,14 @@ static void Dns_note_hosts(Dlist *list, struct addrinfo *res0)
|
||||
continue;
|
||||
}
|
||||
|
||||
dh = dNew0(DilloHost, 1);
|
||||
dh = std::make_unique< DilloHost >();
|
||||
dh->af = AF_INET6;
|
||||
|
||||
in6_addr = (struct sockaddr_in6*) res->ai_addr;
|
||||
dh->alen = sizeof (struct in6_addr);
|
||||
memcpy(&dh->data[0], &in6_addr->sin6_addr.s6_addr, dh->alen);
|
||||
|
||||
dList_append(list, dh);
|
||||
list.push_back( std::move( dh ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -267,7 +262,7 @@ static void *Dns_server(void *data)
|
||||
int channel = VOIDP2INT(data);
|
||||
struct addrinfo hints, *res0;
|
||||
int error;
|
||||
Dlist *hosts;
|
||||
std::vector< std::shared_ptr< DilloHost > > hosts;
|
||||
size_t length, i;
|
||||
char addr_string[40];
|
||||
|
||||
@ -279,8 +274,6 @@ static void *Dns_server(void *data)
|
||||
#endif
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
hosts = dList_new(2);
|
||||
|
||||
_MSG("Dns_server: starting...\n ch: %d host: %s\n",
|
||||
channel, dns_server[channel].hostname);
|
||||
|
||||
@ -295,19 +288,18 @@ static void *Dns_server(void *data)
|
||||
freeaddrinfo(res0);
|
||||
}
|
||||
|
||||
if (dList_length(hosts) > 0) {
|
||||
if (hosts.size() > 0) {
|
||||
dns_server[channel].status = 0;
|
||||
} else {
|
||||
dList_free(hosts);
|
||||
hosts = NULL;
|
||||
hosts.clear(); // Superfluous? -- ADAM
|
||||
}
|
||||
|
||||
/* tell our findings */
|
||||
MSG("Dns_server [%d]: %s is", channel,
|
||||
dns_server[channel].hostname);
|
||||
if ((length = dList_length(hosts))) {
|
||||
if ((length = hosts.size())) {
|
||||
for (i = 0; i < length; i++) {
|
||||
a_Dns_dillohost_to_string(reinterpret_cast< DilloHost * >( dList_nth_data(hosts, i) ),
|
||||
a_Dns_dillohost_to_string(hosts.at( i ).get(),
|
||||
addr_string, sizeof(addr_string));
|
||||
MSG(" %s", addr_string);
|
||||
}
|
||||
@ -366,11 +358,11 @@ void a_Dns_resolve(const char *hostname, DnsCallback_t cb_func, void *cb_data)
|
||||
return;
|
||||
|
||||
/* check for cache hit. */
|
||||
for (i = 0; i < dns_cache_size; i++)
|
||||
if (!dStrAsciiCasecmp(hostname, dns_cache[i].hostname))
|
||||
for (i = 0; i < dns_cache.size(); i++)
|
||||
if (!dStrAsciiCasecmp(hostname, dns_cache[i].hostname.c_str()))
|
||||
break;
|
||||
|
||||
if (i < dns_cache_size) {
|
||||
if (i < dns_cache.size()) {
|
||||
/* already resolved, call the Callback immediately. */
|
||||
cb_func(0, dns_cache[i].addr_list, cb_data);
|
||||
|
||||
@ -404,7 +396,7 @@ static void Dns_serve_channel(int channel)
|
||||
int i;
|
||||
DnsServer *srv = &dns_server[channel];
|
||||
|
||||
for (i = 0; i < dns_queue_size; i++) {
|
||||
for (i = 0; i < dns_queue.size(); i++) {
|
||||
if (dns_queue[i].channel == channel) {
|
||||
dns_queue[i].cb_func(srv->status, srv->addr_list,
|
||||
dns_queue[i].cb_data);
|
||||
@ -424,20 +416,20 @@ static void Dns_assign_channels(void)
|
||||
for (ch = 0; ch < num_servers; ++ch) {
|
||||
if (dns_server[ch].state == DNS_SERVER_IDLE) {
|
||||
/* Find the next query in the queue (we're a FIFO) */
|
||||
for (i = 0; i < dns_queue_size; i++)
|
||||
for (i = 0; i < dns_queue.size(); i++)
|
||||
if (dns_queue[i].channel == -2)
|
||||
break;
|
||||
|
||||
if (i < dns_queue_size) {
|
||||
if (i < dns_queue.size()) {
|
||||
/* assign this channel to every queued request
|
||||
* with the same hostname*/
|
||||
for (j = i; j < dns_queue_size; j++)
|
||||
for (j = i; j < dns_queue.size(); j++)
|
||||
if (dns_queue[j].channel == -2 &&
|
||||
!dStrAsciiCasecmp(dns_queue[j].hostname,
|
||||
dns_queue[i].hostname)) {
|
||||
!dStrAsciiCasecmp(dns_queue[j].hostname.c_str(),
|
||||
dns_queue[i].hostname.c_str())) {
|
||||
dns_queue[j].channel = ch;
|
||||
}
|
||||
Dns_server_req(ch, dns_queue[i].hostname);
|
||||
Dns_server_req(ch, dns_queue[i].hostname.c_str());
|
||||
} else
|
||||
return;
|
||||
}
|
||||
@ -459,7 +451,7 @@ static void Dns_timeout_client(int fd, void *data)
|
||||
DnsServer *srv = &dns_server[i];
|
||||
|
||||
if (srv->state == DNS_SERVER_RESOLVED) {
|
||||
if (srv->addr_list != NULL) {
|
||||
if (srv->addr_list.has_value()) {
|
||||
/* DNS succeeded, let's cache it */
|
||||
Dns_cache_add(srv->hostname, srv->addr_list);
|
||||
}
|
||||
@ -479,18 +471,10 @@ static void Dns_timeout_client(int fd, void *data)
|
||||
*/
|
||||
void a_Dns_freeall(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for ( i = 0; i < dns_cache_size; ++i ){
|
||||
dFree(dns_cache[i].hostname);
|
||||
for ( j = 0; j < dList_length(dns_cache[i].addr_list); ++j)
|
||||
dFree(dList_nth_data(dns_cache[i].addr_list, j));
|
||||
dList_free(dns_cache[i].addr_list);
|
||||
}
|
||||
a_IOwatch_remove_fd(dns_notify_pipe[0], DIO_READ);
|
||||
dClose(dns_notify_pipe[0]);
|
||||
dClose(dns_notify_pipe[1]);
|
||||
dFree(dns_cache);
|
||||
dns_cache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
15
src/dns.hh
15
src/dns.hh
@ -3,12 +3,21 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
typedef void (*DnsCallback_t)(int status, Dlist *addr_list, void *data);
|
||||
struct DilloHost;
|
||||
|
||||
using HostList= std::optional< std::vector< std::shared_ptr< DilloHost > > >;
|
||||
|
||||
|
||||
typedef void (*DnsCallback_t)(int status, HostList &addr_list, void *data);
|
||||
|
||||
void a_Dns_init (void);
|
||||
void a_Dns_freeall(void);
|
||||
@ -20,11 +29,11 @@ void a_Dns_resolve(const char *hostname, DnsCallback_t cb_func, void *cb_data);
|
||||
# define DILLO_ADDR_MAX sizeof(struct in_addr)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
struct DilloHost {
|
||||
int af;
|
||||
int alen;
|
||||
char data[DILLO_ADDR_MAX];
|
||||
} DilloHost;
|
||||
};
|
||||
|
||||
void a_Dns_dillohost_to_string(DilloHost *host, char *dst, size_t size);
|
||||
|
||||
|
Reference in New Issue
Block a user