]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/lwres.cc
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 - 2005 PowerDNS.COM BV
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <semaphore.h>
32 #include "ahuexception.hh"
33 #include "arguments.hh"
36 #include "dnswriter.hh"
37 #include "dnsparser.hh"
45 d_buf
= new unsigned char [ d_bufsize
];
51 Utility :: closesocket ( d_sock
);
56 //! returns -1 for permanent error, 0 for timeout, 1 for success
58 int LWRes :: asyncresolve ( uint32_t ip
, const char * domain
, int type
, bool doTCP
, struct timeval
* now
)
61 vector
< uint8_t > vpacket
;
62 DNSPacketWriter
pw ( vpacket
, domain
, type
);
65 pw
. getHeader ()-> id
= random ();
72 struct sockaddr_in toaddr
;
73 Utility :: socklen_t addrlen
= sizeof ( toaddr
);
74 toaddr
. sin_addr
. s_addr
= htonl ( ip
);
76 toaddr
. sin_port
= htons ( 53 );
77 toaddr
. sin_family
= AF_INET
;
85 if ( asendto (( const char *)&* vpacket
. begin (), vpacket
. size (), 0 , ( struct sockaddr
*)(& toaddr
), sizeof ( toaddr
), pw
. getHeader ()-> id
)< 0 ) {
89 // sleep until we see an answer to this, interface to mtasker
91 ret
= arecvfrom ( reinterpret_cast < char *>( d_buf
), d_bufsize
- 1 , 0 ,( struct sockaddr
*)(& toaddr
), & addrlen
, & d_len
, pw
. getHeader ()-> id
);
94 Socket
s ( InterNetwork
, Stream
);
95 IPEndpoint
ie ( U32ToIP ( ip
), 53 );
99 unsigned int len
= htons ( vpacket
. size ());
100 char * lenP
=( char *)& len
;
101 const char * msgP
=( const char *)&* vpacket
. begin ();
102 string packet
= string ( lenP
, lenP
+ 2 )+ string ( msgP
, msgP
+ vpacket
. size ());
104 if ( asendtcp ( packet
, & s
) == 0 ) {
109 if ( arecvtcp ( packet
, 2 , & s
)== 0 ) {
113 memcpy (& len
, packet
. c_str (), 2 );
116 if ( arecvtcp ( packet
, len
, & s
)== 0 ) {
119 if ( len
> ( unsigned int ) d_bufsize
) {
122 d_buf
= new unsigned char [ d_bufsize
];
124 memcpy ( d_buf
, packet
. c_str (), len
);
129 * now
= dt
. getTimeval ();
134 LWRes :: res_t
LWRes :: result ()
137 MOADNSParser
mdp (( const char *) d_buf
, d_len
);
138 // if(p.parse((char *)d_buf, d_len)<0)
139 // throw LWResException("resolver: unable to parse packet of "+itoa(d_len)+" bytes");
140 d_aabit
= mdp
. d_header
. aa
;
141 d_tcbit
= mdp
. d_header
. tc
;
142 d_rcode
= mdp
. d_header
. rcode
;
144 if ( strcasecmp ( d_domain
. c_str (), mdp
. d_qname
. c_str ())) {
145 if ( d_domain
. find (( char ) 0 )== string :: npos
) { // embedded nulls are too noisy
146 L
<< Logger :: Error
<< "Packet purporting to come from remote server " << U32ToIP ( d_ip
)<< " contained wrong answer: '" << d_domain
<< "' != '" << mdp
. d_qname
<< "'" << endl
;
147 g_stats
. spoofedCount
++;
153 for ( MOADNSParser :: answers_t :: const_iterator i
= mdp
. d_answers
. begin (); i
!= mdp
. d_answers
. end (); ++ i
) {
154 // cout<<i->first.d_place<<"\t"<<i->first.d_label<<"\tIN\t"<<DNSRecordContent::NumberToType(i->first.d_type);
155 // cout<<"\t"<<i->first.d_ttl<<"\t"<< i->first.d_content->getZoneRepresentation()<<endl;
156 DNSResourceRecord rr
;
157 rr
. qtype
= i
-> first
. d_type
;
158 rr
. qname
= i
-> first
. d_label
;
159 rr
. ttl
= i
-> first
. d_ttl
;
160 rr
. content
= i
-> first
. d_content
-> getZoneRepresentation (); // this should be the serialised form
161 rr
. d_place
=( DNSResourceRecord :: Place
) i
-> first
. d_place
;
166 // return p.getAnswers();
168 catch ( exception
& mde
) {
169 if (:: arg (). mustDo ( "log-common-errors" ))
170 L
<< Logger :: Error
<< "Unable to parse packet from remote server: " << mde
. what ()<< endl
;
173 L
<< Logger :: Error
<< "Unknown error parsing packet from remote server" << endl
;
176 g_stats
. serverParseError
++;
179 d_rcode
= RCode :: ServFail
;