You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(7) |
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(1) |
Feb
|
Mar
(13) |
Apr
(10) |
May
(30) |
Jun
(2) |
Jul
(2) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
2003 |
Jan
(1) |
Feb
(1) |
Mar
(6) |
Apr
(17) |
May
(15) |
Jun
(3) |
Jul
(9) |
Aug
(2) |
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
2004 |
Jan
(3) |
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(3) |
2006 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
(2) |
Sep
(1) |
Oct
(4) |
Nov
(2) |
Dec
(7) |
2007 |
Jan
(8) |
Feb
(18) |
Mar
(5) |
Apr
(5) |
May
(16) |
Jun
(11) |
Jul
(18) |
Aug
(18) |
Sep
(15) |
Oct
(10) |
Nov
(17) |
Dec
(8) |
2008 |
Jan
(6) |
Feb
(13) |
Mar
(37) |
Apr
(18) |
May
(24) |
Jun
(14) |
Jul
(25) |
Aug
(10) |
Sep
(13) |
Oct
(8) |
Nov
|
Dec
|
From: Anthony B. <an...@in...> - 2002-03-19 12:56:23
|
How important is python 1.5.2 compatibility? given that we're just about up to the 7th release since 1.5.2, is it ditchable? opinions, anyone? Anthony |
From: Anthony B. <ant...@us...> - 2002-03-19 12:41:52
|
Update of /cvsroot/pydns/CVSROOT In directory usw-pr-cvs1:/tmp/cvs-serv27811 Modified Files: loginfo Log Message: ... and we're back. Index: loginfo =================================================================== RCS file: /cvsroot/pydns/CVSROOT/loginfo,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** loginfo 19 Mar 2002 12:36:43 -0000 1.3 --- loginfo 19 Mar 2002 12:41:49 -0000 1.4 *************** *** 27,30 **** CVSROOT $CVSROOT/CVSROOT/syncmail %{sVv} pyd...@li... ! #DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} pyd...@li... --- 27,30 ---- CVSROOT $CVSROOT/CVSROOT/syncmail %{sVv} pyd...@li... ! DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} pyd...@li... |
From: Anthony B. <ant...@us...> - 2002-03-19 12:36:47
|
Update of /cvsroot/pydns/CVSROOT In directory usw-pr-cvs1:/tmp/cvs-serv26646 Modified Files: loginfo Log Message: turn off the mailer for a moment. whitespace canonicalisation. Index: loginfo =================================================================== RCS file: /cvsroot/pydns/CVSROOT/loginfo,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** loginfo 19 Mar 2002 10:11:50 -0000 1.2 --- loginfo 19 Mar 2002 12:36:43 -0000 1.3 *************** *** 27,30 **** CVSROOT $CVSROOT/CVSROOT/syncmail %{sVv} pyd...@li... ! DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} pyd...@li... --- 27,30 ---- CVSROOT $CVSROOT/CVSROOT/syncmail %{sVv} pyd...@li... ! #DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} pyd...@li... |
From: Anthony B. <an...@in...> - 2002-03-19 12:36:04
|
Hrm. I'm going to knock off the mailer briefly, and commit code that's been tabnannied and reindented - it's been bugging me for an age or two. Rather than have massive diffs mailed to the list, I'll do the commit, then turn the mailer back on. Anthony -- Anthony Baxter <an...@in...> It's never too late to have a happy childhood. |
From: Anthony B. <ant...@us...> - 2002-03-19 12:26:18
|
Update of /cvsroot/pydns/pydns/DNS In directory usw-pr-cvs1:/tmp/cvs-serv24393 Modified Files: Base.py Class.py Opcode.py Status.py Type.py Log Message: death to leading tabs. Index: Base.py =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/Base.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Base.py 19 Mar 2002 10:30:33 -0000 1.8 --- Base.py 19 Mar 2002 12:26:13 -0000 1.9 *************** *** 135,139 **** def req(self,*name,**args): ! " needs a refactoring " import time self.argparse(name,args) --- 135,139 ---- def req(self,*name,**args): ! " needs a refactoring " import time self.argparse(name,args) *************** *** 202,207 **** if not self.async: return self.response ! else: ! return None #class DnsAsyncRequest(DnsRequest): --- 202,207 ---- if not self.async: return self.response ! else: ! return None #class DnsAsyncRequest(DnsRequest): *************** *** 209,214 **** " an asynchronous request object. out of date, probably broken " def __init__(self,*name,**args): ! DnsRequest.__init__(self, *name, **args) ! # XXX todo if args.has_key('done') and args['done']: self.donefunc=args['done'] --- 209,214 ---- " an asynchronous request object. out of date, probably broken " def __init__(self,*name,**args): ! DnsRequest.__init__(self, *name, **args) ! # XXX todo if args.has_key('done') and args['done']: self.donefunc=args['done'] *************** *** 241,244 **** --- 241,247 ---- # # $Log$ + # Revision 1.9 2002/03/19 12:26:13 anthonybaxter + # death to leading tabs. + # # Revision 1.8 2002/03/19 10:30:33 anthonybaxter # first round of major bits and pieces. The major stuff here (summarised Index: Class.py =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/Class.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Class.py 9 Aug 2001 09:08:55 -0000 1.3 --- Class.py 19 Mar 2002 12:26:13 -0000 1.4 *************** *** 1,15 **** ! # $Id$ ! # ! # This file is part of the pydns project. ! # Homepage: http://pydns.sourceforge.net ! # ! # This code is covered by the standard Python License. ! # - # CLASS values (section 3.2.4) IN = 1 # the Internet CS = 2 # the CSNET class (Obsolete - used only for examples in ! # some obsolete RFCs) CH = 3 # the CHAOS class HS = 4 # Hesiod [Dyer 87] --- 1,17 ---- ! """ ! $Id$ ! ! This file is part of the pydns project. ! Homepage: http://pydns.sourceforge.net ! ! This code is covered by the standard Python License. ! ! CLASS values (section 3.2.4) ! """ IN = 1 # the Internet CS = 2 # the CSNET class (Obsolete - used only for examples in ! # some obsolete RFCs) CH = 3 # the CHAOS class HS = 4 # Hesiod [Dyer 87] *************** *** 25,36 **** classmap = {} for _name in _names: ! if _name[0] != '_': classmap[eval(_name)] = _name def classstr(klass): ! if classmap.has_key(klass): return classmap[klass] ! else: return `klass` # # $Log$ # Revision 1.3 2001/08/09 09:08:55 anthonybaxter # added identifying header to top of each file --- 27,41 ---- classmap = {} for _name in _names: ! if _name[0] != '_': classmap[eval(_name)] = _name def classstr(klass): ! if classmap.has_key(klass): return classmap[klass] ! else: return `klass` # # $Log$ + # Revision 1.4 2002/03/19 12:26:13 anthonybaxter + # death to leading tabs. + # # Revision 1.3 2001/08/09 09:08:55 anthonybaxter # added identifying header to top of each file Index: Opcode.py =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/Opcode.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Opcode.py 9 Aug 2001 09:08:55 -0000 1.3 --- Opcode.py 19 Mar 2002 12:26:13 -0000 1.4 *************** *** 1,11 **** ! # $Id$ ! # ! # This file is part of the pydns project. ! # Homepage: http://pydns.sourceforge.net ! # ! # This code is covered by the standard Python License. ! # - # Opcode values in message header (section 4.1.1) QUERY = 0 --- 1,14 ---- ! """ ! $Id$ ! ! This file is part of the pydns project. ! Homepage: http://pydns.sourceforge.net ! ! This code is covered by the standard Python License. ! ! Opcode values in message header (section 4.1.1) ! """ ! QUERY = 0 *************** *** 26,29 **** --- 29,35 ---- # # $Log$ + # Revision 1.4 2002/03/19 12:26:13 anthonybaxter + # death to leading tabs. + # # Revision 1.3 2001/08/09 09:08:55 anthonybaxter # added identifying header to top of each file Index: Status.py =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/Status.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Status.py 9 Aug 2001 09:08:55 -0000 1.3 --- Status.py 19 Mar 2002 12:26:13 -0000 1.4 *************** *** 1,11 **** ! # $Id$ ! # ! # This file is part of the pydns project. ! # Homepage: http://pydns.sourceforge.net ! # ! # This code is covered by the standard Python License. ! # ! # Status values in message header NOERROR = 0 --- 1,12 ---- ! """ ! $Id$ ! This file is part of the pydns project. ! Homepage: http://pydns.sourceforge.net ! ! This code is covered by the standard Python License. ! ! Status values in message header ! """ NOERROR = 0 *************** *** 29,32 **** --- 30,36 ---- # # $Log$ + # Revision 1.4 2002/03/19 12:26:13 anthonybaxter + # death to leading tabs. + # # Revision 1.3 2001/08/09 09:08:55 anthonybaxter # added identifying header to top of each file Index: Type.py =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/Type.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Type.py 9 Aug 2001 09:08:55 -0000 1.4 --- Type.py 19 Mar 2002 12:26:13 -0000 1.5 *************** *** 1,11 **** ! # $Id$ ! # ! # This file is part of the pydns project. ! # Homepage: http://pydns.sourceforge.net ! # ! # This code is covered by the standard Python License. ! # ! # TYPE values (section 3.2.2) A = 1 # a host address --- 1,12 ---- ! """ ! $Id$ ! This file is part of the pydns project. ! Homepage: http://pydns.sourceforge.net ! ! This code is covered by the standard Python License. ! ! TYPE values (section 3.2.2) ! """ A = 1 # a host address *************** *** 46,56 **** typemap = {} for _name in _names: ! if _name[0] != '_': typemap[eval(_name)] = _name def typestr(type): ! if typemap.has_key(type): return typemap[type] ! else: return `type` # # $Log$ # Revision 1.4 2001/08/09 09:08:55 anthonybaxter # added identifying header to top of each file --- 47,60 ---- typemap = {} for _name in _names: ! if _name[0] != '_': typemap[eval(_name)] = _name def typestr(type): ! if typemap.has_key(type): return typemap[type] ! else: return `type` # # $Log$ + # Revision 1.5 2002/03/19 12:26:13 anthonybaxter + # death to leading tabs. + # # Revision 1.4 2001/08/09 09:08:55 anthonybaxter # added identifying header to top of each file |
From: Anthony B. <ant...@us...> - 2002-03-19 10:45:40
|
Update of /cvsroot/pydns/pydns In directory usw-pr-cvs1:/tmp/cvs-serv1507 Modified Files: .cvsignore Log Message: in theory the cvsignore in CVSROOT should catch this stuff. Index: .cvsignore =================================================================== RCS file: /cvsroot/pydns/pydns/.cvsignore,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** .cvsignore 23 Nov 2001 19:31:51 -0000 1.3 --- .cvsignore 19 Mar 2002 10:45:35 -0000 1.4 *************** *** 1,4 **** build dist - *.pyc - *.pyo --- 1,2 ---- |
From: Anthony B. <ant...@us...> - 2002-03-19 10:45:39
|
Update of /cvsroot/pydns/pydns/tests In directory usw-pr-cvs1:/tmp/cvs-serv1507/tests Modified Files: .cvsignore Log Message: in theory the cvsignore in CVSROOT should catch this stuff. Index: .cvsignore =================================================================== RCS file: /cvsroot/pydns/pydns/tests/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** .cvsignore 19 Jul 2001 06:49:18 -0000 1.1 --- .cvsignore 19 Mar 2002 10:45:36 -0000 1.2 *************** *** 1 **** - *.pyc --- 0 ---- |
From: Anthony B. <ant...@us...> - 2002-03-19 10:45:39
|
Update of /cvsroot/pydns/pydns/DNS In directory usw-pr-cvs1:/tmp/cvs-serv1507/DNS Modified Files: .cvsignore Log Message: in theory the cvsignore in CVSROOT should catch this stuff. Index: .cvsignore =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** .cvsignore 19 Jul 2001 06:51:26 -0000 1.1 --- .cvsignore 19 Mar 2002 10:45:36 -0000 1.2 *************** *** 1 **** - *.pyc --- 0 ---- |
From: Anthony B. <an...@ek...> - 2002-03-19 10:36:20
|
>>> Anthony Baxter wrote > Update of /cvsroot/pydns/pydns/tests > In directory usw-pr-cvs1:/tmp/cvs-serv29678/tests As should hopefully be obvious: a) I've pointed the CVS updates at this list b) I'm merging the changes from far too long on a plane into the CVS If the CVS messages are a problem (really, I can't imagine they will be) I can either just point them at me, or a different list. |
From: Anthony B. <ant...@us...> - 2002-03-19 10:30:37
|
Update of /cvsroot/pydns/pydns/DNS In directory usw-pr-cvs1:/tmp/cvs-serv29678/DNS Modified Files: Base.py Lib.py Log Message: first round of major bits and pieces. The major stuff here (summarised from my local, off-net CVS server :/ this will cause some oddities with the tests/testPackers.py: a large slab of unit tests for the packer and unpacker code in DNS.Lib DNS/Lib.py: placeholder for addSRV. added 'klass' to addA, make it the same as the other A* records. made addTXT check for being passed a string, turn it into a length 1 list. explicitly check for adding a string of length > 255 (prohibited). a bunch of cleanups from a first pass with pychecker new code for pack/unpack. the bitwise stuff uses struct, for a smallish (disappointly small, actually) improvement, while addr2bin is much much faster now. DNS/Base.py: added DiscoverNameServers. This automatically does the right thing on unix/ win32. No idea how MacOS handles this. *sigh* Incompatible change: Don't use ParseResolvConf on non-unix, use this function, instead! a bunch of cleanups from a first pass with pychecker Index: Base.py =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/Base.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Base.py 7 Dec 2001 21:48:34 -0000 1.7 --- Base.py 19 Mar 2002 10:30:33 -0000 1.8 *************** *** 6,20 **** This code is covered by the standard Python License. """ - import sys - import getopt import socket import string ! import DNS,DNS.Lib,DNS.Type,DNS.Class,DNS.Opcode ! #import asyncore ! defaults= { 'protocol':'udp', 'port':53, 'opcode':DNS.Opcode.QUERY, ! 'qtype':DNS.Type.A, 'rd':1, 'timing':1, 'timeout': 30 } defaults['server']=[] --- 6,21 ---- This code is covered by the standard Python License. + + Base functionality. Request and Response classes, that sort of thing. """ import socket import string ! import Lib,Type,Class,Opcode ! import asyncore ! from DNS import Error as DNSError ! defaults= { 'protocol':'udp', 'port':53, 'opcode':Opcode.QUERY, ! 'qtype':Type.A, 'rd':1, 'timing':1, 'timeout': 30 } defaults['server']=[] *************** *** 22,247 **** def ParseResolvConf(resolv_path="/etc/resolv.conf"): "parses the /etc/resolv.conf file and sets defaults for name servers" - import string, os global defaults - if os.name=="nt": - from win32dns import RegistryResolve - defaults['server']=RegistryResolve() - return - # else lines=open(resolv_path).readlines() for line in lines: ! line = string.strip(line) ! if not line or line[0]==';' or line[0]=='#': ! continue ! fields=string.split(line) ! if fields[0]=='domain': ! defaults['domain']=fields[1] ! if fields[0]=='search': ! pass ! if fields[0]=='options': ! pass ! if fields[0]=='sortlist': ! pass ! if fields[0]=='nameserver': ! defaults['server'].append(fields[1]) class DnsRequest: def __init__(self,*name,**args): ! self.donefunc=None ! self.async=None ! self.defaults = {} ! self.argparse(name,args) ! self.defaults = self.args def argparse(self,name,args): ! if not name and self.defaults.has_key('name'): ! args['name'] = self.defaults['name'] ! if type(name) is type(""): ! args['name']=name ! else: ! if len(name) == 1: ! if name[0]: ! args['name']=name[0] ! for i in defaults.keys(): ! if not args.has_key(i): ! if self.defaults.has_key(i): ! args[i]=self.defaults[i] ! else: ! args[i]=defaults[i] ! if type(args['server']) == type(''): ! args['server'] = [args['server']] ! self.args=args def socketInit(self,a,b): ! import socket ! self.s = socket.socket(a,b) def processUDPReply(self): ! import time,select ! if self.args['timeout'] > 0: ! r,w,e = select.select([self.s],[],[],self.args['timeout']) ! if not len(r): ! raise DNS.Error, 'Timeout' ! self.reply = self.s.recv(1024) ! self.time_finish=time.time() ! self.args['server']=self.ns ! return self.processReply() def processTCPReply(self): ! import time ! self.f = self.s.makefile('r') ! header = self.f.read(2) ! if len(header) < 2: ! raise DNS.Error,'EOF' ! count = DNS.Lib.unpack16bit(header) ! self.reply = self.f.read(count) ! if len(self.reply) != count: ! raise DNS.Error,'incomplete reply' ! self.time_finish=time.time() ! self.args['server']=self.ns ! return self.processReply() def processReply(self): ! import time ! self.args['elapsed']=(self.time_finish-self.time_start)*1000 ! u = DNS.Lib.Munpacker(self.reply) ! r=DNS.Lib.DnsResult(u,self.args) ! r.args=self.args ! #self.args=None # mark this DnsRequest object as used. ! return r ! #### TODO TODO TODO #### ! if protocol == 'tcp' and qtype == DNS.Type.AXFR: ! while 1: ! header = f.read(2) ! if len(header) < 2: ! print '========== EOF ==========' ! break ! count = DNS.Lib.unpack16bit(header) ! if not count: ! print '========== ZERO COUNT ==========' ! break ! print '========== NEXT ==========' ! reply = f.read(count) ! if len(reply) != count: ! print '*** Incomplete reply ***' ! break ! u = DNS.Lib.Munpacker(reply) ! DNS.Lib.dumpM(u) def conn(self): ! self.s.connect((self.ns,self.port)) def req(self,*name,**args): ! import time,sys ! self.argparse(name,args) ! #if not self.args: ! # raise DNS.Error,'reinitialize request before reuse' ! protocol = self.args['protocol'] ! self.port = self.args['port'] ! opcode = self.args['opcode'] ! rd = self.args['rd'] ! server=self.args['server'] ! if type(self.args['qtype']) == type('foo'): ! try: ! qtype = eval(string.upper(self.args['qtype']), DNS.Type.__dict__) ! except (NameError,SyntaxError): ! raise DNS.Error,'unknown query type' ! else: ! qtype=self.args['qtype'] ! if not self.args.has_key('name'): ! print self.args ! raise DNS.Error,'nothing to lookup' ! qname = self.args['name'] ! if qtype == DNS.Type.AXFR: ! print 'Query type AXFR, protocol forced to TCP' ! protocol = 'tcp' ! #print 'QTYPE %d(%s)' % (qtype, DNS.Type.typestr(qtype)) ! m = DNS.Lib.Mpacker() ! m.addHeader(0, ! 0, opcode, 0, 0, rd, 0, 0, 0, ! 1, 0, 0, 0) ! m.addQuestion(qname, qtype, DNS.Class.IN) ! self.request = m.getbuf() ! if protocol == 'udp': ! self.response=None ! self.socketInit(socket.AF_INET, socket.SOCK_DGRAM) ! for self.ns in server: ! try: ! #self.s.connect((self.ns, self.port)) ! self.conn() ! self.time_start=time.time() ! if not self.async: ! self.s.send(self.request) ! self.response=self.processUDPReply() ! #except socket.error: ! except None: ! continue ! break ! if not self.response: ! if not self.async: ! raise DNS.Error,'no working nameservers found' ! else: ! self.response=None ! for self.ns in server: ! try: ! self.socketInit(socket.AF_INET, socket.SOCK_STREAM) ! self.time_start=time.time() ! self.conn() ! self.s.send(DNS.Lib.pack16bit(len(self.request)) + self.request) ! self.s.shutdown(1) ! self.response=self.processTCPReply() ! except socket.error: ! continue ! break ! if not self.response: ! raise DNS.Error,'no working nameservers found' ! if not self.async: ! return self.response ! #class DnsAsyncRequest(DnsRequest,asyncore.dispatcher_with_send): ! class DnsAsyncRequest(DnsRequest): def __init__(self,*name,**args): ! if args.has_key('done') and args['done']: ! self.donefunc=args['done'] ! else: ! self.donefunc=self.showResult ! self.realinit(name,args) ! self.async=1 def conn(self): ! import time ! self.connect(self.ns,self.port) ! self.time_start=time.time() ! if self.args.has_key('start') and self.args['start']: ! asyncore.dispatcher.go(self) def socketInit(self,a,b): ! self.create_socket(a,b) ! asyncore.dispatcher.__init__(self) ! self.s=self def handle_read(self): ! if self.args['protocol'] == 'udp': ! self.response=self.processUDPReply() ! if self.donefunc: ! apply(self.donefunc,(self,)) def handle_connect(self): ! self.send(self.request) def handle_write(self): ! pass def showResult(self,*s): ! self.response.show() # # $Log$ ! # Revision 1.7 2001/12/07 21:48:34 stroeder ! # Module __doc__ string instead of comment lines. ! # ! # Revision 1.6 2001/12/07 21:47:33 stroeder ! # ParseResolvConf(): # ! # Assign line = string.strip(line) to avoid IndexError with parsing lines only ! # containing white-space chars. # ! # Key word parameter resolv_path for specifying path name of resolv.conf. # ! # Merge checking for empty lines and comments into one if-statement. # # Revision 1.5 2001/08/09 09:22:28 anthonybaxter --- 23,268 ---- def ParseResolvConf(resolv_path="/etc/resolv.conf"): "parses the /etc/resolv.conf file and sets defaults for name servers" global defaults lines=open(resolv_path).readlines() for line in lines: ! line = string.strip(line) ! if not line or line[0]==';' or line[0]=='#': ! continue ! fields=string.split(line) ! if fields[0]=='domain': ! defaults['domain']=fields[1] ! if fields[0]=='search': ! pass ! if fields[0]=='options': ! pass ! if fields[0]=='sortlist': ! pass ! if fields[0]=='nameserver': ! defaults['server'].append(fields[1]) ! ! def DiscoverNameServers(): ! import sys ! if sys.platform in ('win32', 'nt'): ! import win32dns ! defaults['server']=win32dns.RegistryResolve() ! else: ! return ParseResolvConf() class DnsRequest: + """ high level Request object """ def __init__(self,*name,**args): ! self.donefunc=None ! self.async=None ! self.defaults = {} ! self.argparse(name,args) ! self.defaults = self.args def argparse(self,name,args): ! if not name and self.defaults.has_key('name'): ! args['name'] = self.defaults['name'] ! if type(name) is type(""): ! args['name']=name ! else: ! if len(name) == 1: ! if name[0]: ! args['name']=name[0] ! for i in defaults.keys(): ! if not args.has_key(i): ! if self.defaults.has_key(i): ! args[i]=self.defaults[i] ! else: ! args[i]=defaults[i] ! if type(args['server']) == type(''): ! args['server'] = [args['server']] ! self.args=args def socketInit(self,a,b): ! self.s = socket.socket(a,b) def processUDPReply(self): ! import time,select ! if self.args['timeout'] > 0: ! r,w,e = select.select([self.s],[],[],self.args['timeout']) ! if not len(r): ! raise DNSError, 'Timeout' ! self.reply = self.s.recv(1024) ! self.time_finish=time.time() ! self.args['server']=self.ns ! return self.processReply() def processTCPReply(self): ! import time ! self.f = self.s.makefile('r') ! header = self.f.read(2) ! if len(header) < 2: ! raise DNSError,'EOF' ! count = Lib.unpack16bit(header) ! self.reply = self.f.read(count) ! if len(self.reply) != count: ! raise DNSError,'incomplete reply' ! self.time_finish=time.time() ! self.args['server']=self.ns ! return self.processReply() def processReply(self): ! self.args['elapsed']=(self.time_finish-self.time_start)*1000 ! u = Lib.Munpacker(self.reply) ! r=Lib.DnsResult(u,self.args) ! r.args=self.args ! #self.args=None # mark this DnsRequest object as used. ! return r ! #### TODO TODO TODO #### ! # if protocol == 'tcp' and qtype == Type.AXFR: ! # while 1: ! # header = f.read(2) ! # if len(header) < 2: ! # print '========== EOF ==========' ! # break ! # count = Lib.unpack16bit(header) ! # if not count: ! # print '========== ZERO COUNT ==========' ! # break ! # print '========== NEXT ==========' ! # reply = f.read(count) ! # if len(reply) != count: ! # print '*** Incomplete reply ***' ! # break ! # u = Lib.Munpacker(reply) ! # Lib.dumpM(u) def conn(self): ! self.s.connect((self.ns,self.port)) def req(self,*name,**args): ! " needs a refactoring " ! import time ! self.argparse(name,args) ! #if not self.args: ! # raise DNSError,'reinitialize request before reuse' ! protocol = self.args['protocol'] ! self.port = self.args['port'] ! opcode = self.args['opcode'] ! rd = self.args['rd'] ! server=self.args['server'] ! if type(self.args['qtype']) == type('foo'): ! try: ! qtype = eval(string.upper(self.args['qtype']),Type.__dict__) ! except (NameError,SyntaxError): ! raise DNSError,'unknown query type' ! else: ! qtype=self.args['qtype'] ! if not self.args.has_key('name'): ! print self.args ! raise DNSError,'nothing to lookup' ! qname = self.args['name'] ! if qtype == Type.AXFR: ! print 'Query type AXFR, protocol forced to TCP' ! protocol = 'tcp' ! #print 'QTYPE %d(%s)' % (qtype, Type.typestr(qtype)) ! m = Lib.Mpacker() ! m.addHeader(0, ! 0, opcode, 0, 0, rd, 0, 0, 0, ! 1, 0, 0, 0) ! m.addQuestion(qname, qtype, Class.IN) ! self.request = m.getbuf() ! if protocol == 'udp': ! self.response=None ! self.socketInit(socket.AF_INET, socket.SOCK_DGRAM) ! for self.ns in server: ! try: ! #self.s.connect((self.ns, self.port)) ! self.conn() ! self.time_start=time.time() ! if not self.async: ! self.s.send(self.request) ! self.response=self.processUDPReply() ! #except socket.error: ! except None: ! continue ! break ! if not self.response: ! if not self.async: ! raise DNSError,'no working nameservers found' ! else: ! self.response=None ! for self.ns in server: ! try: ! self.socketInit(socket.AF_INET, socket.SOCK_STREAM) ! self.time_start=time.time() ! self.conn() ! self.s.send(Lib.pack16bit(len(self.request)) + ! self.request) ! self.s.shutdown(1) ! self.response=self.processTCPReply() ! except socket.error: ! continue ! break ! if not self.response: ! raise DNSError,'no working nameservers found' ! if not self.async: ! return self.response ! else: ! return None ! #class DnsAsyncRequest(DnsRequest): ! class DnsAsyncRequest(DnsRequest,asyncore.dispatcher_with_send): ! " an asynchronous request object. out of date, probably broken " def __init__(self,*name,**args): ! DnsRequest.__init__(self, *name, **args) ! # XXX todo ! if args.has_key('done') and args['done']: ! self.donefunc=args['done'] ! else: ! self.donefunc=self.showResult ! #self.realinit(name,args) # XXX todo ! self.async=1 def conn(self): ! import time ! self.connect((self.ns,self.port)) ! self.time_start=time.time() ! if self.args.has_key('start') and self.args['start']: ! asyncore.dispatcher.go(self) def socketInit(self,a,b): ! self.create_socket(a,b) ! asyncore.dispatcher.__init__(self) ! self.s=self def handle_read(self): ! if self.args['protocol'] == 'udp': ! self.response=self.processUDPReply() ! if self.donefunc: ! apply(self.donefunc,(self,)) def handle_connect(self): ! self.send(self.request) def handle_write(self): ! pass def showResult(self,*s): ! self.response.show() # # $Log$ ! # Revision 1.8 2002/03/19 10:30:33 anthonybaxter ! # first round of major bits and pieces. The major stuff here (summarised ! # from my local, off-net CVS server :/ this will cause some oddities with ! # the # ! # tests/testPackers.py: ! # a large slab of unit tests for the packer and unpacker code in DNS.Lib # ! # DNS/Lib.py: ! # placeholder for addSRV. ! # added 'klass' to addA, make it the same as the other A* records. ! # made addTXT check for being passed a string, turn it into a length 1 list. ! # explicitly check for adding a string of length > 255 (prohibited). ! # a bunch of cleanups from a first pass with pychecker ! # new code for pack/unpack. the bitwise stuff uses struct, for a smallish ! # (disappointly small, actually) improvement, while addr2bin is much ! # much faster now. # ! # DNS/Base.py: ! # added DiscoverNameServers. This automatically does the right thing ! # on unix/ win32. No idea how MacOS handles this. *sigh* ! # Incompatible change: Don't use ParseResolvConf on non-unix, use this ! # function, instead! ! # a bunch of cleanups from a first pass with pychecker # # Revision 1.5 2001/08/09 09:22:28 anthonybaxter Index: Lib.py =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/Lib.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Lib.py 9 Aug 2001 09:08:55 -0000 1.8 --- Lib.py 19 Mar 2002 10:30:33 -0000 1.9 *************** *** 1,2 **** --- 1,5 ---- + """ + Library code. Largely this is packers and unpackers for various types. + """ # Domain Name Server (DNS) interface # *************** *** 20,60 **** # ------------------------------------------------------------------------ [...1212 lines suppressed...] + # + # DNS/Lib.py: + # placeholder for addSRV. + # added 'klass' to addA, make it the same as the other A* records. + # made addTXT check for being passed a string, turn it into a length 1 list. + # explicitly check for adding a string of length > 255 (prohibited). + # a bunch of cleanups from a first pass with pychecker + # new code for pack/unpack. the bitwise stuff uses struct, for a smallish + # (disappointly small, actually) improvement, while addr2bin is much + # much faster now. + # + # DNS/Base.py: + # added DiscoverNameServers. This automatically does the right thing + # on unix/ win32. No idea how MacOS handles this. *sigh* + # Incompatible change: Don't use ParseResolvConf on non-unix, use this + # function, instead! + # a bunch of cleanups from a first pass with pychecker + # # Revision 1.8 2001/08/09 09:08:55 anthonybaxter # added identifying header to top of each file |
From: Anthony B. <ant...@us...> - 2002-03-19 10:30:37
|
Update of /cvsroot/pydns/pydns/tests In directory usw-pr-cvs1:/tmp/cvs-serv29678/tests Modified Files: testPackers.py Log Message: first round of major bits and pieces. The major stuff here (summarised from my local, off-net CVS server :/ this will cause some oddities with the tests/testPackers.py: a large slab of unit tests for the packer and unpacker code in DNS.Lib DNS/Lib.py: placeholder for addSRV. added 'klass' to addA, make it the same as the other A* records. made addTXT check for being passed a string, turn it into a length 1 list. explicitly check for adding a string of length > 255 (prohibited). a bunch of cleanups from a first pass with pychecker new code for pack/unpack. the bitwise stuff uses struct, for a smallish (disappointly small, actually) improvement, while addr2bin is much much faster now. DNS/Base.py: added DiscoverNameServers. This automatically does the right thing on unix/ win32. No idea how MacOS handles this. *sigh* Incompatible change: Don't use ParseResolvConf on non-unix, use this function, instead! a bunch of cleanups from a first pass with pychecker Index: testPackers.py =================================================================== RCS file: /cvsroot/pydns/pydns/tests/testPackers.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** testPackers.py 10 Aug 2001 00:13:35 -0000 1.2 --- testPackers.py 19 Mar 2002 10:30:33 -0000 1.3 *************** *** 5,15 **** # # only tests the simple packers for now. next is to test the ! # classes: Packer/Unpacker, RRpacker/RRunpacker, Hpacker/Hunpacker, # Qpacker/Unpacker, then Mpacker/Munpacker # import DNS import unittest class Int16Packing(unittest.TestCase): knownValues = ( ( 10, '\x00\n'), --- 5,19 ---- # # only tests the simple packers for now. next is to test the ! # classes: Hpacker/Hunpacker, # Qpacker/Unpacker, then Mpacker/Munpacker # + # Start doing unpleasant tests with broken data, truncations, that + # sort of thing. import DNS import unittest + TestCompleted = "TestCompleted" # exc. + class Int16Packing(unittest.TestCase): knownValues = ( ( 10, '\x00\n'), *************** *** 75,81 **** self.assertEqual(i,result) ! # more to come... --- 79,368 ---- self.assertEqual(i,result) + class PackerClassPacking(unittest.TestCase): + knownPackValues = [ + ( ['www.ekit.com'], '\x03www\x04ekit\x03com\x00' ), + ( ['ns1.ekorp.com', 'ns2.ekorp.com', 'ns3.ekorp.com'], + '\x03ns1\x05ekorp\x03com\x00\x03ns2\xc0\x04\x03ns3\xc0\x04'), + ( ['a.root-servers.net.', 'b.root-servers.net.', + 'c.root-servers.net.', 'd.root-servers.net.', + 'e.root-servers.net.', 'f.root-servers.net.'], + '\x01a\x0croot-servers\x03net\x00\x01b\xc0\x02\x01c\xc0'+ + '\x02\x01d\xc0\x02\x01e\xc0\x02\x01f\xc0\x02' ), + ] + knownUnpackValues = [ + ( ['www.ekit.com'], '\x03www\x04ekit\x03com\x00' ), + ( ['ns1.ekorp.com', 'ns2.ekorp.com', 'ns3.ekorp.com'], + '\x03ns1\x05ekorp\x03com\x00\x03ns2\xc0\x04\x03ns3\xc0\x04'), + ( ['a.root-servers.net', 'b.root-servers.net', + 'c.root-servers.net', 'd.root-servers.net', + 'e.root-servers.net', 'f.root-servers.net'], + '\x01a\x0croot-servers\x03net\x00\x01b\xc0\x02\x01c\xc0'+ + '\x02\x01d\xc0\x02\x01e\xc0\x02\x01f\xc0\x02' ), + ] ! def testPackNames(self): ! from DNS.Lib import Packer ! for namelist,result in self.knownPackValues: ! p = Packer() ! for n in namelist: ! p.addname(n) ! self.assertEqual(p.getbuf(),result) ! ! def testUnpackNames(self): ! from DNS.Lib import Unpacker ! for namelist,result in self.knownUnpackValues: ! u = Unpacker(result) ! names = [] ! for i in range(len(namelist)): ! n = u.getname() ! names.append(n) ! self.assertEqual(names, namelist) ! ! def testUnpackerLimitCheck(self): ! from DNS.Lib import Unpacker ! u=Unpacker('\x03ns1\x05ekorp\x03com\x00\x03ns2\xc0\x04\x03ns3\xc0\x04') ! u.getname() ; u.getname() ; u.getname() ! # 4th call should fail ! self.assertRaises(IndexError, u.getname) ! ! class testUnpackingMangled(unittest.TestCase): ! "addA(self, name, klass, ttl, address)" ! packerCorrect = '\x05www02\x04ekit\x03com\x00\x00\x01\x00\x01\x00\x01Q\x80\x00\x04\xc0\xa8\n\x02' ! def testWithoutRR(self): ! u = DNS.Lib.RRunpacker(self.packerCorrect) ! u.getAdata() ! def testWithTwoRRs(self): ! u = DNS.Lib.RRunpacker(self.packerCorrect) ! u.getRRheader() ! self.assertRaises(DNS.Lib.UnpackError, u.getRRheader) ! def testWithNoGetData(self): ! u = DNS.Lib.RRunpacker(self.packerCorrect) ! u.getRRheader() ! self.assertRaises(DNS.Lib.UnpackError, u.endRR) ! ! class PackerTestCase(unittest.TestCase): ! " base class for tests of Packing code. Laziness on my part, I know. " ! def testPacker(self): ! from DNS.Lib import RRpacker ! p = RRpacker() ! check = self.doPack(p) ! if (p is not None) and (check is not TestCompleted): ! return self.checkPackResult(p) ! ! def checkPackResult(self, buf): ! if not hasattr(self, 'packerExpectedResult'): ! if self.__class__.__name__ != 'PackerTestCase': ! print "P***", self, repr(buf.getbuf()) #cheat testcase ! else: ! return self.assertEqual(buf.getbuf(), ! self.packerExpectedResult) ! ! def checkUnpackResult(self, rrbits, specbits): ! if not hasattr(self, 'unpackerExpectedResult'): ! if self.__class__.__name__ != 'PackerTestCase': ! print "U***", self, repr((rrbits,specbits)) #cheat testcase ! else: ! return self.assertEqual((rrbits, specbits), ! self.unpackerExpectedResult) + def testUnpacker(self): + from DNS.Lib import RRunpacker + if self.doUnpack is not None: + if hasattr(self.__class__, 'doUnpack') \ + and hasattr(self, 'packerExpectedResult'): + u = RRunpacker(self.packerExpectedResult) + rrbits = u.getRRheader()[:4] + specbits = self.doUnpack(u) + try: + u.endRR() + except DNS.Lib.UnpackError: + self.assertEqual(0, 'Not at end of RR!') + return self.checkUnpackResult(rrbits, specbits) + else: + me = self.__class__.__name__ + if me != 'PackerTestCase': + self.assertEquals(self.__class__.__name__, + 'Unpack NotImplemented') + + def doPack(self, p): + " stub. don't test the base class " + return None + + def doUnpack(self, p): + " stub. don't test the base class " + return None + + + + class testPackingOfCNAME(PackerTestCase): + "addCNAME(self, name, klass, ttl, cname)" + def doPack(self,p): + p.addCNAME('www.sub.domain', DNS.Class.IN, 3600, 'realhost.sub.domain') + def doUnpack(self, u): + return u.getCNAMEdata() + + unpackerExpectedResult = (('www.sub.domain', DNS.Type.CNAME, DNS.Class.IN, 3600), 'realhost.sub.domain') + packerExpectedResult = \ + '\x03www\x03sub\x06domain\x00\x00\x05\x00\x01\x00'+ \ + '\x00\x0e\x10\x00\x0b\x08realhost\xc0\x04' + + class testPackingOfCNAME2(PackerTestCase): + "addCNAME(self, name, klass, ttl, cname)" + def doPack(self,p): + p.addCNAME('www.cust.com', DNS.Class.IN, 200, 'www023.big.isp.com') + def doUnpack(self, u): + return u.getCNAMEdata() + unpackerExpectedResult = (('www.cust.com', DNS.Type.CNAME, DNS.Class.IN, 200), 'www023.big.isp.com') + packerExpectedResult = \ + '\x03www\x04cust\x03com\x00\x00\x05\x00\x01\x00'+ \ + '\x00\x00\xc8\x00\x11\x06www023\x03big\x03isp\xc0\t' + + class testPackingOfCNAME3(PackerTestCase): + "addCNAME(self, name, klass, ttl, cname)" + def doPack(self,p): + p.addCNAME('www.fred.com', DNS.Class.IN, 86400, 'webhost.loa.com') + def doUnpack(self, u): + return u.getCNAMEdata() + unpackerExpectedResult = (('www.fred.com', DNS.Type.CNAME, DNS.Class.IN, 86400), 'webhost.loa.com') + packerExpectedResult = \ + '\x03www\x04fred\x03com\x00\x00\x05\x00\x01\x00\x01Q'+ \ + '\x80\x00\x0e\x07webhost\x03loa\xc0\t' + + class testPackingOfHINFO(PackerTestCase): + "addHINFO(self, name, klass, ttl, cpu, os)" + def doPack(self,p): + p.addHINFO('www.sub.domain.com', DNS.Class.IN, 3600, 'i686', 'linux') + def doUnpack(self, u): + return u.getHINFOdata() + unpackerExpectedResult = (('www.sub.domain.com', 13, 1, 3600), ('i686', 'linux')) + packerExpectedResult = \ + '\x03www\x03sub\x06domain\x03com\x00\x00\r\x00\x01'+ \ + '\x00\x00\x0e\x10\x00\x0b\x04i686\x05linux' + + class testPackingOfHINFO2(PackerTestCase): + "addHINFO(self, name, klass, ttl, cpu, os)" + def doPack(self,p): + p.addHINFO('core1.lax.foo.com', DNS.Class.IN, 3600, 'cisco', 'ios') + def doUnpack(self, u): + return u.getHINFOdata() + unpackerExpectedResult = (('core1.lax.foo.com', 13, 1, 3600), ('cisco', 'ios')) + packerExpectedResult = \ + '\x05core1\x03lax\x03foo\x03com\x00\x00\r\x00\x01'+ \ + '\x00\x00\x0e\x10\x00\n\x05cisco\x03ios' + + class testPackingOfMX(PackerTestCase): + "addMX(self, name, klass, ttl, preference, exchange)" + def doPack(self, p): + p.addMX('sub.domain.com', DNS.Class.IN, 86400, 10, 'mailhost1.isp.com') + def doUnpack(self, u): + return u.getMXdata() + packerExpectedResult = \ + '\x03sub\x06domain\x03com\x00\x00\x0f\x00\x01'+ \ + '\x00\x01Q\x80\x00\x12\x00\n\tmailhost1\x03isp\xc0\x0b' + unpackerExpectedResult = (('sub.domain.com', 15, 1, 86400), (10, 'mailhost1.isp.com')) + + class testPackingOfMX2(PackerTestCase): + "addMX(self, name, klass, ttl, preference, exchange)" + def doPack(self, p): + p.addMX('ekit-inc.com.', DNS.Class.IN, 86400, 10, 'mx1.ekorp.com') + p.addMX('ekit-inc.com.', DNS.Class.IN, 86400, 20, 'mx2.ekorp.com') + p.addMX('ekit-inc.com.', DNS.Class.IN, 86400, 30, 'mx3.ekorp.com') + def doUnpack(self, u): + res = [u.getMXdata(),] + dummy = u.getRRheader()[:4] + res += u.getMXdata() + dummy = u.getRRheader()[:4] + res += u.getMXdata() + return res + unpackerExpectedResult = (('ekit-inc.com', 15, 1, 86400), [(10, 'mx1.ekorp.com'), 20, 'mx2.ekorp.com', 30, 'mx3.ekorp.com']) + packerExpectedResult = \ + '\x08ekit-inc\x03com\x00\x00\x0f\x00\x01\x00\x01Q\x80\x00'+\ + '\x0e\x00\n\x03mx1\x05ekorp\xc0\t\x00\x00\x0f\x00\x01\x00'+\ + '\x01Q\x80\x00\x08\x00\x14\x03mx2\xc0\x1e\x00\x00\x0f\x00'+\ + '\x01\x00\x01Q\x80\x00\x08\x00\x1e\x03mx3\xc0\x1e' + + class testPackingOfNS(PackerTestCase): + "addNS(self, name, klass, ttl, nsdname)" + def doPack(self, p): + p.addNS('ekit-inc.com', DNS.Class.IN, 86400, 'ns1.ekorp.com') + def doUnpack(self, u): + return u.getNSdata() + unpackerExpectedResult = (('ekit-inc.com', 2, 1, 86400), 'ns1.ekorp.com') + packerExpectedResult = '\x08ekit-inc\x03com\x00\x00\x02\x00\x01\x00\x01Q\x80\x00\x0c\x03ns1\x05ekorp\xc0\t' + + class testPackingOfPTR(PackerTestCase): + "addPTR(self, name, klass, ttl, ptrdname)" + def doPack(self, p): + p.addPTR('www.ekit-inc.com', DNS.Class.IN, 3600, 'www-real01.ekorp.com') + def doUnpack(self, u): + return u.getPTRdata() + unpackerExpectedResult = (('www.ekit-inc.com', 12, 1, 3600), 'www-real01.ekorp.com') + packerExpectedResult = '\x03www\x08ekit-inc\x03com\x00\x00\x0c\x00\x01\x00\x00\x0e\x10\x00\x13\nwww-real01\x05ekorp\xc0\r' + + class testPackingOfSOA(PackerTestCase): + """addSOA(self, name, klass, ttl, mname, + rname, serial, refresh, retry, expire, minimum)""" + def doPack(self, p): + p.addSOA('ekit-inc.com', DNS.Class.IN, 3600, 'ns1.ekorp.com', + 'hostmaster.ekit-inc.com', 2002020301, 100, 200, 300, 400) + def doUnpack(self, u): + return u.getSOAdata() + unpackerExpectedResult = (('ekit-inc.com', 6, 1, 3600), ('ns1.ekorp.com', 'hostmaster', ('serial', 2002020301), ('refresh ', 100, '1 minutes'), ('retry', 200, '3 minutes'), ('expire', 300, '5 minutes'), ('minimum', 400, '6 minutes'))) + packerExpectedResult = '\x08ekit-inc\x03com\x00\x00\x06\x00\x01\x00\x00\x0e\x10\x00,\x03ns1\x05ekorp\xc0\t\nhostmaster\x00wTg\xcd\x00\x00\x00d\x00\x00\x00\xc8\x00\x00\x01,\x00\x00\x01\x90' + + + class testPackingOfA(PackerTestCase): + "addA(self, name, klass, ttl, address)" + def doPack(self, p): + p.addA('www02.ekit.com', DNS.Class.IN, 86400, '192.168.10.2') + def doUnpack(self, u): + return u.getAdata() + unpackerExpectedResult = (('www02.ekit.com', 1, 1, 86400), '192.168.10.2') + packerExpectedResult = '\x05www02\x04ekit\x03com\x00\x00\x01\x00\x01\x00\x01Q\x80\x00\x04\xc0\xa8\n\x02' + + class testPackingOfA2(PackerTestCase): + "addA(self, name, ttl, address)" + def doPack(self, p): + p.addA('www.ekit.com', DNS.Class.IN, 86400, '10.98.1.0') + def doUnpack(self, u): + return u.getAdata() + unpackerExpectedResult = (('www.ekit.com', 1, 1, 86400), '10.98.1.0') + packerExpectedResult = '\x03www\x04ekit\x03com\x00\x00\x01\x00\x01\x00\x01Q\x80\x00\x04\nb\x01\x00' + + class testPackingOfA3(PackerTestCase): + "addA(self, name, ttl, address)" + def doPack(self, p): + p.addA('www.zol.com', DNS.Class.IN, 86400, '192.168.10.4') + p.addA('www.zol.com', DNS.Class.IN, 86400, '192.168.10.3') + p.addA('www.zol.com', DNS.Class.IN, 86400, '192.168.10.2') + p.addA('www.zol.com', DNS.Class.IN, 86400, '192.168.10.1') + def doUnpack(self, u): + u1,d1,u2,d2,u3,d3,u4=u.getAdata(),u.getRRheader(),u.getAdata(),u.getRRheader(),u.getAdata(),u.getRRheader(),u.getAdata() + return u1,u2,u3,u4 + unpackerExpectedResult = (('www.zol.com', 1, 1, 86400), ('192.168.10.4', '192.168.10.3', '192.168.10.2', '192.168.10.1')) + packerExpectedResult = '\x03www\x03zol\x03com\x00\x00\x01\x00\x01\x00\x01Q\x80\x00\x04\xc0\xa8\n\x04\x00\x00\x01\x00\x01\x00\x01Q\x80\x00\x04\xc0\xa8\n\x03\x00\x00\x01\x00\x01\x00\x01Q\x80\x00\x04\xc0\xa8\n\x02\x00\x00\x01\x00\x01\x00\x01Q\x80\x00\x04\xc0\xa8\n\x01' + + class testPackingOfTXT(PackerTestCase): + "addTXT(self, name, klass, ttl, list)" + def doPack(self, p): + p.addTXT('ekit-inc.com', DNS.Class.IN, 3600, 'this is a text record') + def doUnpack(self, u): + return u.getTXTdata() + packerExpectedResult = '\x08ekit-inc\x03com\x00\x00\x10\x00\x01\x00\x00\x0e\x10\x00\x16\x15this is a text record' + unpackerExpectedResult = (('ekit-inc.com', 16, 1, 3600), ['this is a text record']) + + # check what the maximum/minimum &c of TXT records are. + class testPackingOfTXT2(PackerTestCase): + "addTXT(self, name, klass, ttl, list)" + def doPack(self, p): + f = lambda p=p:p.addTXT('ekit-inc.com', DNS.Class.IN, 3600, 'the quick brown fox jumped over the lazy brown dog\n'*20) + self.assertRaises(ValueError, f) + return TestCompleted + doUnpack = None + + #class testPackingOfQuestion(PackerTestCase): + # "addQuestion(self, qname, qtype, qclass)" + # def doPack(self, p): + # self.assertEquals(0,"NotImplemented") |
From: David T. <db...@me...> - 2002-01-30 02:54:37
|
First cut. It uses a tuple of 4 integers as the intermediate step (get128bits()). It does rfc1884 2.2 address compression (0:0:0:0:0:0:0:1 -> ::1). It does not have the necessary code to do the reverse, yet, or reverse DNS in lazy.py. That's coming soon. Index: DNS/Lib.py =================================================================== RCS file: /cvsroot/pydns/pydns/DNS/Lib.py,v retrieving revision 1.8 diff -u -r1.8 Lib.py --- DNS/Lib.py 2001/08/09 09:08:55 1.8 +++ DNS/Lib.py 2002/01/30 02:37:39 @@ -37,6 +37,16 @@ return chr((n>>24)&0xFF) + chr((n>>16)&0xFF) \ + chr((n>>8)&0xFF) + chr(n&0xFF) +def pack128bit(t): + return chr(chr(t[0]>>24)&0xFF) + chr((t[0]>>16)&0xFF) \ + + chr((t[0]>>8)&0xFF) + chr(t[0]&0xFF) \ + + chr((t[1]>>24)&0xFF) + chr((t[1]>>16)&0xFF) \ + + chr((t[1]>>8)&0xFF) + chr(t[1]&0xFF) \ + + chr((t[2]>>24)&0xFF) + chr((t[2]>>16)&0xFF) \ + + chr((t[2]>>8)&0xFF) + chr(t[2]&0xFF) \ + + chr((t[3]>>24)&0xFF) + chr((t[3]>>16)&0xFF) \ + + chr((t[3]>>8)&0xFF) + chr(t[3]&0xFF) + def unpack16bit(s): return (ord(s[0])<<8) | ord(s[1]) @@ -44,6 +54,17 @@ return (ord(s[0])<<24) | (ord(s[1])<<16) \ | (ord(s[2])<<8) | ord(s[3]) +def unpack128bit(s): + # tuple of 4 32 bit values + return(((ord(s[0])<<24) | (ord(s[1])<<16) \ + | (ord(s[2])<<8) | ord(s[3])), + ((ord(s[4])<<24) | (ord(s[5])<<16) \ + | (ord(s[6])<<8) | ord(s[7])), + ((ord(s[8])<<24) | (ord(s[9])<<16) \ + | (ord(s[10])<<8) | ord(s[11])), + ((ord(s[12])<<24) | (ord(s[13])<<16) \ + | (ord(s[14])<<8) | ord(s[15]))) + def addr2bin(addr): if type(addr) == type(0): return addr @@ -57,7 +78,26 @@ return '%d.%d.%d.%d' % ((n>>24)&0xFF, (n>>16)&0xFF, (n>>8)&0xFF, n&0xFF) - +def bin2addr6(t): + comp = 0 # 0 - no compression yet, 1 - compressing, 2 - already compressed + mask = (0xffff0000,0xffff) + shift = (16, 0) + ret = '' + for n in 0,1,2,3: + for sub in 0,1: + if comp < 2 and ((t[n] & mask[sub])==0): + # and skip it + comp = 1 + else: + if(comp==1): + comp=2 + ret += ':' + if(ret): + ret += ':' + ret += '%x' % (((t[n] & mask[sub]) >> shift[sub]) & 0xFFFF) + + return(ret) + # Packing class class Packer: @@ -168,8 +208,12 @@ return unpack16bit(self.getbytes(2)) def get32bit(self): return unpack32bit(self.getbytes(4)) + def get128bit(self): + return unpack128bit(self.getbytes(16)) def getaddr(self): return bin2addr(self.get32bit()) + def getaddr6(self): + return bin2addr6(self.get128bit()) def getstring(self): return self.getbytes(ord(self.getbyte())) def getname(self): @@ -386,6 +430,8 @@ return list def getAdata(self): return self.getaddr() + def getAAAAdata(self): + return self.getaddr6() def getWKSdata(self): address = self.getaddr() protocol = ord(self.getbyte()) -- David Terrell | "the only part about medicinal marijuana that Prime Minister, Nebcorp | bothers me is that, when I started chemo, all of db...@me... | my children and grandchildren told me they could http://wwn.nebcorp.com/ | get some for me if I needed it." -mrw's grandfather |
From: Anthony B. <an...@in...> - 2001-08-09 11:52:30
|
>>> Anthony Baxter wrote > We talked before about unit tests, and how it's difficult because > the test data changes around a bit (as servers move &c.) I realised on the way home that at least for things like the packers and unpackers, this isn't the case. We can provide the data "as it came off the wire" and use that to test with. Duh. Me not thinking goodly. Anthony. -- Anthony Baxter <an...@in...> It's never too late to have a happy childhood. |
From: Michael <mi...@st...> - 2001-08-09 10:11:22
|
Anthony Baxter wrote: > > > If you don't mind I will stuff the relevant RFCs in section > > "related" on http://pydns.sourceforge.net/docs.shtml. > > That's fine - I was thinking of making a checklist of which > ones we have and haven't got support for, as well as which > aren't relevant. I've added a link to RFC2052 (SRV RRs). I'd suggest using links to http://www.ietf.org/rfc/. > DNS related RFCs are at http://www.dns.net/dnsrd/rfc/ > > Browsing the list, I notice DNSSEC. That's gotta be good for a giggle. > Wonder how horrible it is to implement? Do you have much spare time...? ;-) Ciao, Michael. |
From: Anthony B. <an...@in...> - 2001-08-09 09:49:57
|
[starting a different thread for each major topic - I find it's easier this way to keep track of stuff] We talked before about unit tests, and how it's difficult because the test data changes around a bit (as servers move &c.) A couple of ways we could handle this: 1. Make the test suite call (and parse!) "dig" or similar to get a set of current test data. Only works on unix. Oh well. 2. Make a different script that generates the test data and gets run automatically from cron and makes the test data available on the pydns website. Better, but probably more work. Still has a window of opportunity for it to be broken. 3. Just ignore the problem and leave it as something that might change, sometimes, and that the developers and anyone who wants to run the suite will just have to Just Deal With. 4. Don't bother with unit tests (booo!) Anthony |
From: Anthony B. <an...@in...> - 2001-08-09 09:38:50
|
> If you don't mind I will stuff the relevant RFCs in section > "related" on http://pydns.sourceforge.net/docs.shtml. That's fine - I was thinking of making a checklist of which ones we have and haven't got support for, as well as which aren't relevant. DNS related RFCs are at http://www.dns.net/dnsrd/rfc/ Browsing the list, I notice DNSSEC. That's gotta be good for a giggle. Wonder how horrible it is to implement? |
From: Michael <mi...@st...> - 2001-08-09 09:29:18
|
Anthony Baxter wrote: > > I was going to have a hunt for DNS-relevant RFCs > and have a 'Supported' page to list which ones are and aren't listed. If you don't mind I will stuff the relevant RFCs in section "related" on http://pydns.sourceforge.net/docs.shtml. Ciao, Michael. |
From: Anthony B. <an...@in...> - 2001-08-09 09:26:47
|
> > can you edit the default index.shtml to have a link to the project page? > The SourceForge icon points to the project page. Hmm, maybe to > unusal? It was for me. I thought that would go to the SF front page. Anyway, I just put the win32dns stuff in place. Going to try and figure out a way to get the CVS checkout onto my windows box at home to check it works ok. Anthony |
From: Anthony B. <an...@in...> - 2001-08-09 09:24:24
|
resending this, because I'm a twonk and sent it to the wrong address first time round. archiving it. ----- opened on 2001-07-19 closed on 2001-08-09 Guess the SF guys are having a busy time. Anyway, it's in and working, and I can do commits fine (I just bolted a generic header to each file). Anyway, on to stuff to do: can you edit the default index.shtml to have a link to the project page? otherwise I can do it... I was going to have a hunt for DNS-relevant RFCs and have a 'Supported' page to list which ones are and aren't listed. Hm, might code a double-reverse-lookup(-with-a-twist-of-lemon) as another one for the DNS/lazy.py module - it's something I've done often enough. Anthony - -- Anthony Baxter <an...@in...> It's never too late to have a happy childhood. ------- End of Forwarded Message |