2
$Id: Base.py,v 1.12.2.10 2008/08/01 03:58:03 customdesigned Exp $
2
$Id: Base.py,v 1.12.2.11.2.4 2011/08/04 22:53:09 customdesigned Exp $
4
4
This file is part of the pydns project.
5
5
Homepage: http://pydns.sourceforge.net
7
This code is covered by the standard Python License.
7
This code is covered by the standard Python License. See LICENSE for details.
9
9
Base functionality. Request and Response classes, that sort of thing.
91
93
args['name']=name[0]
92
if defaults['server_rotate'] and type(defaults['server']) == types.ListType:
94
if defaults['server_rotate'] and \
95
type(defaults['server']) == types.ListType:
93
96
defaults['server'] = defaults['server'][1:]+defaults['server'][:1]
94
97
for i in list(defaults.keys()):
114
117
self.args['server']=self.ns
115
118
return self.processReply()
120
def _readall(self,f,count):
122
while len(res) < count:
124
# should we restart timeout everytime we get a dribble of data?
125
rem = self.time_start + self.timeout - time.time()
126
if rem <= 0: raise DNSError('Timeout')
127
self.s.settimeout(rem)
128
buf = f.read(count - len(res))
130
raise DNSError('incomplete reply - %d of %d read' % (len(res),count))
117
134
def processTCPReply(self):
118
135
if self.timeout > 0:
119
r,w,e = select.select([self.s],[],[],self.timeout)
121
raise DNSError('Timeout')
122
f = self.s.makefile('r')
125
raise DNSError('EOF')
126
count = Lib.unpack16bit(header)
127
self.reply = f.read(count)
128
if len(self.reply) != count:
129
# FIXME: Since we are non-blocking, it could just be a large reply
130
# that we need to loop and wait for.
131
raise DNSError('incomplete reply')
136
self.s.settimeout(self.timeout)
138
self.s.settimeout(None)
139
f = self.s.makefile('rb')
141
header = self._readall(f,2)
142
count = Lib.unpack16bit(header)
143
self.reply = self._readall(f,count)
132
146
self.time_finish=time.time()
133
147
self.args['server']=self.ns
134
148
return self.processReply()
197
211
print((self.args))
198
212
raise DNSError('nothing to lookup')
199
213
qname = self.args['name']
200
if qtype == Type.AXFR:
214
if qtype == Type.AXFR and protocol != 'tcp':
201
215
print('Query type AXFR, protocol forced to TCP')
203
217
#print('QTYPE %d(%s)' % (qtype, Type.typestr(qtype)))
278
292
# FIXME: throws WOULDBLOCK if request too large to fit in
280
294
self.s.sendall(buf)
281
self.s.shutdown(socket.SHUT_WR)
295
# SHUT_WR breaks blocking IO with google DNS (8.8.8.8)
296
#self.s.shutdown(socket.SHUT_WR)
282
297
r=self.processTCPReply()
283
298
if r.header['id'] == self.tid:
284
299
self.response = r
322
337
def showResult(self,*s):
323
338
self.response.show()
340
def ParseOSXSysConfig():
341
"Retrieves the current Mac OS X resolver settings using the scutil(8) command."
343
scutil = os.popen('scutil --dns', 'r')
344
res_re = re.compile('^\s+nameserver[]0-9[]*\s*\:\s*(\S+)$')
348
l = scutil.readline()
352
if len(l) < 1 or l[0] not in string.whitespace:
357
if currentset is None:
359
sets.append(currentset)
360
currentset.append(m.group(1))
362
# Someday: Figure out if we should do something other than simply concatenate the sets.
363
for currentset in sets:
364
defaults['server'].extend(currentset)
326
367
# $Log: Base.py,v $
368
# Revision 1.12.2.11.2.4 2011/08/04 22:53:09 customdesigned
371
# Revision 1.12.2.11.2.3 2011/05/02 16:04:32 customdesigned
372
# Don't complain about AXFR protocol unless actually changing it.
373
# Reported by Ewoud Kohl van Wijngaarden.
375
# Revision 1.12.2.11.2.2 2011/03/23 01:42:07 customdesigned
376
# Changes from 2.3 branch
378
# Revision 1.12.2.11.2.1 2011/02/18 19:35:22 customdesigned
379
# Python3 updates from Scott Kitterman
327
381
# Revision 1.12.2.10 2008/08/01 03:58:03 customdesigned
328
382
# Don't try to close socket when never opened.