From: Vlad S. <ser...@us...> - 2005-06-14 03:20:47
|
Update of /cvsroot/naviserver/modules/nsdns In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26182 Modified Files: ChangeLog dns.c dns.h nsdns.c Log Message: better performance for udp requests Index: nsdns.c =================================================================== RCS file: /cvsroot/naviserver/modules/nsdns/nsdns.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** nsdns.c 13 Jun 2005 16:04:32 -0000 1.4 --- nsdns.c 14 Jun 2005 03:20:38 -0000 1.5 *************** *** 39,48 **** --- 39,64 ---- unsigned short proxy_count; unsigned long proxy_time; + char buffer[DNS_BUF_SIZE]; + int size; } dnsRequest; + typedef struct _dnsQueue { + int id; + Ns_Cond cond; + Ns_Mutex lock; + unsigned long size; + unsigned long maxsize; + unsigned long requests; + unsigned long time; + struct _dnsRequest *head; + struct _dnsRequest *tail; + struct _dnsRequest *freelist; + } dnsQueue; + static void *dnsRequestCreate(int sock,char *buf,int len); static void dnsRequestFree(dnsRequest *req); 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); *************** *** 51,60 **** static int DnsCmd(ClientData arg,Tcl_Interp *interp,int objc,Tcl_Obj *CONST objv[]); static int DnsInterpInit(Tcl_Interp *interp, void *context); - static int DnsUdpListen(SOCKET sock,void *si,int when); static int DnsTcpListen(SOCKET sock,void *si,int when); static void DnsTcpThread(void *arg); static void DnsProxyThread(void *arg); ! ! static void dnsRecordCache(dnsRecord **list); static unsigned short dnsID = 0; --- 67,75 ---- static int DnsCmd(ClientData arg,Tcl_Interp *interp,int objc,Tcl_Obj *CONST objv[]); static int DnsInterpInit(Tcl_Interp *interp, void *context); static int DnsTcpListen(SOCKET sock,void *si,int when); static void DnsTcpThread(void *arg); static void DnsProxyThread(void *arg); ! static void DnsQueueListenThread(void *arg); ! static void DnsQueueRequestThread(void *arg); static unsigned short dnsID = 0; *************** *** 68,80 **** static int dnsProxyPort; static int dnsProxySock; static int dnsProxyRetries; static char *dnsProxyHost; static char *dnsDefaultHost; - static struct sockaddr_in dnsProxyAddr; static Tcl_HashTable dnsCache; ! static Ns_Mutex dnsMutex; ! static dnsRequest *dnsProxyQueue = 0; ! static Ns_Mutex dnsProxyMutex; static Ns_Cond dnsProxyCond; NS_EXPORT int Ns_ModuleVersion = 1; --- 83,98 ---- static int dnsProxyPort; static int dnsProxySock; + static int dnsThreads; + static int dnsRcvBuf; static int dnsProxyRetries; static char *dnsProxyHost; static char *dnsDefaultHost; static Tcl_HashTable dnsCache; ! static Ns_RWLock dnsMutex; static Ns_Cond dnsProxyCond; + static Ns_Mutex dnsProxyMutex; + static dnsRequest *dnsProxyQueue = 0; + static struct sockaddr_in dnsProxyAddr; + static dnsQueue dnsQueues[DNS_QUEUE_SIZE]; NS_EXPORT int Ns_ModuleVersion = 1; *************** *** 83,86 **** --- 101,105 ---- Ns_ModuleInit(char *server, char *module) { + int n,i; char *path, *address; *************** *** 96,120 **** if(!Ns_ConfigGetInt(path,"ttl",&dnsTTL)) dnsTTL = 86400; if(!Ns_ConfigGetInt(path,"negativettl",&dnsNegativeTTL)) dnsNegativeTTL = 3600; if(!Ns_ConfigGetInt(path,"readtimeout",&dnsReadTimeout)) dnsReadTimeout = 30; if(!Ns_ConfigGetInt(path,"writetimeout",&dnsWriteTimeout)) dnsWriteTimeout = 30; if(!Ns_ConfigGetInt(path,"proxytimeout",&dnsProxyTimeout)) dnsProxyTimeout = 3; if(!Ns_ConfigGetInt(path,"proxyretries",&dnsProxyRetries)) dnsProxyRetries = 2; dnsDefaultHost = Ns_ConfigGet(path,"defaulthost"); ! /* Resolving dns servers */ dnsInit("nameserver",Ns_ConfigGet(path,"nameserver"),0); /* If no port specified it will be just client dns resolver module */ if(dnsPort > 0) { ! /* UDP socket */ if((dnsUdpSock = Ns_SockListenUdp(address,dnsPort)) == -1) { Ns_Log(Error,"nsdns: udp: %s:%d: couldn't create socket: %s",address,dnsPort,strerror(errno)); return NS_ERROR; } ! Ns_SockCallback(dnsUdpSock,DnsUdpListen,0,NS_SOCK_READ|NS_SOCK_EXIT|NS_SOCK_EXCEPTION); ! /* TCP socket */ if((dnsTcpSock = Ns_SockListen(address,dnsPort)) == -1) { Ns_Log(Error,"nsdns: tcp: %s:%d: couldn't create socket: %s",address,dnsPort,strerror(errno)); return NS_ERROR; } Ns_SockCallback(dnsTcpSock,DnsTcpListen,0,NS_SOCK_READ|NS_SOCK_EXIT|NS_SOCK_EXCEPTION); if(!Ns_ConfigGetInt(path,"proxyport",&dnsProxyPort)) dnsProxyPort = 53; if((dnsProxyHost = Ns_ConfigGet(path,"proxyhost")) && --- 115,142 ---- if(!Ns_ConfigGetInt(path,"ttl",&dnsTTL)) dnsTTL = 86400; if(!Ns_ConfigGetInt(path,"negativettl",&dnsNegativeTTL)) dnsNegativeTTL = 3600; + if(!Ns_ConfigGetInt(path,"rcvbuf",&dnsRcvBuf)) dnsRcvBuf = 0; if(!Ns_ConfigGetInt(path,"readtimeout",&dnsReadTimeout)) dnsReadTimeout = 30; if(!Ns_ConfigGetInt(path,"writetimeout",&dnsWriteTimeout)) dnsWriteTimeout = 30; if(!Ns_ConfigGetInt(path,"proxytimeout",&dnsProxyTimeout)) dnsProxyTimeout = 3; if(!Ns_ConfigGetInt(path,"proxyretries",&dnsProxyRetries)) dnsProxyRetries = 2; + if (!Ns_ConfigGetInt(path,"threads",&dnsThreads)) dnsThreads = 1; dnsDefaultHost = Ns_ConfigGet(path,"defaulthost"); ! // Resolving dns servers dnsInit("nameserver",Ns_ConfigGet(path,"nameserver"),0); /* If no port specified it will be just client dns resolver module */ if(dnsPort > 0) { ! // UDP socket if((dnsUdpSock = Ns_SockListenUdp(address,dnsPort)) == -1) { Ns_Log(Error,"nsdns: udp: %s:%d: couldn't create socket: %s",address,dnsPort,strerror(errno)); return NS_ERROR; } ! // TCP socket if((dnsTcpSock = Ns_SockListen(address,dnsPort)) == -1) { Ns_Log(Error,"nsdns: tcp: %s:%d: couldn't create socket: %s",address,dnsPort,strerror(errno)); return NS_ERROR; } + // Use NS callback facility because TCP is not going to be very busy Ns_SockCallback(dnsTcpSock,DnsTcpListen,0,NS_SOCK_READ|NS_SOCK_EXIT|NS_SOCK_EXCEPTION); + // DNS proxy thread if(!Ns_ConfigGetInt(path,"proxyport",&dnsProxyPort)) dnsProxyPort = 53; if((dnsProxyHost = Ns_ConfigGet(path,"proxyhost")) && *************** *** 127,130 **** --- 149,175 ---- return NS_ERROR; } + if(dnsRcvBuf) { + setsockopt(dnsUdpSock,SOL_SOCKET,SO_RCVBUF,&dnsRcvBuf,sizeof(dnsRcvBuf)); + setsockopt(dnsUdpSock,SOL_SOCKET,SO_SNDBUF,&dnsRcvBuf,sizeof(dnsRcvBuf)); + } + // Start queue threads + for(n = 0;n < dnsThreads;n++) { + dnsQueues[n].id = n; + // Preallocate SIP tickets + for(i = 0;i <= dnsThreads*10;i++) { + dnsRequest *req = ns_calloc(1,sizeof(dnsRequest)); + req->next = dnsQueues[n].freelist; + dnsQueues[n].freelist = req; + } + if(Ns_BeginDetachedThread(DnsQueueRequestThread,&dnsQueues[n]) != NS_OK) { + Ns_Log(Error,"nsdns: queue thread failed: %s",strerror(errno)); + return NS_ERROR; + } + } + // Start listen thread + if(Ns_BeginDetachedThread(DnsQueueListenThread,0) != NS_OK) { + Ns_Log(Error,"nsdns: main thread failed: %s",strerror(errno)); + return NS_ERROR; + } } if(dnsDebug) { *************** *** 133,137 **** Ns_Log(Notice,"nsdns: SEGV and Panic trapping is activated"); } - Ns_MutexSetName2(&dnsMutex,"nsdns","dns"); Ns_MutexSetName2(&dnsProxyMutex,"nsdns","proxy"); Ns_Log(Notice,"nsdns: version %s listening on %s:%d, FD %d:%d",VERSION,address?address:"0.0.0.0",dnsPort,dnsUdpSock,dnsTcpSock); --- 178,181 ---- *************** *** 174,188 **** DnsCmd(ClientData arg,Tcl_Interp *interp,int objc,Tcl_Obj *CONST objv[]) { - int cmd; enum commands { ! cmdAdd, cmdRemove, cmdFlush, cmdList, cmdResolve, cmdQueue, cmdLookup }; static const char *sCmd[] = { ! "add", "del", "flush", "list", "resolve", "queue", "lookup", 0 }; dnsRecord *drec; Tcl_HashEntry *hrec; Tcl_HashSearch search; if(objc < 2) { --- 218,234 ---- DnsCmd(ClientData arg,Tcl_Interp *interp,int objc,Tcl_Obj *CONST objv[]) { 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; Tcl_HashEntry *hrec; Tcl_HashSearch search; + unsigned long n,r; if(objc < 2) { *************** *** 194,197 **** --- 240,254 ---- 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) { *************** *** 212,215 **** --- 269,281 ---- if(objc > 6) drec->ttl = atoi(Tcl_GetString(objv[6])); break; + case DNS_TYPE_NAPTR: + if(objc < 10) { + 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]),Tcl_GetString(objv[9])); + 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])); *************** *** 235,239 **** return TCL_ERROR; } ! Ns_MutexLock(&dnsMutex); if((hrec = Tcl_FindHashEntry(&dnsCache,Tcl_GetString(objv[2])))) { int type = dnsType(Tcl_GetString(objv[3])); --- 301,305 ---- return TCL_ERROR; } ! Ns_RWLockWrLock(&dnsMutex); if((hrec = Tcl_FindHashEntry(&dnsCache,Tcl_GetString(objv[2])))) { int type = dnsType(Tcl_GetString(objv[3])); *************** *** 252,259 **** } } ! Ns_MutexUnlock(&dnsMutex); break; case cmdFlush: ! Ns_MutexLock(&dnsMutex); hrec = Tcl_FirstHashEntry(&dnsCache,&search); while(hrec) { --- 318,325 ---- } } ! Ns_RWLockUnlock(&dnsMutex); break; case cmdFlush: ! Ns_RWLockWrLock(&dnsMutex); hrec = Tcl_FirstHashEntry(&dnsCache,&search); while(hrec) { *************** *** 263,272 **** hrec = Tcl_NextHashEntry(&search); } ! Ns_MutexUnlock(&dnsMutex); break; case cmdList: { Tcl_Obj *list = Tcl_NewListObj(0,0); ! Ns_MutexLock(&dnsMutex); hrec = Tcl_FirstHashEntry(&dnsCache,&search); while(hrec) { --- 329,338 ---- 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) { *************** *** 275,279 **** hrec = Tcl_NextHashEntry(&search); } ! Ns_MutexUnlock(&dnsMutex); Tcl_SetObjResult(interp,list); break; --- 341,345 ---- hrec = Tcl_NextHashEntry(&search); } ! Ns_RWLockUnlock(&dnsMutex); Tcl_SetObjResult(interp,list); break; *************** *** 342,428 **** } - static int - DnsUdpListen(SOCKET sock,void *si,int when) - { - int len, saddr_len; - char buf[DNS_BUF_SIZE+1]; - dnsRequest *req; - struct sockaddr_in saddr; - - switch(when) { - case NS_SOCK_READ: - saddr_len = sizeof(struct sockaddr_in); - if((len = recvfrom(sock,buf,DNS_BUF_SIZE,0,(struct sockaddr*)&saddr,&saddr_len)) <= 0) { - Ns_Log(Error,"nsdns: recvfrom error: %s",strerror(errno)); - return NS_TRUE; - } - if(dnsDebug > 3) Ns_Log(Error,"DnsUdpListen: received %d bytes from %s",len,ns_inet_ntoa(saddr.sin_addr)); - if(!(req = dnsRequestCreate(sock,buf,len))) return NS_TRUE; - memcpy(&req->addr,&saddr,sizeof(struct sockaddr_in)); - switch(dnsRequestHandle(req)) { - case 1: - /* Request will handled by proxy queue manager */ - break; - case 0: - dnsRequestSend(req); - default: - dnsRequestFree(req); - } - return NS_TRUE; - } - close(sock); - return NS_FALSE; - } - - static int - 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; - } - close(sock); - return NS_FALSE; - } - - 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: - /* Request will handled by proxy queue manager */ - break; - case 0: - dnsRequestSend(req); - default: - dnsRequestFree(req); - } - close(sock); - } - static void DnsProxyThread(void *arg) --- 408,411 ---- *************** *** 520,523 **** --- 503,653 ---- } + static void + DnsQueueListenThread(void *arg) + { + int len = sizeof(struct sockaddr_in); + dnsRequest *req, buf; + int id = 0; + + Ns_ThreadSetName("nsdns:thread"); + + while(1) { + if ((buf.size = recvfrom(dnsUdpSock,buf.buffer,DNS_BUF_SIZE-1,0,(struct sockaddr*)&buf.addr,&len)) <= 0) { + Ns_Log(Error,"nsdns: recvfrom error: %s",strerror(errno)); + continue; + } + buf.buffer[buf.size] = 0; + if(dnsDebug > 0) { + Ns_Log(Debug,"nsdns: received %d bytes from %s",buf.size,ns_inet_ntoa(buf.addr.sin_addr)); + } + /* + * Link new job into the queue + */ + Ns_MutexLock(&dnsQueues[id].lock); + if((req = dnsQueues[id].freelist)) dnsQueues[id].freelist = req->next; + if(!req) req = ns_calloc(1,sizeof(dnsRequest)); + memcpy(req,&buf,sizeof(buf)); + if(dnsQueues[id].tail) dnsQueues[id].tail->next = req; + dnsQueues[id].tail = req; + if(!dnsQueues[id].head) dnsQueues[id].head = req; + dnsQueues[id].size++; + dnsQueues[id].requests++; + Ns_CondBroadcast(&dnsQueues[id].cond); + Ns_MutexUnlock(&dnsQueues[id].lock); + if(++id >= dnsThreads) id = 0; + } + } + + static void + DnsQueueRequestThread(void *arg) + { + char buf[32]; + dnsQueue *queue; + dnsRequest *req; + unsigned long t0; + struct timeval t1,t2; + + queue = (dnsQueue*)arg; + sprintf(buf, "nsdns:queue:%d", queue->id); + Ns_Log(Notice, "Starting thread: %s", buf); + Ns_ThreadSetName(buf); + + Ns_MutexInit(&queue->lock); + Ns_MutexSetName(&queue->lock,buf); + Ns_MutexLock(&queue->lock); + while (1) { + while (!queue->head) { + Ns_CondWait(&queue->cond, &queue->lock); + } + gettimeofday(&t1,0); + /* + * Unlink first job from the queue + */ + req = queue->head; + queue->head = req->next; + if(queue->tail == req) queue->tail = 0; + if(queue->size > queue->maxsize) queue->maxsize = queue->size; + queue->size--; + Ns_MutexUnlock(&queue->lock); + req->sock = dnsUdpSock; + // Allocate request structure + if((req->req = dnsParsePacket(req->buffer,req->size))) { + // Prepare reply header + req->reply = dnsPacketCreateReply(req->req); + switch(dnsRequestHandle(req)) { + case 1: + // Proxy will handle request + req = 0; + break; + case 0: + dnsRequestSend(req); + dnsPacketFree(req->req,3); + dnsPacketFree(req->reply,4); + break; + } + } + // Put request structure back if not handled by proxy + if(req) { + req->next = queue->freelist; + queue->freelist = req; + } + Ns_MutexLock(&queue->lock); + Ns_CondBroadcast(&queue->cond); + gettimeofday(&t2,0); + t0 = ((t2.tv_sec - t1.tv_sec)*1000000 + (t2.tv_usec - t1.tv_usec))/1000; + if(t0 > queue->time) queue->time = t0; + } + } + + static int + 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; + } + close(sock); + return NS_FALSE; + } + + 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: + /* Request will handled by proxy queue manager */ + break; + case 0: + dnsRequestSend(req); + default: + dnsRequestFree(req); + } + close(sock); + } + static int dnsRead(int sock, void *vbuf, int len) *************** *** 593,597 **** switch(DNS_GET_OPCODE(req->req->u)) { case OPCODE_QUERY: ! Ns_MutexLock(&dnsMutex); for(qrec = req->req->qdlist;qrec;qrec = qrec->next) { if(!qrec->name) continue; --- 723,727 ---- 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; *************** *** 667,671 **** } } ! Ns_MutexUnlock(&dnsMutex); // No records found if(!req->reply->ancount && !req->reply->nscount) { --- 797,801 ---- } } ! Ns_RWLockUnlock(&dnsMutex); // No records found if(!req->reply->ancount && !req->reply->nscount) { *************** *** 733,737 **** drec->timestamp = now; drec->next = drec->prev = 0; ! Ns_MutexLock(&dnsMutex); hrec = Tcl_CreateHashEntry(&dnsCache,drec->name,&new); if(new) { --- 863,867 ---- drec->timestamp = now; drec->next = drec->prev = 0; ! Ns_RWLockWrLock(&dnsMutex); hrec = Tcl_CreateHashEntry(&dnsCache,drec->name,&new); if(new) { *************** *** 746,750 **** } } ! Ns_MutexUnlock(&dnsMutex); } } --- 876,880 ---- } } ! Ns_RWLockUnlock(&dnsMutex); } } Index: dns.c =================================================================== RCS file: /cvsroot/naviserver/modules/nsdns/dns.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dns.c 12 Jun 2005 22:34:22 -0000 1.3 --- dns.c 14 Jun 2005 03:20:38 -0000 1.4 *************** *** 435,438 **** --- 435,458 ---- dnsRecord * + dnsRecordCreateNAPTR(char *name,int order,int preference,char *flags,char *service,char *regexp,char *replace) + { + dnsRecord *y = ns_calloc(1,sizeof(dnsRecord)); + y->name = ns_strcopy(name); + y->type = DNS_TYPE_NAPTR; + y->class = DNS_CLASS_INET; + y->data.naptr = ns_calloc(1,sizeof(dnsMX)); + y->data.naptr->order = order; + y->data.naptr->preference = preference; + y->data.naptr->flags = ns_strcopy(flags); + y->data.naptr->service = ns_strcopy(service); + y->data.naptr->regexp = ns_strcopy(regexp); + y->data.naptr->replace = ns_strcopy(replace); + y->len = 2; + if(y->data.name) y->len += strlen(y->data.name); + y->ttl = dnsTTL; + return y; + } + + dnsRecord * dnsRecordCreateSOA(char *name,char *mname,char *rname, unsigned long serial,unsigned long refresh, *************** *** 476,479 **** --- 496,508 ---- Tcl_ListObjAppendElement(interp,obj,Tcl_NewIntObj(drec->data.mx->preference)); break; + case DNS_TYPE_NAPTR: + if(!drec->data.naptr) break; + Tcl_ListObjAppendElement(interp,obj,Tcl_NewIntObj(drec->data.naptr->order)); + Tcl_ListObjAppendElement(interp,obj,Tcl_NewIntObj(drec->data.naptr->preference)); + Tcl_ListObjAppendElement(interp,obj,Tcl_NewStringObj(drec->data.naptr->flags,-1)); + Tcl_ListObjAppendElement(interp,obj,Tcl_NewStringObj(drec->data.naptr->service,-1)); + Tcl_ListObjAppendElement(interp,obj,Tcl_NewStringObj(drec->data.naptr->regexp,-1)); + Tcl_ListObjAppendElement(interp,obj,Tcl_NewStringObj(drec->data.naptr->replace,-1)); + break; case DNS_TYPE_SOA: if(!drec->data.soa) break; *************** *** 558,561 **** --- 587,605 ---- } break; + case DNS_TYPE_NAPTR: + if(!rec->data.naptr || !drec->data.naptr || + (!rec->data.naptr->regexp && !rec->data.naptr->replace) || + (!drec->data.naptr->regexp && !drec->data.naptr->replace)) return -1; + if((rec->data.naptr->regexp && drec->data.naptr->regexp && + !strcmp(rec->data.naptr->regexp,drec->data.naptr->regexp)) || + (rec->data.naptr->replace && drec->data.naptr->replace && + !strcmp(rec->data.naptr->replace,drec->data.naptr->replace))) { + if(replace) { + rec->ttl = drec->ttl; + rec->data.mx->preference = drec->data.mx->preference; + } + return 1; + } + break; case DNS_TYPE_SOA: if(!rec->data.soa || !drec->data.soa) return -1; *************** *** 716,719 **** --- 760,782 ---- y->data.name = ns_strdup(name); break; + case DNS_TYPE_NAPTR: + y->data.naptr = ns_calloc(1,sizeof(dnsNAPTR)); + y->data.naptr->order = ntohs(*((unsigned short*)pkt->buf.ptr)); + pkt->buf.ptr += 2; + y->data.mx->preference = ntohs(*((unsigned short*)pkt->buf.ptr)); + pkt->buf.ptr += 2; + /* flags */ + if(dnsParseName(pkt,&pkt->buf.ptr,name,255,0,0) < 0) goto err; + y->data.naptr->flags = ns_strdup(name); + /* service */ + if(dnsParseName(pkt,&pkt->buf.ptr,name,255,0,0) < 0) goto err; + y->data.naptr->service = ns_strdup(name); + /* regexp */ + if(dnsParseName(pkt,&pkt->buf.ptr,name,255,0,0) < 0) goto err; + y->data.naptr->regexp = ns_strdup(name); + /* replace */ + if(dnsParseName(pkt,&pkt->buf.ptr,name,255,0,0) < 0) goto err; + y->data.naptr->replace = ns_strdup(name); + break; case DNS_TYPE_SOA: y->data.soa = ns_calloc(1,sizeof(dnsSOA)); *************** *** 910,913 **** --- 973,988 ---- dnsEncodeName(pkt,list->data.name); break; + case DNS_TYPE_NAPTR: + dnsEncodeShort(pkt,list->data.naptr->order); + dnsEncodeShort(pkt,list->data.naptr->preference); + dnsEncodeGrow(pkt,64,"pkt:naptr"); + dnsEncodeName(pkt,list->data.naptr->flags); + dnsEncodeGrow(pkt,64,"pkt:naptr"); + dnsEncodeName(pkt,list->data.naptr->service); + dnsEncodeGrow(pkt,64,"pkt:naptr"); + dnsEncodeName(pkt,list->data.naptr->regexp); + dnsEncodeGrow(pkt,64,"pkt:naptr"); + dnsEncodeName(pkt,list->data.naptr->replace); + break; } dnsEncodeEnd(pkt); *************** *** 1062,1065 **** --- 1137,1141 ---- type == DNS_TYPE_PTR ? "PTR" : type == DNS_TYPE_MX ? "MX" : + type == DNS_TYPE_NAPTR ? "NAPTR" : type == DNS_TYPE_ANY ? "ANY" : "unknown"; } *************** *** 1074,1077 **** --- 1150,1154 ---- if(!strcasecmp(type,"SOA")) return DNS_TYPE_SOA; if(!strcasecmp(type,"PTR")) return DNS_TYPE_PTR; + if(!strcasecmp(type,"NAPTR")) return DNS_TYPE_NAPTR; if(!strcasecmp(type,"MX")) return DNS_TYPE_MX; return -1; Index: dns.h =================================================================== RCS file: /cvsroot/naviserver/modules/nsdns/dns.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dns.h 12 Jun 2005 22:34:22 -0000 1.3 --- dns.h 14 Jun 2005 03:20:38 -0000 1.4 *************** *** 84,87 **** --- 84,88 ---- #define DNS_BUF_SIZE 1524 #define DNS_REPLY_SIZE 514 + #define DNS_QUEUE_SIZE 16 typedef struct _dnsSOA { *************** *** 106,118 **** } dnsName; ! typedef struct _dnsNA { struct _dnsNA *next; short order; ! short prefs; char *flags; char *service; char *regexp; char *replace; ! } dnsNA; typedef struct _dnsRecord { --- 107,119 ---- } dnsName; ! typedef struct _dnsNAPTR { struct _dnsNA *next; short order; ! short preference; char *flags; char *service; char *regexp; char *replace; ! } dnsNAPTR; typedef struct _dnsRecord { *************** *** 127,131 **** struct in_addr ipaddr; dnsMX *mx; ! dnsNA *na; dnsSOA *soa; } data; --- 128,132 ---- struct in_addr ipaddr; dnsMX *mx; ! dnsNAPTR *naptr; dnsSOA *soa; } data; *************** *** 174,177 **** --- 175,180 ---- unsigned long serial,unsigned long refresh, unsigned long retry,unsigned long expire,unsigned long ttl); + dnsRecord *dnsRecordCreateNAPTR(char *name,int order,int preference,char *flags, + char *service,char *regexp,char *replace); Tcl_Obj *dnsRecordCreateTclObj(Tcl_Interp *interp,dnsRecord *drec); dnsRecord *dnsRecordAppend(dnsRecord **list,dnsRecord *pkt); Index: ChangeLog =================================================================== RCS file: /cvsroot/naviserver/modules/nsdns/ChangeLog,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** ChangeLog 20 May 2005 20:40:08 -0000 1.1.1.1 --- ChangeLog 14 Jun 2005 03:20:38 -0000 1.2 *************** *** 1,2 **** --- 1,6 ---- + 2005-06-13 Vlad Seryakov vl...@cr... + + * restructured for more performance of udp requests + 2004-03-23 Vlad Seryakov vl...@cr... |