mirror of
https://github.com/3proxy/3proxy.git
synced 2026-04-19 18:50:12 +08:00
move hashtable/resolve/sql functions to separate files
This commit is contained in:
parent
4c0e3a1bac
commit
a0d580b36d
@ -283,6 +283,9 @@ set(3PROXY_CORE_SOURCES
|
|||||||
src/3proxy.c
|
src/3proxy.c
|
||||||
src/auth.c
|
src/auth.c
|
||||||
src/authradius.c
|
src/authradius.c
|
||||||
|
src/hash.c
|
||||||
|
src/resolve.c
|
||||||
|
src/sql.c
|
||||||
src/conf.c
|
src/conf.c
|
||||||
src/datatypes.c
|
src/datatypes.c
|
||||||
src/plugins.c
|
src/plugins.c
|
||||||
|
|||||||
@ -119,6 +119,9 @@ srvdnspr$(OBJSUFFICS): dnspr.c proxy.h structures.h
|
|||||||
auth$(OBJSUFFICS): auth.c proxy.h structures.h
|
auth$(OBJSUFFICS): auth.c proxy.h structures.h
|
||||||
$(CC) $(COUT)auth$(OBJSUFFICS) $(CFLAGS) auth.c
|
$(CC) $(COUT)auth$(OBJSUFFICS) $(CFLAGS) auth.c
|
||||||
|
|
||||||
|
hash$(OBJSUFFICS): hash.c proxy.h structures.h
|
||||||
|
$(CC) $(COUT)hash$(OBJSUFFICS) $(CFLAGS) hash.c
|
||||||
|
|
||||||
authradius$(OBJSUFFICS): authradius.c proxy.h structures.h
|
authradius$(OBJSUFFICS): authradius.c proxy.h structures.h
|
||||||
$(CC) $(COUT)authradius$(OBJSUFFICS) $(CFLAGS) authradius.c
|
$(CC) $(COUT)authradius$(OBJSUFFICS) $(CFLAGS) authradius.c
|
||||||
|
|
||||||
@ -150,6 +153,6 @@ md5$(OBJSUFFICS): libs/md5.h libs/md5.c
|
|||||||
stringtable$(OBJSUFFICS): stringtable.c
|
stringtable$(OBJSUFFICS): stringtable.c
|
||||||
$(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c
|
$(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c
|
||||||
|
|
||||||
$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycrypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(VERSIONDEP)
|
$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycrypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(VERSIONDEP)
|
||||||
$(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) mycrypt$(OBJSUFFICS) md5$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
$(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) mycrypt$(OBJSUFFICS) md5$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||||
|
|
||||||
|
|||||||
513
src/auth.c
513
src/auth.c
@ -1035,516 +1035,3 @@ struct auth authfuncs[] = {
|
|||||||
{NULL, NULL, NULL, ""}
|
{NULL, NULL, NULL, ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, NULL};
|
|
||||||
struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, NULL};
|
|
||||||
|
|
||||||
|
|
||||||
void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd){
|
|
||||||
unsigned i, j, k;
|
|
||||||
memcpy(hash, rnd, sizeof(unsigned)*4);
|
|
||||||
for(i=0, j=0, k=0; name[j]; j++){
|
|
||||||
hash[i] += (toupper(name[j]) - 32)+rnd[((toupper(name[j]))*29277+rnd[(k+j+i)%16]+k+j+i)%16];
|
|
||||||
if(++i == sizeof(unsigned)*4) {
|
|
||||||
i = 0;
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned hashindex(struct hashtable *ht, const unsigned char* hash){
|
|
||||||
unsigned t1, t2, t3, t4;
|
|
||||||
t1 = *(unsigned *)hash;
|
|
||||||
t2 = *(unsigned *)(hash + sizeof(unsigned));
|
|
||||||
t3 = *(unsigned *)(hash + (2*sizeof(unsigned)));
|
|
||||||
t4 = *(unsigned *)(hash + (3*sizeof(unsigned)));
|
|
||||||
return (t1 + (t2 * 7) + (t3 * 17) + (t4 * 29) ) % (ht->hashsize >> 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void destroyhashtable(struct hashtable *ht){
|
|
||||||
pthread_mutex_lock(&hash_mutex);
|
|
||||||
if(ht->hashtable){
|
|
||||||
myfree(ht->hashtable);
|
|
||||||
ht->hashtable = NULL;
|
|
||||||
}
|
|
||||||
if(ht->hashvalues){
|
|
||||||
myfree(ht->hashvalues);
|
|
||||||
ht->hashvalues = NULL;
|
|
||||||
}
|
|
||||||
ht->hashsize = 0;
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define hvalue(I) ((struct hashentry *)((char *)ht->hashvalues + (I)*(sizeof(struct hashentry) + ht->recsize - 4)))
|
|
||||||
int inithashtable(struct hashtable *ht, unsigned nhashsize){
|
|
||||||
unsigned i;
|
|
||||||
clock_t c;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
struct timeb tb;
|
|
||||||
|
|
||||||
ftime(&tb);
|
|
||||||
|
|
||||||
#else
|
|
||||||
struct timeval tb;
|
|
||||||
struct timezone tz;
|
|
||||||
gettimeofday(&tb, &tz);
|
|
||||||
#endif
|
|
||||||
c = clock();
|
|
||||||
|
|
||||||
if(nhashsize<4) return 1;
|
|
||||||
pthread_mutex_lock(&hash_mutex);
|
|
||||||
if(ht->hashtable){
|
|
||||||
myfree(ht->hashtable);
|
|
||||||
ht->hashtable = NULL;
|
|
||||||
}
|
|
||||||
if(ht->hashvalues){
|
|
||||||
myfree(ht->hashvalues);
|
|
||||||
ht->hashvalues = NULL;
|
|
||||||
}
|
|
||||||
ht->hashsize = 0;
|
|
||||||
if(!(ht->hashtable = myalloc((nhashsize>>2) * sizeof(struct hashentry *)))){
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
if(!(ht->hashvalues = myalloc(nhashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){
|
|
||||||
myfree(ht->hashtable);
|
|
||||||
ht->hashtable = NULL;
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
ht->hashsize = nhashsize;
|
|
||||||
ht->rnd[0] = myrand(&tb, sizeof(tb));
|
|
||||||
ht->rnd[1] = myrand(ht->hashtable, sizeof(ht->hashtable));
|
|
||||||
ht->rnd[2] = myrand(&c, sizeof(c));
|
|
||||||
ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues));
|
|
||||||
memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *));
|
|
||||||
memset(ht->hashvalues, 0, ht->hashsize * (sizeof(struct hashentry) + ht->recsize -4));
|
|
||||||
|
|
||||||
for(i = 0; i< (ht->hashsize - 1); i++) {
|
|
||||||
hvalue(i)->next = hvalue(i+1);
|
|
||||||
}
|
|
||||||
ht->hashempty = ht->hashvalues;
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires){
|
|
||||||
struct hashentry * hen, *he;
|
|
||||||
struct hashentry ** hep;
|
|
||||||
|
|
||||||
unsigned index;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&hash_mutex);
|
|
||||||
if(!ht||!value||!name||!ht->hashtable||!ht->hashempty) {
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hen = ht->hashempty;
|
|
||||||
ht->hashempty = ht->hashempty->next;
|
|
||||||
nametohash(name, hen->hash, (unsigned char *)ht->rnd);
|
|
||||||
memcpy(hen->value, value, ht->recsize);
|
|
||||||
hen->expires = expires;
|
|
||||||
hen->next = NULL;
|
|
||||||
index = hashindex(ht, hen->hash);
|
|
||||||
|
|
||||||
for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
|
|
||||||
if(he->expires < conf.time || !memcmp(hen->hash, he->hash, sizeof(he->hash))) {
|
|
||||||
(*hep) = he->next;
|
|
||||||
he->expires = 0;
|
|
||||||
he->next = ht->hashempty;
|
|
||||||
ht->hashempty = he;
|
|
||||||
}
|
|
||||||
else hep=&(he->next);
|
|
||||||
}
|
|
||||||
hen->next = ht->hashtable[index];
|
|
||||||
ht->hashtable[index] = hen;
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t hashresolv(struct hashtable *ht, const unsigned char* name, unsigned char* value, uint32_t *ttl){
|
|
||||||
unsigned char hash[sizeof(unsigned)*4];
|
|
||||||
struct hashentry ** hep;
|
|
||||||
struct hashentry *he;
|
|
||||||
unsigned index;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&hash_mutex);
|
|
||||||
if(!ht || !ht->hashtable || !name) {
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
nametohash(name, hash, (unsigned char *)ht->rnd);
|
|
||||||
index = hashindex(ht, hash);
|
|
||||||
for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
|
|
||||||
if(he->expires < conf.time) {
|
|
||||||
(*hep) = he->next;
|
|
||||||
he->expires = 0;
|
|
||||||
he->next = ht->hashempty;
|
|
||||||
ht->hashempty = he;
|
|
||||||
}
|
|
||||||
else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){
|
|
||||||
if(ttl) *ttl = (uint32_t)(he->expires - conf.time);
|
|
||||||
memcpy(value, he->value, ht->recsize);
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else hep=&(he->next);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&hash_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
|
|
||||||
struct nserver authnserver;
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_t *retttl, struct clientparam* param, int makeauth){
|
|
||||||
|
|
||||||
int i,n;
|
|
||||||
uint32_t retval;
|
|
||||||
|
|
||||||
if((af == AF_INET) && (retval = hashresolv(&dns_table, name, value, retttl))) {
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
if((af == AF_INET6) && (retval = hashresolv(&dns6_table, name, value, retttl))) {
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
n = (makeauth && !SAISNULL(&authnserver.addr))? 1 : numservers;
|
|
||||||
for(i=0; i<n; i++){
|
|
||||||
unsigned short nq, na;
|
|
||||||
unsigned char b[4098], *buf, *s1, *s2;
|
|
||||||
int j, k, len, flen;
|
|
||||||
SOCKET sock;
|
|
||||||
uint32_t ttl;
|
|
||||||
PROXYSOCKADDRTYPE addr;
|
|
||||||
PROXYSOCKADDRTYPE *sinsr, *sinsl;
|
|
||||||
int usetcp = 0;
|
|
||||||
unsigned short serial = 1;
|
|
||||||
|
|
||||||
buf = b+2;
|
|
||||||
|
|
||||||
sinsl = (param && !makeauth)? ¶m->sinsl : &addr;
|
|
||||||
sinsr = (param && !makeauth)? ¶m->sinsr : &addr;
|
|
||||||
memset(sinsl, 0, sizeof(addr));
|
|
||||||
memset(sinsr, 0, sizeof(addr));
|
|
||||||
|
|
||||||
|
|
||||||
if(makeauth && !SAISNULL(&authnserver.addr)){
|
|
||||||
usetcp = authnserver.usetcp;
|
|
||||||
*SAFAMILY(sinsl) = *SAFAMILY(&authnserver.addr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
usetcp = nservers[i].usetcp;
|
|
||||||
*SAFAMILY(sinsl) = *SAFAMILY(&nservers[i].addr);
|
|
||||||
}
|
|
||||||
if((sock=so._socket(so.state, SASOCK(sinsl), usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
|
|
||||||
if(so._bind(so.state, sock,(struct sockaddr *)sinsl,SASIZE(sinsl))){
|
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
|
||||||
so._closesocket(so.state, sock);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(makeauth && !SAISNULL(&authnserver.addr)){
|
|
||||||
*sinsr = authnserver.addr;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*sinsr = nservers[i].addr;
|
|
||||||
}
|
|
||||||
if(usetcp){
|
|
||||||
if(connectwithpoll(NULL, sock,(struct sockaddr *)sinsr,SASIZE(sinsr),conf.timeouts[CONNECT_TO])) {
|
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
|
||||||
so._closesocket(so.state, sock);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef TCP_NODELAY
|
|
||||||
{
|
|
||||||
int opt = 1;
|
|
||||||
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
len = (int)strlen((char *)name);
|
|
||||||
|
|
||||||
serial = myrand(name,len);
|
|
||||||
*(unsigned short*)buf = serial; /* query id */
|
|
||||||
buf[2] = 1; /* recursive */
|
|
||||||
buf[3] = 0;
|
|
||||||
buf[4] = 0;
|
|
||||||
buf[5] = 1; /* 1 request */
|
|
||||||
buf[6] = buf[7] = 0; /* no replies */
|
|
||||||
buf[8] = buf[9] = 0; /* no ns count */
|
|
||||||
buf[10] = buf[11] = 0; /* no additional */
|
|
||||||
if(len > 255) {
|
|
||||||
len = 255;
|
|
||||||
}
|
|
||||||
memcpy(buf + 13, name, len);
|
|
||||||
len += 13;
|
|
||||||
buf[len] = 0;
|
|
||||||
for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1);
|
|
||||||
*s2 = (len - (int)(s2 - buf)) - 1;
|
|
||||||
len++;
|
|
||||||
buf[len++] = 0;
|
|
||||||
buf[len++] = (makeauth == 1)? 0x0c : (af==AF_INET6? 0x1c:0x01); /* PTR:host address */
|
|
||||||
buf[len++] = 0;
|
|
||||||
buf[len++] = 1; /* INET */
|
|
||||||
if(usetcp){
|
|
||||||
buf-=2;
|
|
||||||
*(unsigned short*)buf = htons(len);
|
|
||||||
len+=2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(socksendto(NULL, sock, (struct sockaddr *)sinsr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
|
||||||
so._closesocket(so.state, sock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(param) param->statscli64 += len;
|
|
||||||
len = sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf, 4096, conf.timeouts[DNS_TO]*1000);
|
|
||||||
so._shutdown(so.state, sock, SHUT_RDWR);
|
|
||||||
so._closesocket(so.state, sock);
|
|
||||||
if(len <= 13) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(param) param->statssrv64 += len;
|
|
||||||
if(usetcp){
|
|
||||||
unsigned short us;
|
|
||||||
us = ntohs(*(unsigned short*)buf);
|
|
||||||
len-=2;
|
|
||||||
buf+=2;
|
|
||||||
if(us > 4096 || us < len || (us > len && sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf+len, us-len, conf.timeouts[DNS_TO]*1000) != us-len)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(*(unsigned short *)buf != serial)continue;
|
|
||||||
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
nq = buf[5] + (((unsigned short)buf[4])<<8);
|
|
||||||
if (nq != 1) {
|
|
||||||
continue; /* we did only 1 request */
|
|
||||||
}
|
|
||||||
for(k = 13; k<len && buf[k]; k++) {
|
|
||||||
}
|
|
||||||
k++;
|
|
||||||
if( (k+4) >= len) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
k += 4;
|
|
||||||
if(na > 255) na = 255; /* somebody is very evil */
|
|
||||||
for (j = 0; j < na; j++) { /* now there should be answers */
|
|
||||||
while(buf[k] < 192 && buf[k] !=0 && (k+buf[k]+14) < len) k+= (buf[k] + 1);
|
|
||||||
if(!buf[k]) k--;
|
|
||||||
if((k+(af == AF_INET6?28:16)) > len) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
flen = buf[k+11] + (((unsigned short)buf[k+10])<<8);
|
|
||||||
if((k+12+flen) > len) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(makeauth != 1){
|
|
||||||
if(buf[k+2] != 0 || buf[k+3] != (af == AF_INET6?0x1c:0x1) || flen != (af == AF_INET6?16:4)) {
|
|
||||||
k+= (12 + flen);
|
|
||||||
continue; /* we need A IPv4 */
|
|
||||||
}
|
|
||||||
ttl = ntohl(*(uint32_t *)(buf + k + 6));
|
|
||||||
memcpy(value, buf + k + 12, af == AF_INET6? 16:4);
|
|
||||||
if(ttl < 0 || ttl > (3600*12)) ttl = 3600*12;
|
|
||||||
if(!ttl) ttl = 1;
|
|
||||||
hashadd(af == AF_INET6?&dns6_table:&dns_table, name, value, conf.time+ttl);
|
|
||||||
if(retttl) *retttl = ttl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
if(buf[k+2] != 0 || buf[k+3] != 0x0c) {
|
|
||||||
k+= (12 + flen);
|
|
||||||
continue; /* we need A PTR */
|
|
||||||
}
|
|
||||||
for (s2 = buf + k + 12; s2 < (buf + k + 12 + len) && *s2; ){
|
|
||||||
s1 = s2 + ((unsigned)*s2) + 1;
|
|
||||||
*s2 = '.';
|
|
||||||
s2 = s1;
|
|
||||||
}
|
|
||||||
*s2 = 0;
|
|
||||||
if(param->username)myfree(param->username);
|
|
||||||
param->username = (unsigned char *)mystrdup ((char *)buf + k + 13);
|
|
||||||
|
|
||||||
return udpresolve(af,param->username, value, NULL, NULL, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t myresolver(int af, unsigned char * name, unsigned char * value){
|
|
||||||
return udpresolve(af, name, value, NULL, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fakeresolver (int af, unsigned char *name, unsigned char * value){
|
|
||||||
memset(value, 0, af == AF_INET6? 16 : 4);
|
|
||||||
if(af == AF_INET6){
|
|
||||||
memset(value, 0, 16);
|
|
||||||
value[15] = 2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
value[0] = 127;
|
|
||||||
value[1] = 0;
|
|
||||||
value[2] = 0;
|
|
||||||
value[3] = 2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NOODBC
|
|
||||||
|
|
||||||
SQLHENV henv = NULL;
|
|
||||||
SQLHSTMT hstmt = NULL;
|
|
||||||
SQLHDBC hdbc = NULL;
|
|
||||||
char * sqlstring = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
void close_sql(){
|
|
||||||
if(hstmt) {
|
|
||||||
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
|
||||||
hstmt = NULL;
|
|
||||||
}
|
|
||||||
if(hdbc){
|
|
||||||
SQLDisconnect(hdbc);
|
|
||||||
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
|
||||||
hdbc = NULL;
|
|
||||||
}
|
|
||||||
if(henv) {
|
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
|
||||||
henv = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int attempt = 0;
|
|
||||||
time_t attempt_time = 0;
|
|
||||||
|
|
||||||
int init_sql(char * s){
|
|
||||||
SQLRETURN retcode;
|
|
||||||
char * datasource;
|
|
||||||
char * username;
|
|
||||||
char * password;
|
|
||||||
char * string;
|
|
||||||
|
|
||||||
if(!s) return 0;
|
|
||||||
if(!sqlstring || strcmp(sqlstring, s)){
|
|
||||||
string = sqlstring;
|
|
||||||
sqlstring=mystrdup(s);
|
|
||||||
if(string)myfree(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hstmt || hdbc || henv) close_sql();
|
|
||||||
attempt++;
|
|
||||||
attempt_time = time(0);
|
|
||||||
if(!henv){
|
|
||||||
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
|
||||||
if (!henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
|
|
||||||
henv = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
|
|
||||||
|
|
||||||
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!hdbc){
|
|
||||||
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
|
||||||
if (!hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
|
|
||||||
hdbc = NULL;
|
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
|
||||||
henv = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
|
|
||||||
}
|
|
||||||
string = mystrdup(sqlstring);
|
|
||||||
if(!string) return 0;
|
|
||||||
datasource = strtok(string, ",");
|
|
||||||
username = strtok(NULL, ",");
|
|
||||||
password = strtok(NULL, ",");
|
|
||||||
|
|
||||||
|
|
||||||
/* Connect to data source */
|
|
||||||
retcode = SQLConnect(hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
|
|
||||||
(SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
|
|
||||||
(SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
|
|
||||||
|
|
||||||
myfree(string);
|
|
||||||
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
|
|
||||||
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
|
||||||
hdbc = NULL;
|
|
||||||
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
|
||||||
henv = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
|
||||||
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
|
|
||||||
close_sql();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sqlerr (char *buf){
|
|
||||||
if(conf.stdlog){
|
|
||||||
fprintf(conf.stdlog, "%s\n", buf);
|
|
||||||
fflush(conf.stdlog);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&log_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char statbuf[8192];
|
|
||||||
|
|
||||||
void logsql(struct clientparam * param, const unsigned char *s) {
|
|
||||||
SQLRETURN ret;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
|
|
||||||
if(param->nolog) return;
|
|
||||||
pthread_mutex_lock(&log_mutex);
|
|
||||||
len = dobuf(param, statbuf, s, (unsigned char *)"\'");
|
|
||||||
|
|
||||||
if(attempt > 5){
|
|
||||||
time_t t;
|
|
||||||
|
|
||||||
t = time(0);
|
|
||||||
if (t - attempt_time < 180){
|
|
||||||
sqlerr((char *)statbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!hstmt){
|
|
||||||
if(!init_sql(sqlstring)) {
|
|
||||||
sqlerr((char *)statbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(hstmt){
|
|
||||||
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
|
|
||||||
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
|
|
||||||
close_sql();
|
|
||||||
if(!init_sql(sqlstring)){
|
|
||||||
sqlerr((char *)statbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(hstmt) {
|
|
||||||
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
|
|
||||||
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
|
|
||||||
sqlerr((char *)statbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
attempt = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attempt = 0;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&log_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
146
src/hash.c
Normal file
146
src/hash.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include "proxy.h"
|
||||||
|
|
||||||
|
|
||||||
|
unsigned hashindex(struct hashtable *ht, const unsigned char* hash){
|
||||||
|
unsigned t1, t2, t3, t4;
|
||||||
|
t1 = *(unsigned *)hash;
|
||||||
|
t2 = *(unsigned *)(hash + sizeof(unsigned));
|
||||||
|
t3 = *(unsigned *)(hash + (2*sizeof(unsigned)));
|
||||||
|
t4 = *(unsigned *)(hash + (3*sizeof(unsigned)));
|
||||||
|
return (t1 + (t2 * 7) + (t3 * 17) + (t4 * 29) ) % (ht->hashsize >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void destroyhashtable(struct hashtable *ht){
|
||||||
|
pthread_mutex_lock(&hash_mutex);
|
||||||
|
if(ht->hashtable){
|
||||||
|
myfree(ht->hashtable);
|
||||||
|
ht->hashtable = NULL;
|
||||||
|
}
|
||||||
|
if(ht->hashvalues){
|
||||||
|
myfree(ht->hashvalues);
|
||||||
|
ht->hashvalues = NULL;
|
||||||
|
}
|
||||||
|
ht->hashsize = 0;
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define hvalue(I) ((struct hashentry *)((char *)ht->hashvalues + (I)*(sizeof(struct hashentry) + ht->recsize - 4)))
|
||||||
|
int inithashtable(struct hashtable *ht, unsigned nhashsize){
|
||||||
|
unsigned i;
|
||||||
|
clock_t c;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
struct timeb tb;
|
||||||
|
|
||||||
|
ftime(&tb);
|
||||||
|
|
||||||
|
#else
|
||||||
|
struct timeval tb;
|
||||||
|
struct timezone tz;
|
||||||
|
gettimeofday(&tb, &tz);
|
||||||
|
#endif
|
||||||
|
c = clock();
|
||||||
|
|
||||||
|
if(nhashsize<4) return 1;
|
||||||
|
pthread_mutex_lock(&hash_mutex);
|
||||||
|
if(ht->hashtable){
|
||||||
|
myfree(ht->hashtable);
|
||||||
|
ht->hashtable = NULL;
|
||||||
|
}
|
||||||
|
if(ht->hashvalues){
|
||||||
|
myfree(ht->hashvalues);
|
||||||
|
ht->hashvalues = NULL;
|
||||||
|
}
|
||||||
|
ht->hashsize = 0;
|
||||||
|
if(!(ht->hashtable = myalloc((nhashsize>>2) * sizeof(struct hashentry *)))){
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if(!(ht->hashvalues = myalloc(nhashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){
|
||||||
|
myfree(ht->hashtable);
|
||||||
|
ht->hashtable = NULL;
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
ht->hashsize = nhashsize;
|
||||||
|
ht->rnd[0] = myrand(&tb, sizeof(tb));
|
||||||
|
ht->rnd[1] = myrand(ht->hashtable, sizeof(ht->hashtable));
|
||||||
|
ht->rnd[2] = myrand(&c, sizeof(c));
|
||||||
|
ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues));
|
||||||
|
memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *));
|
||||||
|
memset(ht->hashvalues, 0, ht->hashsize * (sizeof(struct hashentry) + ht->recsize -4));
|
||||||
|
|
||||||
|
for(i = 0; i< (ht->hashsize - 1); i++) {
|
||||||
|
hvalue(i)->next = hvalue(i+1);
|
||||||
|
}
|
||||||
|
ht->hashempty = ht->hashvalues;
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires){
|
||||||
|
struct hashentry * hen, *he;
|
||||||
|
struct hashentry ** hep;
|
||||||
|
|
||||||
|
unsigned index;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&hash_mutex);
|
||||||
|
if(!ht||!value||!name||!ht->hashtable||!ht->hashempty) {
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hen = ht->hashempty;
|
||||||
|
ht->hashempty = ht->hashempty->next;
|
||||||
|
ht->index2hash(name, hen->hash, (unsigned char *)ht->rnd);
|
||||||
|
memcpy(hen->value, value, ht->recsize);
|
||||||
|
hen->expires = expires;
|
||||||
|
hen->next = NULL;
|
||||||
|
index = hashindex(ht, hen->hash);
|
||||||
|
|
||||||
|
for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
|
||||||
|
if(he->expires < conf.time || !memcmp(hen->hash, he->hash, sizeof(he->hash))) {
|
||||||
|
(*hep) = he->next;
|
||||||
|
he->expires = 0;
|
||||||
|
he->next = ht->hashempty;
|
||||||
|
ht->hashempty = he;
|
||||||
|
}
|
||||||
|
else hep=&(he->next);
|
||||||
|
}
|
||||||
|
hen->next = ht->hashtable[index];
|
||||||
|
ht->hashtable[index] = hen;
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl){
|
||||||
|
unsigned char hash[sizeof(unsigned)*4];
|
||||||
|
struct hashentry ** hep;
|
||||||
|
struct hashentry *he;
|
||||||
|
unsigned index;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&hash_mutex);
|
||||||
|
if(!ht || !ht->hashtable || !name) {
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ht->index2hash(name, hash, (unsigned char *)ht->rnd);
|
||||||
|
index = hashindex(ht, hash);
|
||||||
|
for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
|
||||||
|
if(he->expires < conf.time) {
|
||||||
|
(*hep) = he->next;
|
||||||
|
he->expires = 0;
|
||||||
|
he->next = ht->hashempty;
|
||||||
|
ht->hashempty = he;
|
||||||
|
}
|
||||||
|
else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){
|
||||||
|
if(ttl) *ttl = (uint32_t)(he->expires - conf.time);
|
||||||
|
memcpy(value, he->value, ht->recsize);
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else hep=&(he->next);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&hash_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -11,8 +11,6 @@
|
|||||||
unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nbytesout);
|
unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nbytesout);
|
||||||
void trafcountfunc(struct clientparam *param);
|
void trafcountfunc(struct clientparam *param);
|
||||||
int checkACL(struct clientparam * param);
|
int checkACL(struct clientparam * param);
|
||||||
void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd);
|
|
||||||
unsigned hashindex(struct hashtable *ht, const unsigned char* hash);
|
|
||||||
void decodeurl(unsigned char *s, int allowcr);
|
void decodeurl(unsigned char *s, int allowcr);
|
||||||
int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize);
|
int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize);
|
||||||
struct ace * make_ace (int argc, unsigned char ** argv);
|
struct ace * make_ace (int argc, unsigned char ** argv);
|
||||||
@ -45,38 +43,36 @@ struct symbol symbols[] = {
|
|||||||
{symbols+18, "ipauth", (void *) ipauth},
|
{symbols+18, "ipauth", (void *) ipauth},
|
||||||
{symbols+19, "strongauth", (void *) strongauth},
|
{symbols+19, "strongauth", (void *) strongauth},
|
||||||
{symbols+20, "checkACL", (void *) checkACL},
|
{symbols+20, "checkACL", (void *) checkACL},
|
||||||
{symbols+21, "nametohash", (void *) nametohash},
|
{symbols+21, "nservers", (void *) nservers},
|
||||||
{symbols+22, "hashindex", (void *) hashindex},
|
{symbols+22, "udpresolve", (void *) udpresolve},
|
||||||
{symbols+23, "nservers", (void *) nservers},
|
{symbols+23, "bandlim_mutex", (void *) &bandlim_mutex},
|
||||||
{symbols+24, "udpresolve", (void *) udpresolve},
|
{symbols+24, "tc_mutex", (void *) &tc_mutex},
|
||||||
{symbols+25, "bandlim_mutex", (void *) &bandlim_mutex},
|
{symbols+25, "hash_mutex", (void *) &hash_mutex},
|
||||||
{symbols+26, "tc_mutex", (void *) &tc_mutex},
|
{symbols+26, "pwl_mutex", (void *) &pwl_mutex},
|
||||||
{symbols+27, "hash_mutex", (void *) &hash_mutex},
|
{symbols+27, "linenum", (void *) &linenum},
|
||||||
{symbols+28, "pwl_mutex", (void *) &pwl_mutex},
|
{symbols+28, "proxy_stringtable", (void *) proxy_stringtable},
|
||||||
{symbols+29, "linenum", (void *) &linenum},
|
{symbols+29, "en64", (void *) en64},
|
||||||
{symbols+30, "proxy_stringtable", (void *) proxy_stringtable},
|
{symbols+30, "de64", (void *) de64},
|
||||||
{symbols+31, "en64", (void *) en64},
|
{symbols+31, "tohex", (void *) tohex},
|
||||||
{symbols+32, "de64", (void *) de64},
|
{symbols+32, "fromhex", (void *) fromhex},
|
||||||
{symbols+33, "tohex", (void *) tohex},
|
{symbols+33, "dnspr", (void *) dnsprchild},
|
||||||
{symbols+34, "fromhex", (void *) fromhex},
|
{symbols+34, "pop3p", (void *) pop3pchild},
|
||||||
{symbols+35, "dnspr", (void *) dnsprchild},
|
{symbols+35, "proxy", (void *) proxychild},
|
||||||
{symbols+36, "pop3p", (void *) pop3pchild},
|
{symbols+36, "socks", (void *) sockschild},
|
||||||
{symbols+37, "proxy", (void *) proxychild},
|
{symbols+37, "tcppm", (void *) tcppmchild},
|
||||||
{symbols+38, "socks", (void *) sockschild},
|
{symbols+38, "udppm", (void *) udppmchild},
|
||||||
{symbols+39, "tcppm", (void *) tcppmchild},
|
{symbols+39, "admin", (void *) adminchild},
|
||||||
{symbols+40, "udppm", (void *) udppmchild},
|
{symbols+40, "ftppr", (void *) ftpprchild},
|
||||||
{symbols+41, "admin", (void *) adminchild},
|
{symbols+41, "smtpp", (void *) smtppchild},
|
||||||
{symbols+42, "ftppr", (void *) ftpprchild},
|
{symbols+42, "auto", (void *) smtppchild},
|
||||||
{symbols+43, "smtpp", (void *) smtppchild},
|
{symbols+43, "tlspr", (void *) smtppchild},
|
||||||
{symbols+44, "auto", (void *) smtppchild},
|
{symbols+44, "authfuncs", (void *) &authfuncs},
|
||||||
{symbols+45, "tlspr", (void *) smtppchild},
|
{symbols+45, "commandhandlers", (void *) &commandhandlers},
|
||||||
{symbols+46, "authfuncs", (void *) &authfuncs},
|
{symbols+46, "decodeurl", (void *) decodeurl},
|
||||||
{symbols+47, "commandhandlers", (void *) &commandhandlers},
|
{symbols+47, "parsestr", (void *) parsestr},
|
||||||
{symbols+48, "decodeurl", (void *) decodeurl},
|
{symbols+48, "make_ace", (void *) make_ace},
|
||||||
{symbols+49, "parsestr", (void *) parsestr},
|
{symbols+49, "freeacl", (void *) freeacl},
|
||||||
{symbols+50, "make_ace", (void *) make_ace},
|
{symbols+50, "handleredirect", (void *) handleredirect},
|
||||||
{symbols+51, "freeacl", (void *) freeacl},
|
|
||||||
{symbols+52, "handleredirect", (void *) handleredirect},
|
|
||||||
{NULL, "", NULL}
|
{NULL, "", NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -111,8 +107,6 @@ struct pluginlink pluginlink = {
|
|||||||
ACLmatches,
|
ACLmatches,
|
||||||
alwaysauth,
|
alwaysauth,
|
||||||
checkACL,
|
checkACL,
|
||||||
nametohash,
|
|
||||||
hashindex,
|
|
||||||
en64,
|
en64,
|
||||||
de64,
|
de64,
|
||||||
tohex,
|
tohex,
|
||||||
|
|||||||
@ -245,7 +245,11 @@ void mschap(const unsigned char *win_password,
|
|||||||
const unsigned char *challenge, unsigned char *response);
|
const unsigned char *challenge, unsigned char *response);
|
||||||
|
|
||||||
struct hashtable;
|
struct hashtable;
|
||||||
void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires);
|
unsigned hashindex(struct hashtable *ht, const unsigned char* hash);
|
||||||
|
void destroyhashtable(struct hashtable *ht);
|
||||||
|
int inithashtable(struct hashtable *ht, unsigned nhashsize);
|
||||||
|
void hashadd(struct hashtable *ht, const void* name, const void* value, time_t expires);
|
||||||
|
int hashresolv(struct hashtable *ht, const void* name, void* value, uint32_t *ttl);
|
||||||
|
|
||||||
int parsehost(int family, unsigned char *host, struct sockaddr *sa);
|
int parsehost(int family, unsigned char *host, struct sockaddr *sa);
|
||||||
int parsehostname(char *hostname, struct clientparam *param, uint16_t port);
|
int parsehostname(char *hostname, struct clientparam *param, uint16_t port);
|
||||||
|
|||||||
217
src/resolve.c
Normal file
217
src/resolve.c
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
#include "proxy.h"
|
||||||
|
|
||||||
|
void char_index2hash(const void *index, unsigned char *hash, const unsigned char *rnd){
|
||||||
|
const char* name = index;
|
||||||
|
unsigned i, j, k;
|
||||||
|
memcpy(hash, rnd, sizeof(unsigned)*4);
|
||||||
|
for(i=0, j=0, k=0; name[j]; j++){
|
||||||
|
hash[i] += (toupper(name[j]) - 32)+rnd[((toupper(name[j]))*29277+rnd[(k+j+i)%16]+k+j+i)%16];
|
||||||
|
if(++i == sizeof(unsigned)*4) {
|
||||||
|
i = 0;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, NULL, char_index2hash};
|
||||||
|
struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, NULL, char_index2hash};
|
||||||
|
|
||||||
|
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
|
||||||
|
struct nserver authnserver;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_t *retttl, struct clientparam* param, int makeauth){
|
||||||
|
|
||||||
|
int i,n;
|
||||||
|
uint32_t retval;
|
||||||
|
|
||||||
|
if((af == AF_INET) && (retval = hashresolv(&dns_table, name, value, retttl))) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
if((af == AF_INET6) && (retval = hashresolv(&dns6_table, name, value, retttl))) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
n = (makeauth && !SAISNULL(&authnserver.addr))? 1 : numservers;
|
||||||
|
for(i=0; i<n; i++){
|
||||||
|
unsigned short nq, na;
|
||||||
|
unsigned char b[4098], *buf, *s1, *s2;
|
||||||
|
int j, k, len, flen;
|
||||||
|
SOCKET sock;
|
||||||
|
uint32_t ttl;
|
||||||
|
PROXYSOCKADDRTYPE addr;
|
||||||
|
PROXYSOCKADDRTYPE *sinsr, *sinsl;
|
||||||
|
int usetcp = 0;
|
||||||
|
unsigned short serial = 1;
|
||||||
|
|
||||||
|
buf = b+2;
|
||||||
|
|
||||||
|
sinsl = (param && !makeauth)? ¶m->sinsl : &addr;
|
||||||
|
sinsr = (param && !makeauth)? ¶m->sinsr : &addr;
|
||||||
|
memset(sinsl, 0, sizeof(addr));
|
||||||
|
memset(sinsr, 0, sizeof(addr));
|
||||||
|
|
||||||
|
|
||||||
|
if(makeauth && !SAISNULL(&authnserver.addr)){
|
||||||
|
usetcp = authnserver.usetcp;
|
||||||
|
*SAFAMILY(sinsl) = *SAFAMILY(&authnserver.addr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
usetcp = nservers[i].usetcp;
|
||||||
|
*SAFAMILY(sinsl) = *SAFAMILY(&nservers[i].addr);
|
||||||
|
}
|
||||||
|
if((sock=so._socket(so.state, SASOCK(sinsl), usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
|
||||||
|
if(so._bind(so.state, sock,(struct sockaddr *)sinsl,SASIZE(sinsl))){
|
||||||
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
|
so._closesocket(so.state, sock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(makeauth && !SAISNULL(&authnserver.addr)){
|
||||||
|
*sinsr = authnserver.addr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*sinsr = nservers[i].addr;
|
||||||
|
}
|
||||||
|
if(usetcp){
|
||||||
|
if(connectwithpoll(NULL, sock,(struct sockaddr *)sinsr,SASIZE(sinsr),conf.timeouts[CONNECT_TO])) {
|
||||||
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
|
so._closesocket(so.state, sock);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef TCP_NODELAY
|
||||||
|
{
|
||||||
|
int opt = 1;
|
||||||
|
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
len = (int)strlen((char *)name);
|
||||||
|
|
||||||
|
serial = myrand(name,len);
|
||||||
|
*(unsigned short*)buf = serial; /* query id */
|
||||||
|
buf[2] = 1; /* recursive */
|
||||||
|
buf[3] = 0;
|
||||||
|
buf[4] = 0;
|
||||||
|
buf[5] = 1; /* 1 request */
|
||||||
|
buf[6] = buf[7] = 0; /* no replies */
|
||||||
|
buf[8] = buf[9] = 0; /* no ns count */
|
||||||
|
buf[10] = buf[11] = 0; /* no additional */
|
||||||
|
if(len > 255) {
|
||||||
|
len = 255;
|
||||||
|
}
|
||||||
|
memcpy(buf + 13, name, len);
|
||||||
|
len += 13;
|
||||||
|
buf[len] = 0;
|
||||||
|
for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1);
|
||||||
|
*s2 = (len - (int)(s2 - buf)) - 1;
|
||||||
|
len++;
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = (makeauth == 1)? 0x0c : (af==AF_INET6? 0x1c:0x01);/* PTR:host address */
|
||||||
|
buf[len++] = 0;
|
||||||
|
buf[len++] = 1; /* INET */
|
||||||
|
if(usetcp){
|
||||||
|
buf-=2;
|
||||||
|
*(unsigned short*)buf = htons(len);
|
||||||
|
len+=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(socksendto(NULL, sock, (struct sockaddr *)sinsr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
||||||
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
|
so._closesocket(so.state, sock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(param) param->statscli64 += len;
|
||||||
|
len = sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf, 4096, conf.timeouts[DNS_TO]*1000);
|
||||||
|
so._shutdown(so.state, sock, SHUT_RDWR);
|
||||||
|
so._closesocket(so.state, sock);
|
||||||
|
if(len <= 13) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(param) param->statssrv64 += len;
|
||||||
|
if(usetcp){
|
||||||
|
unsigned short us;
|
||||||
|
us = ntohs(*(unsigned short*)buf);
|
||||||
|
len-=2;
|
||||||
|
buf+=2;
|
||||||
|
if(us > 4096 || us < len || (us > len && sockrecvfrom(NULL, sock, (struct sockaddr *)sinsr, buf+len, us-len, conf.timeouts[DNS_TO]*1000) != us-len)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(*(unsigned short *)buf != serial)continue;
|
||||||
|
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
nq = buf[5] + (((unsigned short)buf[4])<<8);
|
||||||
|
if (nq != 1) {
|
||||||
|
continue; /* we did only 1 request */
|
||||||
|
}
|
||||||
|
for(k = 13; k<len && buf[k]; k++) {
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
if( (k+4) >= len) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
k += 4;
|
||||||
|
if(na > 255) na = 255; /* somebody is very evil */
|
||||||
|
for (j = 0; j < na; j++) { /* now there should be answers */
|
||||||
|
while(buf[k] < 192 && buf[k] !=0 && (k+buf[k]+14) < len) k+= (buf[k] + 1);
|
||||||
|
if(!buf[k]) k--;
|
||||||
|
if((k+(af == AF_INET6?28:16)) > len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
flen = buf[k+11] + (((unsigned short)buf[k+10])<<8);
|
||||||
|
if((k+12+flen) > len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(makeauth != 1){
|
||||||
|
if(buf[k+2] != 0 || buf[k+3] != (af == AF_INET6?0x1c:0x1) || flen != (af == AF_INET6?16:4)) {
|
||||||
|
k+= (12 + flen);
|
||||||
|
continue; /* we need A IPv4 */
|
||||||
|
}
|
||||||
|
ttl = ntohl(*(uint32_t *)(buf + k + 6));
|
||||||
|
memcpy(value, buf + k + 12, af == AF_INET6? 16:4);
|
||||||
|
if(ttl < 0 || ttl > (3600*12)) ttl = 3600*12;
|
||||||
|
if(!ttl) ttl = 1;
|
||||||
|
hashadd(af == AF_INET6?&dns6_table:&dns_table, name, value, conf.time+ttl);
|
||||||
|
if(retttl) *retttl = ttl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if(buf[k+2] != 0 || buf[k+3] != 0x0c) {
|
||||||
|
k+= (12 + flen);
|
||||||
|
continue; /* we need A PTR */
|
||||||
|
}
|
||||||
|
for (s2 = buf + k + 12; s2 < (buf + k + 12 + len) && *s2; ){
|
||||||
|
s1 = s2 + ((unsigned)*s2) + 1;
|
||||||
|
*s2 = '.';
|
||||||
|
s2 = s1;
|
||||||
|
}
|
||||||
|
*s2 = 0;
|
||||||
|
if(param->username)myfree(param->username);
|
||||||
|
param->username = (unsigned char *)mystrdup ((char *)buf + k + 13);
|
||||||
|
|
||||||
|
return udpresolve(af,param->username, value, NULL, NULL, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t myresolver(int af, unsigned char * name, unsigned char * value){
|
||||||
|
return udpresolve(af, name, value, NULL, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fakeresolver (int af, unsigned char *name, unsigned char * value){
|
||||||
|
memset(value, 0, af == AF_INET6? 16 : 4);
|
||||||
|
if(af == AF_INET6){
|
||||||
|
memset(value, 0, 16);
|
||||||
|
value[15] = 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value[0] = 127;
|
||||||
|
value[1] = 0;
|
||||||
|
value[2] = 0;
|
||||||
|
value[3] = 2;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
152
src/sql.c
Normal file
152
src/sql.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include "proxy.h"
|
||||||
|
#ifndef NOODBC
|
||||||
|
|
||||||
|
SQLHENV henv = NULL;
|
||||||
|
SQLHSTMT hstmt = NULL;
|
||||||
|
SQLHDBC hdbc = NULL;
|
||||||
|
char * sqlstring = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
void close_sql(){
|
||||||
|
if(hstmt) {
|
||||||
|
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
|
||||||
|
hstmt = NULL;
|
||||||
|
}
|
||||||
|
if(hdbc){
|
||||||
|
SQLDisconnect(hdbc);
|
||||||
|
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||||
|
hdbc = NULL;
|
||||||
|
}
|
||||||
|
if(henv) {
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||||
|
henv = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int attempt = 0;
|
||||||
|
time_t attempt_time = 0;
|
||||||
|
|
||||||
|
int init_sql(char * s){
|
||||||
|
SQLRETURN retcode;
|
||||||
|
char * datasource;
|
||||||
|
char * username;
|
||||||
|
char * password;
|
||||||
|
char * string;
|
||||||
|
|
||||||
|
if(!s) return 0;
|
||||||
|
if(!sqlstring || strcmp(sqlstring, s)){
|
||||||
|
string = sqlstring;
|
||||||
|
sqlstring=mystrdup(s);
|
||||||
|
if(string)myfree(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hstmt || hdbc || henv) close_sql();
|
||||||
|
attempt++;
|
||||||
|
attempt_time = time(0);
|
||||||
|
if(!henv){
|
||||||
|
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
|
||||||
|
if (!henv || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)){
|
||||||
|
henv = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
|
||||||
|
|
||||||
|
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!hdbc){
|
||||||
|
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
|
||||||
|
if (!hdbc || (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)) {
|
||||||
|
hdbc = NULL;
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||||
|
henv = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (void*)15, 0);
|
||||||
|
}
|
||||||
|
string = mystrdup(sqlstring);
|
||||||
|
if(!string) return 0;
|
||||||
|
datasource = strtok(string, ",");
|
||||||
|
username = strtok(NULL, ",");
|
||||||
|
password = strtok(NULL, ",");
|
||||||
|
|
||||||
|
|
||||||
|
/* Connect to data source */
|
||||||
|
retcode = SQLConnect(hdbc, (SQLCHAR*) datasource, (SQLSMALLINT)strlen(datasource),
|
||||||
|
(SQLCHAR*) username, (SQLSMALLINT)((username)?strlen(username):0),
|
||||||
|
(SQLCHAR*) password, (SQLSMALLINT)((password)?strlen(password):0));
|
||||||
|
|
||||||
|
myfree(string);
|
||||||
|
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
|
||||||
|
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
|
||||||
|
hdbc = NULL;
|
||||||
|
SQLFreeHandle(SQL_HANDLE_ENV, henv);
|
||||||
|
henv = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
|
||||||
|
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO){
|
||||||
|
close_sql();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sqlerr (char *buf){
|
||||||
|
if(conf.stdlog){
|
||||||
|
fprintf(conf.stdlog, "%s\n", buf);
|
||||||
|
fflush(conf.stdlog);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&log_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char statbuf[8192];
|
||||||
|
|
||||||
|
void logsql(struct clientparam * param, const unsigned char *s) {
|
||||||
|
SQLRETURN ret;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
|
||||||
|
if(param->nolog) return;
|
||||||
|
pthread_mutex_lock(&log_mutex);
|
||||||
|
len = dobuf(param, statbuf, s, (unsigned char *)"\'");
|
||||||
|
|
||||||
|
if(attempt > 5){
|
||||||
|
time_t t;
|
||||||
|
|
||||||
|
t = time(0);
|
||||||
|
if (t - attempt_time < 180){
|
||||||
|
sqlerr((char *)statbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!hstmt){
|
||||||
|
if(!init_sql(sqlstring)) {
|
||||||
|
sqlerr((char *)statbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hstmt){
|
||||||
|
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
|
||||||
|
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
|
||||||
|
close_sql();
|
||||||
|
if(!init_sql(sqlstring)){
|
||||||
|
sqlerr((char *)statbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(hstmt) {
|
||||||
|
ret = SQLExecDirect(hstmt, (SQLCHAR *)statbuf, (SQLINTEGER)len);
|
||||||
|
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
|
||||||
|
sqlerr((char *)statbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
attempt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attempt = 0;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&log_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -768,6 +768,8 @@ struct hashtable {
|
|||||||
struct hashentry ** hashtable;
|
struct hashentry ** hashtable;
|
||||||
void * hashvalues;
|
void * hashvalues;
|
||||||
struct hashentry * hashempty;
|
struct hashentry * hashempty;
|
||||||
|
void (*index2hash)(const void *index, unsigned char *hash, const unsigned char *rnd);
|
||||||
|
int grow;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct hashtable dns_table;
|
extern struct hashtable dns_table;
|
||||||
@ -795,8 +797,6 @@ struct pluginlink {
|
|||||||
int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
|
int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
|
||||||
int (*alwaysauth)(struct clientparam * param);
|
int (*alwaysauth)(struct clientparam * param);
|
||||||
int (*checkACL)(struct clientparam * param);
|
int (*checkACL)(struct clientparam * param);
|
||||||
void (*nametohash)(const unsigned char * name, unsigned char *hash, unsigned char *rnd);
|
|
||||||
unsigned (*hashindex)(struct hashtable *ht, const unsigned char* hash);
|
|
||||||
unsigned char* (*en64)(const unsigned char *in, unsigned char *out, int inlen);
|
unsigned char* (*en64)(const unsigned char *in, unsigned char *out, int inlen);
|
||||||
int (*de64)(const unsigned char *in, unsigned char *out, int maxlen);
|
int (*de64)(const unsigned char *in, unsigned char *out, int maxlen);
|
||||||
void (*tohex)(unsigned char *in, unsigned char *out, int len);
|
void (*tohex)(unsigned char *in, unsigned char *out, int len);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user