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/auth.c
|
||||
src/authradius.c
|
||||
src/hash.c
|
||||
src/resolve.c
|
||||
src/sql.c
|
||||
src/conf.c
|
||||
src/datatypes.c
|
||||
src/plugins.c
|
||||
|
||||
@ -119,6 +119,9 @@ srvdnspr$(OBJSUFFICS): dnspr.c proxy.h structures.h
|
||||
auth$(OBJSUFFICS): auth.c proxy.h structures.h
|
||||
$(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
|
||||
$(CC) $(COUT)authradius$(OBJSUFFICS) $(CFLAGS) authradius.c
|
||||
|
||||
@ -150,6 +153,6 @@ md5$(OBJSUFFICS): libs/md5.h libs/md5.c
|
||||
stringtable$(OBJSUFFICS): 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)
|
||||
$(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)
|
||||
$(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) 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, ""}
|
||||
};
|
||||
|
||||
|
||||
|
||||
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);
|
||||
void trafcountfunc(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);
|
||||
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);
|
||||
@ -45,38 +43,36 @@ struct symbol symbols[] = {
|
||||
{symbols+18, "ipauth", (void *) ipauth},
|
||||
{symbols+19, "strongauth", (void *) strongauth},
|
||||
{symbols+20, "checkACL", (void *) checkACL},
|
||||
{symbols+21, "nametohash", (void *) nametohash},
|
||||
{symbols+22, "hashindex", (void *) hashindex},
|
||||
{symbols+23, "nservers", (void *) nservers},
|
||||
{symbols+24, "udpresolve", (void *) udpresolve},
|
||||
{symbols+25, "bandlim_mutex", (void *) &bandlim_mutex},
|
||||
{symbols+26, "tc_mutex", (void *) &tc_mutex},
|
||||
{symbols+27, "hash_mutex", (void *) &hash_mutex},
|
||||
{symbols+28, "pwl_mutex", (void *) &pwl_mutex},
|
||||
{symbols+29, "linenum", (void *) &linenum},
|
||||
{symbols+30, "proxy_stringtable", (void *) proxy_stringtable},
|
||||
{symbols+31, "en64", (void *) en64},
|
||||
{symbols+32, "de64", (void *) de64},
|
||||
{symbols+33, "tohex", (void *) tohex},
|
||||
{symbols+34, "fromhex", (void *) fromhex},
|
||||
{symbols+35, "dnspr", (void *) dnsprchild},
|
||||
{symbols+36, "pop3p", (void *) pop3pchild},
|
||||
{symbols+37, "proxy", (void *) proxychild},
|
||||
{symbols+38, "socks", (void *) sockschild},
|
||||
{symbols+39, "tcppm", (void *) tcppmchild},
|
||||
{symbols+40, "udppm", (void *) udppmchild},
|
||||
{symbols+41, "admin", (void *) adminchild},
|
||||
{symbols+42, "ftppr", (void *) ftpprchild},
|
||||
{symbols+43, "smtpp", (void *) smtppchild},
|
||||
{symbols+44, "auto", (void *) smtppchild},
|
||||
{symbols+45, "tlspr", (void *) smtppchild},
|
||||
{symbols+46, "authfuncs", (void *) &authfuncs},
|
||||
{symbols+47, "commandhandlers", (void *) &commandhandlers},
|
||||
{symbols+48, "decodeurl", (void *) decodeurl},
|
||||
{symbols+49, "parsestr", (void *) parsestr},
|
||||
{symbols+50, "make_ace", (void *) make_ace},
|
||||
{symbols+51, "freeacl", (void *) freeacl},
|
||||
{symbols+52, "handleredirect", (void *) handleredirect},
|
||||
{symbols+21, "nservers", (void *) nservers},
|
||||
{symbols+22, "udpresolve", (void *) udpresolve},
|
||||
{symbols+23, "bandlim_mutex", (void *) &bandlim_mutex},
|
||||
{symbols+24, "tc_mutex", (void *) &tc_mutex},
|
||||
{symbols+25, "hash_mutex", (void *) &hash_mutex},
|
||||
{symbols+26, "pwl_mutex", (void *) &pwl_mutex},
|
||||
{symbols+27, "linenum", (void *) &linenum},
|
||||
{symbols+28, "proxy_stringtable", (void *) proxy_stringtable},
|
||||
{symbols+29, "en64", (void *) en64},
|
||||
{symbols+30, "de64", (void *) de64},
|
||||
{symbols+31, "tohex", (void *) tohex},
|
||||
{symbols+32, "fromhex", (void *) fromhex},
|
||||
{symbols+33, "dnspr", (void *) dnsprchild},
|
||||
{symbols+34, "pop3p", (void *) pop3pchild},
|
||||
{symbols+35, "proxy", (void *) proxychild},
|
||||
{symbols+36, "socks", (void *) sockschild},
|
||||
{symbols+37, "tcppm", (void *) tcppmchild},
|
||||
{symbols+38, "udppm", (void *) udppmchild},
|
||||
{symbols+39, "admin", (void *) adminchild},
|
||||
{symbols+40, "ftppr", (void *) ftpprchild},
|
||||
{symbols+41, "smtpp", (void *) smtppchild},
|
||||
{symbols+42, "auto", (void *) smtppchild},
|
||||
{symbols+43, "tlspr", (void *) smtppchild},
|
||||
{symbols+44, "authfuncs", (void *) &authfuncs},
|
||||
{symbols+45, "commandhandlers", (void *) &commandhandlers},
|
||||
{symbols+46, "decodeurl", (void *) decodeurl},
|
||||
{symbols+47, "parsestr", (void *) parsestr},
|
||||
{symbols+48, "make_ace", (void *) make_ace},
|
||||
{symbols+49, "freeacl", (void *) freeacl},
|
||||
{symbols+50, "handleredirect", (void *) handleredirect},
|
||||
{NULL, "", NULL}
|
||||
};
|
||||
|
||||
@ -111,8 +107,6 @@ struct pluginlink pluginlink = {
|
||||
ACLmatches,
|
||||
alwaysauth,
|
||||
checkACL,
|
||||
nametohash,
|
||||
hashindex,
|
||||
en64,
|
||||
de64,
|
||||
tohex,
|
||||
|
||||
@ -245,7 +245,11 @@ void mschap(const unsigned char *win_password,
|
||||
const unsigned char *challenge, unsigned char *response);
|
||||
|
||||
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 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;
|
||||
void * hashvalues;
|
||||
struct hashentry * hashempty;
|
||||
void (*index2hash)(const void *index, unsigned char *hash, const unsigned char *rnd);
|
||||
int grow;
|
||||
};
|
||||
|
||||
extern struct hashtable dns_table;
|
||||
@ -795,8 +797,6 @@ struct pluginlink {
|
||||
int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
|
||||
int (*alwaysauth)(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);
|
||||
int (*de64)(const unsigned char *in, unsigned char *out, int maxlen);
|
||||
void (*tohex)(unsigned char *in, unsigned char *out, int len);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user