From: Vlad S. <ser...@us...> - 2005-06-21 03:36:49
|
Update of /cvsroot/naviserver/modules/nsdns In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11692 Modified Files: ChangeLog dns.c dns.h nsdns.c Log Message: re-structured for multiple clients Index: nsdns.c =================================================================== RCS file: /cvsroot/naviserver/modules/nsdns/nsdns.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** nsdns.c 18 Jun 2005 22:02:04 -0000 1.6 --- nsdns.c 21 Jun 2005 03:36:40 -0000 1.7 *************** *** 28,31 **** --- 28,38 ---- #include "dns.h" + typedef struct _dnsClient { + Ns_RWLock lock; + char ipaddr[16]; + Tcl_HashTable list; + struct _dnsClient *link; + } dnsClient; + // DNS request typedef struct _dnsRequest { *************** *** 35,38 **** --- 42,46 ---- dnsPacket *req; dnsPacket *reply; + dnsClient *client; struct sockaddr_in addr; unsigned short proxy_id; *************** *** 60,64 **** static int dnsRequestSend(dnsRequest *req); static int dnsRequestHandle(dnsRequest *req); ! static void dnsRecordCache(dnsRecord **list); static int dnsWrite(int sock, void *vbuf, int len); static int dnsRead(int sock, void *vbuf, int len); --- 68,72 ---- static int dnsRequestSend(dnsRequest *req); static int dnsRequestHandle(dnsRequest *req); ! static void dnsRecordCache(dnsClient *client, dnsRecord **list); static int dnsWrite(int sock, void *vbuf, int len); static int dnsRead(int sock, void *vbuf, int len); *************** *** 72,75 **** --- 80,87 ---- static void DnsQueueListenThread(void *arg); static void DnsQueueRequestThread(void *arg); + static dnsClient *DnsClientFind(char *host,struct in_addr addr); + static dnsClient *DnsClientCreate(char *host); + static void DnsClientLink(char *host, char *host2); + static int DnsClientResolve(char *host, struct in_addr *addr); static unsigned short dnsID = 0; *************** *** 88,93 **** static char *dnsProxyHost; static char *dnsDefaultHost; - static Tcl_HashTable dnsCache; - static Ns_RWLock dnsMutex; static Ns_Cond dnsProxyCond; static Ns_Mutex dnsProxyMutex; --- 100,103 ---- *************** *** 95,98 **** --- 105,111 ---- static struct sockaddr_in dnsProxyAddr; static dnsQueue dnsQueues[DNS_QUEUE_SIZE]; + static Ns_RWLock dnsClientLock; + static Tcl_HashTable dnsClientList; + static dnsClient dnsClientDflt; NS_EXPORT int Ns_ModuleVersion = 1; *************** *** 106,110 **** Ns_Log(Notice, "nsdns module version %s server: %s", VERSION,server); ! Tcl_InitHashTable(&dnsCache,TCL_STRING_KEYS); path = Ns_ConfigGetPath(server,module,NULL); --- 119,128 ---- Ns_Log(Notice, "nsdns module version %s server: %s", VERSION,server); ! Ns_RWLockInit(&dnsClientLock); ! Tcl_InitHashTable(&dnsClientList,TCL_ONE_WORD_KEYS); ! memset(&dnsClientDflt,0,sizeof(dnsClient)); ! strcpy(dnsClientDflt.ipaddr,"0.0.0.0"); ! Ns_RWLockInit(&dnsClientDflt.lock); ! Tcl_InitHashTable(&dnsClientDflt.list,TCL_STRING_KEYS); path = Ns_ConfigGetPath(server,module,NULL); *************** *** 219,229 **** { enum commands { ! cmdAdd, cmdRemove, cmdFlush, cmdList, cmdResolve, cmdQueue, cmdLookup, cmdStat }; static const char *sCmd[] = { ! "add", "del", "flush", "list", "resolve", "queue", "lookup", "stat", 0 }; int i,cmd; char tmp[128]; dnsRecord *drec; --- 237,251 ---- { enum commands { ! cmdAdd, cmdDel, cmdFlush, cmdList, cmdResolve, cmdQueue, cmdLookup, cmdStat, cmdFind, ! cmdClientAdd, cmdClientDel, cmdClientList, cmdClientLink, cmdClientFind }; static const char *sCmd[] = { ! "add", "del", "flush", "list", "resolve", "queue", "lookup", "stat", "find", ! "clientadd", "clientdel", "clientlist", "clientlink", "clientfind", 0 }; int i,cmd; + struct in_addr addr; + int argc = objc, argp = 2; char tmp[128]; dnsRecord *drec; *************** *** 231,234 **** --- 253,257 ---- Tcl_HashSearch search; unsigned long n,r; + dnsClient *client = &dnsClientDflt; if(objc < 2) { *************** *** 240,297 **** switch(cmd) { ! case cmdStat: ! for(n = 0,r = 0,i = 0;i < dnsThreads;i++) { ! n += dnsQueues[i].size; ! r += dnsQueues[i].requests; ! sprintf(tmp,"size%d %lu maxsize%d %lu time%d %lu requests%d %lu ", ! i,dnsQueues[i].size,i,dnsQueues[i].maxsize,i,dnsQueues[i].time,i,dnsQueues[i].requests); ! Tcl_AppendResult(interp, tmp, 0); } ! sprintf(tmp,"total %lu requests %lu",n,r); ! Tcl_AppendResult(interp, tmp, 0); break; case cmdAdd: ! if(objc < 5) { Tcl_WrongNumArgs(interp,2,objv,"name type value ?ttl?"); return TCL_ERROR; } ! switch(dnsType(Tcl_GetString(objv[3]))) { case DNS_TYPE_A: ! drec = dnsRecordCreateA(Tcl_GetString(objv[2]),inet_addr(Tcl_GetString(objv[4]))); ! if(objc > 5) drec->ttl = atoi(Tcl_GetString(objv[5])); break; case DNS_TYPE_MX: ! if(objc < 6) { Tcl_WrongNumArgs(interp,2,objv,"name type preference value ?ttl?"); return TCL_ERROR; } ! drec = dnsRecordCreateMX(Tcl_GetString(objv[2]),atoi(Tcl_GetString(objv[4])), ! Tcl_GetString(objv[5])); ! if(objc > 6) drec->ttl = atoi(Tcl_GetString(objv[6])); break; case DNS_TYPE_NAPTR: ! if(objc < 9) { Tcl_WrongNumArgs(interp,2,objv,"name type order preference flags service regexp ?replace? ?ttl?"); return TCL_ERROR; } ! drec = dnsRecordCreateNAPTR(Tcl_GetString(objv[2]),atoi(Tcl_GetString(objv[4])), ! atoi(Tcl_GetString(objv[5])), ! Tcl_GetString(objv[6]),Tcl_GetString(objv[7]), ! Tcl_GetString(objv[8]), ! objc > 9 ? Tcl_GetString(objv[9]) : 0); ! if(objc > 10) drec->ttl = atoi(Tcl_GetString(objv[10])); break; case DNS_TYPE_NS: ! drec = dnsRecordCreateNS(Tcl_GetString(objv[2]),Tcl_GetString(objv[4])); ! if(objc > 5) drec->ttl = atoi(Tcl_GetString(objv[5])); break; case DNS_TYPE_PTR: ! drec = dnsRecordCreatePTR(Tcl_GetString(objv[2]),Tcl_GetString(objv[4])); ! if(objc > 5) drec->ttl = atoi(Tcl_GetString(objv[5])); break; case DNS_TYPE_CNAME: ! drec = dnsRecordCreateCNAME(Tcl_GetString(objv[2]),Tcl_GetString(objv[4])); ! if(objc > 5) drec->ttl = atoi(Tcl_GetString(objv[5])); break; default: --- 263,327 ---- switch(cmd) { ! case cmdClientLink: ! if(objc < 4) { ! Tcl_WrongNumArgs(interp,2,objv,"clientip clientip2"); ! return TCL_ERROR; } ! DnsClientLink(Tcl_GetString(objv[2]), Tcl_GetString(objv[3])); break; + case cmdClientAdd: + if(argc < 6) { + Tcl_WrongNumArgs(interp,2,objv,"client name type value ?ttl?"); + return TCL_ERROR; + } + client = DnsClientFind(Tcl_GetString(objv[2]),addr); + // Create new client + if(client == &dnsClientDflt) client = DnsClientCreate(Tcl_GetString(objv[2])); + argc--; + argp++; + case cmdAdd: ! if(argc < 5) { Tcl_WrongNumArgs(interp,2,objv,"name type value ?ttl?"); return TCL_ERROR; } ! switch(dnsType(Tcl_GetString(objv[argp+1]))) { case DNS_TYPE_A: ! drec = dnsRecordCreateA(Tcl_GetString(objv[argp]),inet_addr(Tcl_GetString(objv[argp+2]))); ! if(objc > 5) drec->ttl = atoi(Tcl_GetString(objv[argp+3])); break; case DNS_TYPE_MX: ! if(argc < 6) { Tcl_WrongNumArgs(interp,2,objv,"name type preference value ?ttl?"); return TCL_ERROR; } ! drec = dnsRecordCreateMX(Tcl_GetString(objv[argp]),atoi(Tcl_GetString(objv[argp+2])), ! Tcl_GetString(objv[argp+3])); ! if(argc > 6) drec->ttl = atoi(Tcl_GetString(objv[argp+4])); break; case DNS_TYPE_NAPTR: ! if(argc < 9) { Tcl_WrongNumArgs(interp,2,objv,"name type order preference flags service regexp ?replace? ?ttl?"); return TCL_ERROR; } ! drec = dnsRecordCreateNAPTR(Tcl_GetString(objv[argp]),atoi(Tcl_GetString(objv[argp+2])), ! atoi(Tcl_GetString(objv[argp+3])), ! Tcl_GetString(objv[argp+4]),Tcl_GetString(objv[argp+5]), ! Tcl_GetString(objv[argp+6]), ! argc > 9 ? Tcl_GetString(objv[argp+7]) : 0); ! if(argc > 10) drec->ttl = atoi(Tcl_GetString(objv[argp+8])); break; case DNS_TYPE_NS: ! drec = dnsRecordCreateNS(Tcl_GetString(objv[argp]),Tcl_GetString(objv[argp+2])); ! if(argc > 5) drec->ttl = atoi(Tcl_GetString(objv[argp+3])); break; case DNS_TYPE_PTR: ! drec = dnsRecordCreatePTR(Tcl_GetString(objv[argp]),Tcl_GetString(objv[argp+2])); ! if(argc > 5) drec->ttl = atoi(Tcl_GetString(objv[argp+3])); break; case DNS_TYPE_CNAME: ! drec = dnsRecordCreateCNAME(Tcl_GetString(objv[argp]),Tcl_GetString(objv[argp+2])); ! if(argc > 5) drec->ttl = atoi(Tcl_GetString(objv[argp+3])); break; default: *************** *** 299,312 **** return TCL_ERROR; } ! dnsRecordCache(&drec); break; ! case cmdRemove: ! if(objc < 4) { Tcl_WrongNumArgs(interp,2,objv,"name type ?value?"); return TCL_ERROR; } ! Ns_RWLockWrLock(&dnsMutex); ! if((hrec = Tcl_FindHashEntry(&dnsCache,Tcl_GetString(objv[2])))) { ! int type = dnsType(Tcl_GetString(objv[3])); dnsRecord *list = drec = Tcl_GetHashValue(hrec); while(drec) { --- 329,354 ---- return TCL_ERROR; } ! dnsRecordCache(client, &drec); break; ! ! case cmdClientDel: ! if(argc < 5) { ! Tcl_WrongNumArgs(interp,2,objv,"client name type ?value?"); ! return TCL_ERROR; ! } ! client = DnsClientFind(Tcl_GetString(objv[2]),addr); ! // Ignore unknown clients ! if(client == &dnsClientDflt) break; ! argc--; ! argp++; ! ! case cmdDel: ! if(argc < 4) { Tcl_WrongNumArgs(interp,2,objv,"name type ?value?"); return TCL_ERROR; } ! Ns_RWLockWrLock(&client->lock); ! if((hrec = Tcl_FindHashEntry(&client->list,Tcl_GetString(objv[argp])))) { ! int type = dnsType(Tcl_GetString(objv[argp+1])); dnsRecord *list = drec = Tcl_GetHashValue(hrec); while(drec) { *************** *** 323,344 **** } } ! Ns_RWLockUnlock(&dnsMutex); break; ! case cmdFlush: ! Ns_RWLockWrLock(&dnsMutex); ! hrec = Tcl_FirstHashEntry(&dnsCache,&search); ! while(hrec) { ! drec = Tcl_GetHashValue(hrec); ! dnsRecordDestroy(&drec); ! Tcl_DeleteHashEntry(hrec); ! hrec = Tcl_NextHashEntry(&search); } ! Ns_RWLockUnlock(&dnsMutex); break; case cmdList: { Tcl_Obj *list = Tcl_NewListObj(0,0); ! ! Ns_RWLockRdLock(&dnsMutex); ! hrec = Tcl_FirstHashEntry(&dnsCache,&search); while(hrec) { Tcl_ListObjAppendElement(interp,list, --- 365,410 ---- } } ! Ns_RWLockUnlock(&client->lock); break; ! ! case cmdClientFind: ! if(argc < 4) { ! Tcl_WrongNumArgs(interp,2,objv,"client name"); ! return TCL_ERROR; ! } ! client = DnsClientFind(Tcl_GetString(objv[2]),addr); ! // Ignore unknown clients ! if(client == &dnsClientDflt) break; ! argc--; ! argp++; ! ! case cmdFind: ! if(argc < 3) { ! Tcl_WrongNumArgs(interp,2,objv,"name"); ! return TCL_ERROR; ! } ! Ns_RWLockWrLock(&client->lock); ! if((hrec = Tcl_FindHashEntry(&client->list,Tcl_GetString(objv[argp])))) { ! Tcl_SetObjResult(interp,dnsRecordCreateTclObj(interp,Tcl_GetHashValue(hrec))); } ! Ns_RWLockUnlock(&client->lock); break; + + case cmdClientList: + Ns_RWLockWrLock(&dnsClientLock); + hrec = Tcl_FirstHashEntry(&dnsClientList,&search); + while(hrec) { + addr.s_addr = (unsigned long)Tcl_GetHashKey(&dnsClientList, hrec); + Tcl_AppendElement(interp, ns_inet_ntoa(addr)); + hrec = Tcl_NextHashEntry(&search); + } + Ns_RWLockUnlock(&dnsClientLock); + break; + case cmdList: { Tcl_Obj *list = Tcl_NewListObj(0,0); ! if(objc > 2) client = DnsClientFind(Tcl_GetString(objv[2]),addr); ! Ns_RWLockRdLock(&client->lock); ! hrec = Tcl_FirstHashEntry(&client->list,&search); while(hrec) { Tcl_ListObjAppendElement(interp,list, *************** *** 346,353 **** hrec = Tcl_NextHashEntry(&search); } ! Ns_RWLockUnlock(&dnsMutex); Tcl_SetObjResult(interp,list); break; } case cmdQueue: { char buf[255]; --- 412,449 ---- hrec = Tcl_NextHashEntry(&search); } ! Ns_RWLockUnlock(&client->lock); Tcl_SetObjResult(interp,list); break; } + + case cmdFlush: + if(objc > 2) { + client = DnsClientFind(Tcl_GetString(objv[2]),addr); + // Ignore unknown clients + if(client == &dnsClientDflt) break; + } + Ns_RWLockWrLock(&client->lock); + hrec = Tcl_FirstHashEntry(&client->list,&search); + while(hrec) { + drec = Tcl_GetHashValue(hrec); + dnsRecordDestroy(&drec); + Tcl_DeleteHashEntry(hrec); + hrec = Tcl_NextHashEntry(&search); + } + Ns_RWLockUnlock(&client->lock); + break; + + case cmdStat: + for(n = 0,r = 0,i = 0;i < dnsThreads;i++) { + n += dnsQueues[i].size; + r += dnsQueues[i].requests; + sprintf(tmp,"size%d %lu maxsize%d %lu time%d %lu requests%d %lu ", + i,dnsQueues[i].size,i,dnsQueues[i].maxsize,i,dnsQueues[i].time,i,dnsQueues[i].requests); + Tcl_AppendResult(interp, tmp, 0); + } + sprintf(tmp,"total %lu requests %lu",n,r); + Tcl_AppendResult(interp, tmp, 0); + break; + case cmdQueue: { char buf[255]; *************** *** 361,364 **** --- 457,461 ---- break; } + case cmdResolve: { int i,qtype = 0,timeout = 0; *************** *** 389,393 **** } break; ! } case cmdLookup: { int qtype = 0; --- 486,491 ---- } break; ! } ! case cmdLookup: { int qtype = 0; *************** *** 451,455 **** DNS_SET_RCODE(req->reply->u,RCODE_SRVFAIL); req->req->qdlist->rcode = RCODE_SRVFAIL; ! dnsRecordCache(&req->req->qdlist); dnsRequestSend(req); dnsRequestFree(req); --- 549,553 ---- DNS_SET_RCODE(req->reply->u,RCODE_SRVFAIL); req->req->qdlist->rcode = RCODE_SRVFAIL; ! dnsRecordCache(req->client,&req->req->qdlist); dnsRequestSend(req); dnsRequestFree(req); *************** *** 494,500 **** dnsRequestSend(req); /* Save reply in our cache */ ! dnsRecordCache(&req->reply->anlist); ! dnsRecordCache(&req->reply->nslist); ! dnsRecordCache(&req->reply->arlist); } /* Remove form the queue */ --- 592,598 ---- dnsRequestSend(req); /* Save reply in our cache */ ! dnsRecordCache(req->client,&req->reply->anlist); ! dnsRecordCache(req->client,&req->reply->nslist); ! dnsRecordCache(req->client,&req->reply->arlist); } /* Remove form the queue */ *************** *** 580,583 **** --- 678,682 ---- // Prepare reply header req->reply = dnsPacketCreateReply(req->req); + req->client = DnsClientFind(0,req->addr.sin_addr); switch(dnsRequestHandle(req)) { case 1: *************** *** 608,622 **** DnsTcpListen(SOCKET sock,void *si,int when) { ! SOCKET new; ! struct sockaddr_in saddr; int saddr_len = sizeof(struct sockaddr_in); switch(when) { case NS_SOCK_READ: ! if((new = Ns_SockAccept(sock,(struct sockaddr*)&saddr,&saddr_len)) == INVALID_SOCKET) break; ! if(dnsDebug > 3) Ns_Log(Error,"DnsTcpListen: connection from %s",ns_inet_ntoa(saddr.sin_addr)); ! if(Ns_BeginDetachedThread(DnsTcpThread,(void *)new) != NS_OK) { Ns_Log(Error,"nsdns: Ns_BeginThread() failed with %s.",strerror(errno)); ! close(new); } return NS_TRUE; --- 707,723 ---- DnsTcpListen(SOCKET sock,void *si,int when) { ! struct { ! SOCKET sock; ! struct sockaddr_in saddr; ! } arg; int saddr_len = sizeof(struct sockaddr_in); switch(when) { case NS_SOCK_READ: ! if((arg.sock = Ns_SockAccept(sock,(struct sockaddr*)&arg.saddr,&saddr_len)) == INVALID_SOCKET) break; ! if(dnsDebug > 3) Ns_Log(Error,"DnsTcpListen: connection from %s",ns_inet_ntoa(arg.saddr.sin_addr)); ! if(Ns_BeginDetachedThread(DnsTcpThread,(void *)&arg) != NS_OK) { Ns_Log(Error,"nsdns: Ns_BeginThread() failed with %s.",strerror(errno)); ! close(arg.sock); } return NS_TRUE; *************** *** 627,646 **** static void ! DnsTcpThread(void *arg) { ! int sock = (int)arg; short len; dnsRequest *req; char buf[DNS_BUF_SIZE]; ! Ns_SockSetNonBlocking(sock); ! if(dnsRead(sock,&len,2) != 2 || (len = ntohs(len)) > DNS_BUF_SIZE || ! dnsRead(sock,buf,len) != len || ! !(req = dnsRequestCreate(sock,buf,len))) { ! close(sock); return; } req->flags |= DNS_TCP; switch(dnsRequestHandle(req)) { case 1: --- 728,753 ---- static void ! DnsTcpThread(void *sock) { ! struct { ! struct sockaddr_in saddr; ! SOCKET sock; ! } arg; short len; dnsRequest *req; char buf[DNS_BUF_SIZE]; ! memcpy(&arg,sock,sizeof(arg)); ! Ns_SockSetNonBlocking(arg.sock); ! if(dnsRead(arg.sock,&len,2) != 2 || (len = ntohs(len)) > DNS_BUF_SIZE || ! dnsRead(arg.sock,buf,len) != len || ! !(req = dnsRequestCreate(arg.sock,buf,len))) { ! close(arg.sock); return; } req->flags |= DNS_TCP; + memcpy(&req->addr,&arg.saddr,sizeof(req->addr)); + req->client = DnsClientFind(0,req->addr.sin_addr); switch(dnsRequestHandle(req)) { case 1: *************** *** 652,656 **** dnsRequestFree(req); } ! close(sock); } --- 759,763 ---- dnsRequestFree(req); } ! close(arg.sock); } *************** *** 724,740 **** unsigned long now = time(0); ! dnsPacketLog(req->req,1,"Received request"); switch(DNS_GET_OPCODE(req->req->u)) { case OPCODE_QUERY: ! Ns_RWLockRdLock(&dnsMutex); for(qrec = req->req->qdlist;qrec;qrec = qrec->next) { if(!qrec->name) continue; ! if(!(hrec = Tcl_FindHashEntry(&dnsCache,qrec->name))) { snprintf(domain,sizeof(domain)-1,"*.%s",qrec->name); ! if(!(hrec = Tcl_FindHashEntry(&dnsCache,domain))) { if(!(dot = strchr(qrec->name,'.'))) continue; snprintf(domain,sizeof(domain)-1,"*%s",dot); ! if(!(hrec = Tcl_FindHashEntry(&dnsCache,domain))) continue; } } --- 831,847 ---- unsigned long now = time(0); ! dnsPacketLog(req->req,1,"Received request from client=%s",req->client->ipaddr); switch(DNS_GET_OPCODE(req->req->u)) { case OPCODE_QUERY: ! Ns_RWLockRdLock(&req->client->lock); for(qrec = req->req->qdlist;qrec;qrec = qrec->next) { if(!qrec->name) continue; ! if(!(hrec = Tcl_FindHashEntry(&req->client->list,qrec->name))) { snprintf(domain,sizeof(domain)-1,"*.%s",qrec->name); ! if(!(hrec = Tcl_FindHashEntry(&req->client->list,domain))) { if(!(dot = strchr(qrec->name,'.'))) continue; snprintf(domain,sizeof(domain)-1,"*%s",dot); ! if(!(hrec = Tcl_FindHashEntry(&req->client->list,domain))) continue; } } *************** *** 775,779 **** dnsPacketAddRecord(req->reply,&req->reply->nslist,&req->reply->nscount,dnsRecordCreate(qcache)); // Put IP address of the nameserver into additional section ! if((nrec = Tcl_FindHashEntry(&dnsCache,qcache->data.name))) { for(ncache = Tcl_GetHashValue(nrec);ncache;ncache = ncache->next) if(ncache->type == DNS_TYPE_A) --- 882,886 ---- dnsPacketAddRecord(req->reply,&req->reply->nslist,&req->reply->nscount,dnsRecordCreate(qcache)); // Put IP address of the nameserver into additional section ! if((nrec = Tcl_FindHashEntry(&req->client->list,qcache->data.name))) { for(ncache = Tcl_GetHashValue(nrec);ncache;ncache = ncache->next) if(ncache->type == DNS_TYPE_A) *************** *** 802,806 **** } } ! Ns_RWLockUnlock(&dnsMutex); // No records found if(!req->reply->ancount && !req->reply->nscount) { --- 909,913 ---- } } ! Ns_RWLockUnlock(&req->client->lock); // No records found if(!req->reply->ancount && !req->reply->nscount) { *************** *** 856,860 **** static void ! dnsRecordCache(dnsRecord **list) { int new; --- 963,967 ---- static void ! dnsRecordCache(dnsClient *client, dnsRecord **list) { int new; *************** *** 868,873 **** drec->timestamp = now; drec->next = drec->prev = 0; ! Ns_RWLockWrLock(&dnsMutex); ! hrec = Tcl_CreateHashEntry(&dnsCache,drec->name,&new); if(new) { Tcl_SetHashValue(hrec,drec); --- 975,980 ---- drec->timestamp = now; drec->next = drec->prev = 0; ! Ns_RWLockWrLock(&client->lock); ! hrec = Tcl_CreateHashEntry(&client->list,drec->name,&new); if(new) { Tcl_SetHashValue(hrec,drec); *************** *** 881,886 **** } } ! Ns_RWLockUnlock(&dnsMutex); } } --- 988,1054 ---- } } ! Ns_RWLockUnlock(&client->lock); } } + static dnsClient * + DnsClientCreate(char *host) + { + int new; + struct in_addr addr; + dnsClient *client; + Tcl_HashEntry *entry; + + if (DnsClientResolve(host,&addr) == NS_ERROR) { + Ns_Log(Error, "DnsClientAdd: unable to resolve %s", host); + return 0; + } + Ns_RWLockWrLock(&dnsClientLock); + entry = Tcl_CreateHashEntry(&dnsClientList,(char*)addr.s_addr,&new); + Ns_RWLockUnlock(&dnsClientLock); + if (new) { + client = ns_calloc(1,sizeof(dnsClient)); + strcpy(client->ipaddr,ns_inet_ntoa(addr)); + Ns_RWLockInit(&client->lock); + Tcl_InitHashTable(&client->list,TCL_STRING_KEYS); + Tcl_SetHashValue(entry,(ClientData)client); + } + return Tcl_GetHashValue(entry); + } + + static dnsClient * + DnsClientFind(char *host,struct in_addr addr) + { + Tcl_HashEntry *entry; + + if (host && DnsClientResolve(host,&addr) == NS_ERROR) { + Ns_Log(Error, "DnsClientClear: unable to resolve %s", host); + return &dnsClientDflt; + } + Ns_RWLockRdLock(&dnsClientLock); + entry = Tcl_FindHashEntry(&dnsClientList,(char*)addr.s_addr); + Ns_RWLockUnlock(&dnsClientLock); + if (entry) return Tcl_GetHashValue(entry); + return &dnsClientDflt; + } + + static void + DnsClientLink(char *host, char *host2) + { + dnsClient *client, *client2; + + if((client = DnsClientCreate(host)) && (client2 = DnsClientCreate(host2))) { + client2->link = client; + } + } + + static int + DnsClientResolve(char *host, struct in_addr *addr) + { + struct sockaddr_in sa; + + if (!host) host = Ns_InfoHostname(); + if (Ns_GetSockAddr(&sa,host,0) != NS_OK) return NS_ERROR; + *addr = sa.sin_addr; + return NS_OK; + } Index: dns.c =================================================================== RCS file: /cvsroot/naviserver/modules/nsdns/dns.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** dns.c 17 Jun 2005 15:00:23 -0000 1.7 --- dns.c 21 Jun 2005 03:36:40 -0000 1.8 *************** *** 280,294 **** void ! dnsRecordLog(dnsRecord *rec,int level,char *text) { Ns_DString ds; if(level > dnsDebug) return; Ns_DStringInit(&ds); ! Ns_DStringPrintf(&ds,"nsdns: %s ",text); dnsRecordDump(&ds,rec); Ns_Log(level < 0 ? Error : Debug,ds.string); Ns_DStringFree(&ds); } --- 280,298 ---- void ! dnsRecordLog(dnsRecord *rec,int level,char *text, ...) { Ns_DString ds; + va_list ap; if(level > dnsDebug) return; + va_start(ap, text); Ns_DStringInit(&ds); ! Ns_DStringAppend(&ds, "nsdns: "); ! Ns_DStringVPrintf(&ds,text, ap); dnsRecordDump(&ds,rec); Ns_Log(level < 0 ? Error : Debug,ds.string); Ns_DStringFree(&ds); + va_end(ap); } *************** *** 1113,1125 **** void ! dnsPacketLog(dnsPacket *pkt,int level,char *text) { dnsRecord *y; Ns_DString ds; if(level > dnsDebug) return; Ns_DStringInit(&ds); ! Ns_DStringPrintf(&ds,"nsdns: %s ",text); Ns_DStringPrintf(&ds," HEADER: [%04X] ID=%u, OP=%d, QR=%d, AA=%d, RD=%d, RA=%d, TC=%d, RCODE=%d, " "QUERY=%u, ANSWER=%u, NS=%u, ADDITIONAL=%u, LEN=%d", --- 1117,1134 ---- void ! dnsPacketLog(dnsPacket *pkt,int level,char *text, ...) { dnsRecord *y; Ns_DString ds; + va_list ap; + + if(level > dnsDebug) return; if(level > dnsDebug) return; + va_start(ap, text); Ns_DStringInit(&ds); ! Ns_DStringPrintf(&ds,"nsdns: "); ! Ns_DStringVPrintf(&ds,text, ap); Ns_DStringPrintf(&ds," HEADER: [%04X] ID=%u, OP=%d, QR=%d, AA=%d, RD=%d, RA=%d, TC=%d, RCODE=%d, " "QUERY=%u, ANSWER=%u, NS=%u, ADDITIONAL=%u, LEN=%d", Index: dns.h =================================================================== RCS file: /cvsroot/naviserver/modules/nsdns/dns.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** dns.h 17 Jun 2005 15:00:39 -0000 1.6 --- dns.h 21 Jun 2005 03:36:40 -0000 1.7 *************** *** 162,166 **** const char *dnsTypeStr(int type); void dnsRecordDump(Ns_DString *ds,dnsRecord *y); ! void dnsRecordLog(dnsRecord *rec,int level,char *text); void dnsRecordFree(dnsRecord *pkt); void dnsRecordDestroy(dnsRecord **pkt); --- 162,166 ---- const char *dnsTypeStr(int type); void dnsRecordDump(Ns_DString *ds,dnsRecord *y); ! void dnsRecordLog(dnsRecord *rec,int level,char *text, ...); void dnsRecordFree(dnsRecord *pkt); void dnsRecordDestroy(dnsRecord **pkt); *************** *** 200,204 **** dnsPacket *dnsPacketCreateReply(dnsPacket *req); dnsPacket *dnsPacketCreateQuery(char *name,int type); ! void dnsPacketLog(dnsPacket *pkt,int level,char *text); void dnsPacketFree(dnsPacket *pkt,int type); int dnsPacketAddRecord(dnsPacket *pkt,dnsRecord **list,short *count,dnsRecord *rec); --- 200,204 ---- dnsPacket *dnsPacketCreateReply(dnsPacket *req); dnsPacket *dnsPacketCreateQuery(char *name,int type); ! void dnsPacketLog(dnsPacket *pkt,int level,char *text, ...); void dnsPacketFree(dnsPacket *pkt,int type); int dnsPacketAddRecord(dnsPacket *pkt,dnsRecord **list,short *count,dnsRecord *rec); Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/modules/nsdns/ChangeLog,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ChangeLog 17 Jun 2005 02:35:53 -0000 1.3 --- ChangeLog 21 Jun 2005 03:36:40 -0000 1.4 *************** *** 1,2 **** --- 1,6 ---- + 2005-06-20 Vlad Seryakov vl...@cr... + + * re-strcutured for multiple clients + 2005-06-16 Vlad Seryakov vl...@cr... |