]>
Commit | Line | Data |
---|---|---|
e14f094b BH |
1 | /* |
2 | PowerDNS Versatile Database Driven Nameserver | |
d0166f4a | 3 | Copyright (C) 2002 - 2005 PowerDNS.COM BV |
e14f094b BH |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
d0166f4a BH |
6 | it under the terms of the GNU General Public License version 2 as |
7 | published by the Free Software Foundation | |
e14f094b BH |
8 | |
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. | |
13 | ||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
17 | */ | |
36c5ee42 | 18 | #include "utility.hh" |
e14f094b BH |
19 | #include "lwres.hh" |
20 | #include <pthread.h> | |
21 | #include <semaphore.h> | |
22 | #include <iostream> | |
23 | #include <errno.h> | |
24 | #include "misc.hh" | |
25 | #include <algorithm> | |
26 | #include <sstream> | |
27 | #include <cstring> | |
28 | #include <string> | |
29 | #include <vector> | |
30 | #include "dnspacket.hh" | |
31 | #include "dns.hh" | |
32 | #include "qtype.hh" | |
33 | #include "tcpreceiver.hh" | |
34 | #include "ahuexception.hh" | |
35 | #include "statbag.hh" | |
36 | #include "arguments.hh" | |
5c633640 BH |
37 | #include "sstuff.hh" |
38 | #include "syncres.hh" | |
ea634573 BH |
39 | #include "dnswriter.hh" |
40 | #include "dnsparser.hh" | |
e14f094b BH |
41 | |
42 | LWRes::LWRes() | |
43 | { | |
44 | d_sock=-1; | |
45 | d_timeout=500000; | |
b636533b BH |
46 | d_bufsize=1500; |
47 | d_buf=new unsigned char[d_bufsize]; | |
e14f094b BH |
48 | } |
49 | ||
50 | LWRes::~LWRes() | |
51 | { | |
52 | if(d_sock>=0) | |
53 | Utility::closesocket(d_sock); | |
54 | delete[] d_buf; | |
55 | } | |
56 | ||
57 | ||
58 | //! returns -1 for permanent error, 0 for timeout, 1 for success | |
59 | /** Never throws! */ | |
5c633640 | 60 | int LWRes::asyncresolve(const string &ip, const char *domain, int type, bool doTCP) |
e14f094b | 61 | { |
ea634573 BH |
62 | vector<uint8_t> vpacket; |
63 | DNSPacketWriter pw(vpacket, domain, type); | |
64 | ||
65 | pw.getHeader()->rd=0; | |
8a63d3ce | 66 | pw.getHeader()->id=random(); |
e14f094b BH |
67 | d_domain=domain; |
68 | d_type=type; | |
69 | d_inaxfr=false; | |
36f5e3db | 70 | d_rcode=0; |
e14f094b BH |
71 | |
72 | struct sockaddr_in toaddr; | |
73 | struct in_addr inp; | |
5c633640 | 74 | Utility::socklen_t addrlen=sizeof(toaddr); |
e14f094b BH |
75 | Utility::inet_aton(ip.c_str(),&inp); |
76 | toaddr.sin_addr.s_addr=inp.s_addr; | |
77 | ||
78 | toaddr.sin_port=htons(53); | |
79 | toaddr.sin_family=AF_INET; | |
80 | ||
eefd15f9 BH |
81 | int ret; |
82 | ||
83 | DTime dt; | |
84 | dt.set(); | |
5c633640 BH |
85 | |
86 | if(!doTCP) { | |
ea634573 | 87 | if(asendto((const char*)&*vpacket.begin(), vpacket.size(), 0, (struct sockaddr*)(&toaddr), sizeof(toaddr), pw.getHeader()->id)<0) { |
5c633640 BH |
88 | return -1; |
89 | } | |
90 | ||
91 | // sleep until we see an answer to this, interface to mtasker | |
92 | ||
ea634573 | 93 | ret=arecvfrom(reinterpret_cast<char *>(d_buf), d_bufsize-1,0,(struct sockaddr*)(&toaddr), &addrlen, &d_len, pw.getHeader()->id); |
e14f094b | 94 | } |
5c633640 BH |
95 | else { |
96 | Socket s(InterNetwork, Stream); | |
97 | IPEndpoint ie(ip, 53); | |
98 | s.setNonBlocking(); | |
99 | s.connect(ie); | |
100 | ||
ea634573 | 101 | unsigned int len=htons(vpacket.size()); |
5c633640 | 102 | char *lenP=(char*)&len; |
ea634573 BH |
103 | const char *msgP=(const char*)&*vpacket.begin(); |
104 | string packet=string(lenP, lenP+2)+string(msgP, msgP+vpacket.size()); | |
5c633640 BH |
105 | |
106 | if(asendtcp(packet, &s) == 0) { | |
d0166f4a BH |
107 | // cerr<<"asendtcp: timeout"<<endl; |
108 | return 0; | |
5c633640 | 109 | } |
eefd15f9 | 110 | |
5c633640 BH |
111 | packet.clear(); |
112 | if(arecvtcp(packet,2, &s)==0) { | |
d0166f4a BH |
113 | // cerr<<"arecvtcp: timeout"<<endl; |
114 | return 0; | |
5c633640 BH |
115 | } |
116 | ||
117 | memcpy(&len, packet.c_str(), 2); | |
118 | len=ntohs(len); | |
119 | ||
120 | // cerr<<"Now reading "<<len<<" bytes"<<endl; | |
121 | ||
122 | if(arecvtcp(packet, len, &s)==0) { | |
d0166f4a BH |
123 | // cerr<<"arecvtcp: timeout"<<endl; |
124 | return 0; | |
5c633640 | 125 | } |
ea634573 | 126 | if(len > (unsigned int)d_bufsize) { |
66ab6a63 BH |
127 | d_bufsize=len; |
128 | delete[] d_buf; | |
129 | d_buf = new unsigned char[d_bufsize]; | |
130 | } | |
5c633640 BH |
131 | memcpy(d_buf, packet.c_str(), len); |
132 | d_len=len; | |
133 | ret=1; | |
134 | } | |
135 | d_usec=dt.udiff(); | |
36c5ee42 | 136 | |
eefd15f9 | 137 | return ret; |
e14f094b BH |
138 | } |
139 | ||
140 | ||
eefd15f9 | 141 | LWRes::res_t LWRes::result() |
e14f094b | 142 | { |
c836dc19 | 143 | try { |
ea634573 BH |
144 | MOADNSParser mdp((const char*)d_buf, d_len); |
145 | // if(p.parse((char *)d_buf, d_len)<0) | |
146 | // throw LWResException("resolver: unable to parse packet of "+itoa(d_len)+" bytes"); | |
147 | d_aabit=mdp.d_header.aa; | |
148 | d_tcbit=mdp.d_header.tc; | |
149 | d_rcode=mdp.d_header.rcode; | |
150 | ||
ea634573 BH |
151 | LWRes::res_t ret; |
152 | for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) { | |
153 | // cout<<i->first.d_place<<"\t"<<i->first.d_label<<"\tIN\t"<<DNSRecordContent::NumberToType(i->first.d_type); | |
154 | // cout<<"\t"<<i->first.d_ttl<<"\t"<< i->first.d_content->getZoneRepresentation()<<endl; | |
155 | DNSResourceRecord rr; | |
156 | rr.qtype=i->first.d_type; | |
157 | rr.qname=i->first.d_label; | |
158 | rr.ttl=i->first.d_ttl; | |
159 | rr.content=i->first.d_content->getZoneRepresentation(); // this should be the serialised form | |
160 | ||
161 | rr.d_place=(DNSResourceRecord::Place) i->first.d_place; | |
162 | ret.push_back(rr); | |
163 | } | |
164 | ||
165 | return ret; | |
166 | // return p.getAnswers(); | |
c836dc19 BH |
167 | } |
168 | catch(...) { | |
169 | d_rcode=RCode::ServFail; | |
170 | LWRes::res_t empty; | |
171 | return empty; | |
172 | } | |
e14f094b BH |
173 | } |
174 |