mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-28 22:05:48 +08:00
Without nserver (or fakeresolve) names were resolved by the C library. 3proxy's own resolver is now the default, with the system's name servers: up to 3 from /etc/resolv.conf, on Windows from the registry (set for the system, set for an interface with an address, Tcpip6 interfaces, then those DHCP gave). With none found, the C library as before. nserver takes up to 3 as well (MAXNSERVERS), a fourth is warned about. The name servers in force belong to the process, not a configuration: nserver lines are kept aside while a configuration is read and replace them only once it is committed, so a reload resolves with those in force until then. Resolutions and dnspr read a copy of them. The system's are read at start, before the configuration and a chroot in it, and are in force while it is read, so its host names resolve with them; read again at a commit, and checked every 5 seconds from the main loop while the default is in force. What cannot be read then (within a chroot) stays as last read. The hosts file, read with them, is imported into tables of its own while the default is in force: its first address of a family for a name. A name is looked up as one nsrecord made first, then the hosts file, then the name cache, then name servers. A changed file replaces what was imported. No name cache is made for it: without nscache nothing is cached, as before. The name cache's keys are host names of any case now: DNS names are. Tests: sysdns, a name of the hosts file answered by dnspr without nserver, in any case, and not with one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
100 lines
4.7 KiB
C
100 lines
4.7 KiB
C
#include "proxy.h"
|
|
#include "mdhash.h"
|
|
|
|
|
|
static void char_index2hash(const struct hashtable *ht, void *index, uint8_t *hash){
|
|
int len;
|
|
unsigned int blen;
|
|
|
|
len = strlen((const char*)index);
|
|
memset(hash, 0, ht->hash_size);
|
|
if(len <= ht->hash_size) memcpy(hash, index, len);
|
|
else {
|
|
mdh_ctx *bctx = mdh_init(MDH_BLAKE2, ht->hash_size);
|
|
if(!bctx) return;
|
|
mdh_update(bctx, index, (unsigned int)(strlen((const char*)index) + 1));
|
|
blen = ht->hash_size;
|
|
mdh_final(bctx, hash, &blen);
|
|
mdh_free(bctx);
|
|
}
|
|
}
|
|
|
|
/* A host name, whose case does not matter: hashed as lower case */
|
|
static void dns_index2hash(const struct hashtable *ht, void *index, uint8_t *hash){
|
|
char low[1024];
|
|
size_t i, len = strlen((const char *)index);
|
|
|
|
if(len >= sizeof(low)) {
|
|
char_index2hash(ht, index, hash);
|
|
return;
|
|
}
|
|
for(i = 0; i <= len; i++) low[i] = (char)tolower(((unsigned char *)index)[i]);
|
|
char_index2hash(ht, low, hash);
|
|
}
|
|
|
|
static void param2hash_add(const struct hashtable *ht, void *index, uint8_t *hash){
|
|
struct clientparam *param = (struct clientparam *)index;
|
|
|
|
memcpy(hash, param->hash, ht->hash_size);
|
|
}
|
|
|
|
void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
|
|
struct clientparam *param = (struct clientparam *)index;
|
|
unsigned type = param->srv->authcachetype;
|
|
int oplen = 0, acllen = 0, ulen = 0, plen = 0, hlen = 0, a1len = 0, a2len = 0, a3len = 0, p1len=0, p2len = 0;
|
|
|
|
|
|
if((type & 2) && *param->username) ulen = strlen((const char *)param->username) + 1;
|
|
if((type & 4) && *param->password) plen = strlen((const char *)param->password) + 1;
|
|
if((type & 1) && !(type & 8)) a1len = SAADDRLEN(¶m->sincr);
|
|
if((type & 16)) acllen = sizeof(param->srv->acl);
|
|
if((type & 64)) a2len = SAADDRLEN(¶m->req);
|
|
if((type & 128)) p1len = 2 ;
|
|
if((type & 256) && *param->hostname) hlen = strlen((const char *)param->hostname) + 1;
|
|
if((type & 512)) oplen = sizeof(param->operation);
|
|
if((type & 1024)) a3len = SAADDRLEN(¶m->srv->intsa);
|
|
if((type & 2048)) p2len = 2;
|
|
|
|
memset(hash, 0, ht->hash_size);
|
|
if(ulen + plen + a1len + acllen + a2len + p1len + hlen + oplen + a3len + p2len <= ht->hash_size){
|
|
int offset = 0;
|
|
if((type & 2) && *param->username){ memcpy(hash + offset, param->username, ulen); offset += ulen; }
|
|
if((type & 4) && *param->password){ memcpy(hash + offset, param->password, plen); offset += plen; }
|
|
if((type & 1) && !(type & 8)){ memcpy(hash + offset, SAADDR(¶m->sincr), a1len); offset += a1len; }
|
|
if((type & 16)){ memcpy(hash + offset, ¶m->srv->acl, acllen); offset += acllen; }
|
|
if((type & 64)){ memcpy(hash + offset, SAADDR(¶m->req), a2len); offset += a2len; }
|
|
if((type & 128)){ memcpy(hash + offset, SAPORT(¶m->req), p1len); offset += 2; }
|
|
if((type & 256) && *param->hostname){ memcpy(hash + offset, param->hostname, hlen); offset += hlen; }
|
|
if((type & 512)){ memcpy(hash + offset, ¶m->operation, oplen); offset += oplen; }
|
|
if((type & 1024)){ memcpy(hash + offset, SAADDR(¶m->srv->intsa), a3len); offset += a3len; }
|
|
if((type & 2048)){ memcpy(hash + offset, SAPORT(¶m->srv->intsa), p2len); offset += 2; }
|
|
}
|
|
else {
|
|
mdh_ctx *bctx = mdh_init(MDH_BLAKE2, ht->hash_size);
|
|
unsigned int blen = ht->hash_size;
|
|
if(!bctx) { memcpy(param->hash, hash, ht->hash_size); return; }
|
|
if((type & 2) && *param->username)mdh_update(bctx, param->username, ulen);
|
|
if((type & 4) && *param->password)mdh_update(bctx, param->password, plen);
|
|
if((type & 1) && !(type & 8))mdh_update(bctx, SAADDR(¶m->sincr), a1len);
|
|
if((type & 16))mdh_update(bctx, ¶m->srv->acl, acllen);
|
|
if((type & 64))mdh_update(bctx, SAADDR(¶m->req), a2len);
|
|
if((type & 128))mdh_update(bctx, SAPORT(¶m->req), 2);
|
|
if((type & 256) && *param->hostname)mdh_update(bctx, param->hostname, hlen);
|
|
if((type & 512))mdh_update(bctx, ¶m->operation, sizeof(param->operation));
|
|
if((type & 1024))mdh_update(bctx, SAADDR(¶m->srv->intsa), a3len);
|
|
if((type & 2048))mdh_update(bctx, SAPORT(¶m->srv->intsa), 2);
|
|
mdh_final(bctx, hash, &blen);
|
|
mdh_free(bctx);
|
|
}
|
|
memcpy(param->hash, hash, ht->hash_size);
|
|
}
|
|
|
|
struct hashtable dns_table = {dns_index2hash, dns_index2hash, 4, 32};
|
|
struct hashtable dns6_table = {dns_index2hash, dns_index2hash, 16, 32};
|
|
/* the hosts file, while the system's resolver is the default */
|
|
struct hashtable hosts_table = {dns_index2hash, dns_index2hash, 4, 32};
|
|
struct hashtable hosts6_table = {dns_index2hash, dns_index2hash, 16, 32};
|
|
struct hashtable auth_table = {param2hash_add, param2hash_search, sizeof(struct authcache), 64};
|
|
/* users: each configuration has a table of its own, made from this one */
|
|
const struct hashtable pwl_template = {char_index2hash, char_index2hash, 64, 64};
|