From: Bert Hubert Date: Sat, 19 Feb 2005 14:38:55 +0000 (+0000) Subject: Based on request of Simon Kirby, added ability to listen on multiple addresses. X-Git-Tag: pdns-2.9.18~55 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f28307ad269fcaa8c5dff94e929b44f9f45fdd8d;p=pdns Based on request of Simon Kirby, added ability to listen on multiple addresses. This commit also removes the last mentions of 'AhuDNS', the very old name of PowerDNS. It also removes some old documentation. Furthermore, there are some additional license version clarifications. git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@325 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index ba9754d1f..f92d13bda 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -3,9 +3,8 @@ Copyright (C) 2005 PowerDNS.COM BV This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + it under the terms of the GNU General Public License versionm 2 as + published by the Free Software Foundation This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -80,6 +79,7 @@ DNSPacket::DNSPacket(const DNSPacket &orig) d_dt=orig.d_dt; d_socklen=orig.d_socklen; d_compress=orig.d_compress; + d_tcp=orig.d_tcp; qtype=orig.qtype; qclass=orig.qclass; qdomain=orig.qdomain; @@ -1412,6 +1412,7 @@ DNSPacket *DNSPacket::replyPacket() const r->d_dt=d_dt; r->d.qdcount=1; + r->d_tcp = d_tcp; return r; } diff --git a/pdns/dnspacket.hh b/pdns/dnspacket.hh index 571e3b8ce..8e2445b18 100644 --- a/pdns/dnspacket.hh +++ b/pdns/dnspacket.hh @@ -132,7 +132,6 @@ public: DNSResourceRecord d_place field */ void addRecord(const DNSResourceRecord &); - /** helper function for both DNSPacket and addSOARecord() - converts a line into a struct, for easier parsing */ static void fillSOAData(const string &content, SOAData &data); @@ -245,14 +244,14 @@ public: QType qtype; //!< type of the question 8 string qdomain; //!< qname of the question 4 - - + bool d_tcp; private: bool d_wrapped; // 1 bool d_compress; // 1 u_int16_t d_qlen; // length of the question (including class & type) in this packet 2 - + int d_socket; // 4 + int findlabel(string &label); int toqname(const char *name, string &qname, bool compress = true); int toqname(const string &name, string &qname, bool compress = true); diff --git a/pdns/nameserver.cc b/pdns/nameserver.cc index 6d4153e0f..90725262d 100644 --- a/pdns/nameserver.cc +++ b/pdns/nameserver.cc @@ -37,11 +37,11 @@ extern StatBag S; /** \mainpage - ahudns is a very versatile nameserver that can answer questions from different backends. To implement your + PowerDNS is a very versatile nameserver that can answer questions from different backends. To implement your own backend, see the documentation for the DNSBackend class. \section copyright Copyright and License - AhuDNS is (C) 2002 PowerDNS BV. It is distributed according to the terms of the General Public License version 2. + PowerDNS is (C) 2005 PowerDNS.COM BV. It is distributed according to the terms of the General Public License version 2. \section overview High level overview @@ -67,16 +67,12 @@ extern StatBag S; each taking many miliseconds to complete. This is why the qthread() first checks the PacketCache to see if an answer is known to a packet asking this question. If so, the entire Distributor is shunted, and the answer is sent back *directly*, within a few microseconds. - In turn, the athread() offers each outgoing packet to the PacketCache for possible inclusion. - \section misc Miscellaneous Configuration details are available via the ArgvMap instance arg. Statistics are created by making calls to the StatBag object called S. These statistics are made available via the UeberBackend on the same socket that is used for dynamic module commands. \section Main Main The main() of PowerDNS can be found in receiver.cc - start reading there for further insights into the operation of the nameserver - - */ void UDPNameserver::bindIPv4() diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 499f8c75a..59edd6fb4 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -3,9 +3,8 @@ Copyright (C) 2005 PowerDNS.COM BV This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + it under the terms of the GNU General Public License version 2 + as published by the Free Software Foundation This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -72,8 +71,8 @@ ArgvMap &arg() return theArg; } static int d_clientsock; -static int d_serversock; -static int d_tcpserversock; +static vector d_udpserversocks; +static vector d_tcpserversocks; struct PacketID { @@ -123,8 +122,6 @@ int arecvfrom(char *data, int len, int flags, struct sockaddr *toaddr, Utility:: } - - static void writePid(void) { string fname=arg()["socket-dir"]+"/"+s_programname+".pid"; @@ -194,8 +191,9 @@ void startDoResolve(void *p) } const char *buffer=R->getData(); - if(!R->getSocket()) - sendto(d_serversock,buffer,R->len,0,(struct sockaddr *)(R->remote),R->d_socklen); + + if(!R->d_tcp) + sendto(R->getSocket(),buffer,R->len,0,(struct sockaddr *)(R->remote),R->d_socklen); else { char buf[2]; buf[0]=R->len/256; @@ -249,72 +247,82 @@ void makeClientSocket() Utility::setNonBlocking(d_clientsock); } -void makeTCPServerSocket() +void makeTCPServerSockets() { - d_tcpserversock=socket(AF_INET, SOCK_STREAM,0); - if(d_tcpserversock<0) - throw AhuException("Making a server socket for resolver: "+stringerror()); - - struct sockaddr_in sin; - memset((char *)&sin,0, sizeof(sin)); - - sin.sin_family = AF_INET; + vectorlocals; + stringtok(locals,arg()["local-address"]," ,"); + if(locals.empty()) + throw AhuException("No local address specified"); + if(arg()["local-address"]=="0.0.0.0") { - sin.sin_addr.s_addr = INADDR_ANY; - } - else { - if(!IpToU32(arg()["local-address"], &sin.sin_addr.s_addr)) - throw AhuException("Unable to resolve local address"); + L<::const_iterator i=locals.begin();i!=locals.end();++i) { + int fd=socket(AF_INET, SOCK_STREAM,0); + if(fd<0) + throw AhuException("Making a server socket for resolver: "+stringerror()); - - Utility::setNonBlocking(d_tcpserversock); - - listen(d_tcpserversock, 128); + struct sockaddr_in sin; + memset((char *)&sin,0, sizeof(sin)); + + sin.sin_family = AF_INET; + if(!IpToU32(*i, &sin.sin_addr.s_addr)) + throw AhuException("Unable to resolve local address '"+ *i +"'"); + + int tmp=1; + if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) { + L<locals; + stringtok(locals,arg()["local-address"]," ,"); + if(locals.empty()) + throw AhuException("No local address specified"); + if(arg()["local-address"]=="0.0.0.0") { L<::const_iterator i=locals.begin();i!=locals.end();++i) { + int fd=socket(AF_INET, SOCK_DGRAM,0); + if(fd<0) + throw AhuException("Making a server socket for resolver: "+stringerror()); + + struct sockaddr_in sin; + memset((char *)&sin,0, sizeof(sin)); - if (bind(d_serversock, (struct sockaddr *)&sin, sizeof(sin))<0) - throw AhuException("Resolver binding to server socket: "+stringerror()); - - Utility::setNonBlocking(d_serversock); - - L<numProcesses()<(100000); @@ -484,15 +490,21 @@ int main(int argc, char **argv) fd_set readfds; FD_ZERO( &readfds ); FD_SET( d_clientsock, &readfds ); - FD_SET( d_serversock, &readfds ); - FD_SET( d_tcpserversock, &readfds ); - int fdmax=max(d_tcpserversock,max(d_clientsock,d_serversock)); + int fdmax=d_clientsock; + for(vector::const_iterator i=tcpconnections.begin();i!=tcpconnections.end();++i) { FD_SET(i->fd, &readfds); fdmax=max(fdmax,i->fd); } + for(vector::const_iterator i=d_udpserversocks.begin(); i!=d_udpserversocks.end(); ++i) { + FD_SET( *i, &readfds ); + fdmax=max(fdmax,*i); + } + for(vector::const_iterator i=d_tcpserversocks.begin(); i!=d_tcpserversocks.end(); ++i) { + FD_SET( *i, &readfds ); + fdmax=max(fdmax,*i); + } - /* this should listen on a TCP port as well for new connections, */ int selret = select( fdmax + 1, &readfds, NULL, NULL, &tv ); if(selret<=0) if (selret == -1 && errno!=EINTR) @@ -523,38 +535,43 @@ int main(int argc, char **argv) } } - if(FD_ISSET(d_serversock,&readfds)) { // do we have a new question on udp? - d_len=recvfrom(d_serversock, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen); - if(d_len<0) - continue; - P.setRemote((struct sockaddr *)&fromaddr, addrlen); - if(P.parse(data,d_len)<0) { - L<makeThread(startDoResolve,(void*)new DNSPacket(P)); + for(vector::const_iterator i=d_udpserversocks.begin(); i!=d_udpserversocks.end(); ++i) { + if(FD_ISSET(*i,&readfds)) { // do we have a new question on udp? + d_len=recvfrom(*i, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen); + if(d_len<0) + continue; + P.setRemote((struct sockaddr *)&fromaddr, addrlen); + if(P.parse(data,d_len)<0) { + L<makeThread(startDoResolve,(void*)new DNSPacket(P)); + } } } } - if(FD_ISSET(d_tcpserversock,&readfds)) { // do we have a new TCP connection - struct sockaddr_in addr; - socklen_t addrlen=sizeof(addr); - int newsock=accept(d_tcpserversock, (struct sockaddr*)&addr, &addrlen); - - if(newsock>0) { - Utility::setNonBlocking(newsock); - TCPConnection tc; - tc.fd=newsock; - tc.state=TCPConnection::BYTE0; - tc.remote=addr; - tcpconnections.push_back(tc); + for(vector::const_iterator i=d_tcpserversocks.begin(); i!=d_tcpserversocks.end(); ++i) { + if(FD_ISSET(*i ,&readfds)) { // do we have a new TCP connection + struct sockaddr_in addr; + socklen_t addrlen=sizeof(addr); + int newsock=accept(*i, (struct sockaddr*)&addr, &addrlen); + + if(newsock>0) { + Utility::setNonBlocking(newsock); + TCPConnection tc; + tc.fd=newsock; + tc.state=TCPConnection::BYTE0; + tc.remote=addr; + tcpconnections.push_back(tc); + } } } @@ -610,6 +627,7 @@ int main(int argc, char **argv) } else { P.setSocket(i->fd); + P.d_tcp=true; P.setRemote((struct sockaddr *)&i->remote,sizeof(i->remote)); if(P.d.qr) L<