1 # Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
3 # Permission to use, copy, modify, and distribute this software and its
4 # documentation for any purpose with or without fee is hereby granted,
5 # provided that the above copyright notice and this permission notice
6 # appear in all copies.
8 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 class SOA(dns.rdata.Rdata):
25 @ivar mname: the SOA MNAME (master name) field
26 @type mname: dns.name.Name object
27 @ivar rname: the SOA RNAME (responsible name) field
28 @type rname: dns.name.Name object
29 @ivar serial: The zone's serial number
31 @ivar refresh: The zone's refresh value (in seconds)
33 @ivar retry: The zone's retry value (in seconds)
35 @ivar expire: The zone's expiration value (in seconds)
37 @ivar minimum: The zone's negative caching time (in seconds, called
38 "minimum" for historical reasons)
42 __slots__ = ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire',
45 def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry,
47 super(SOA, self).__init__(rdclass, rdtype)
51 self.refresh = refresh
54 self.minimum = minimum
56 def to_text(self, origin=None, relativize=True, **kw):
57 mname = self.mname.choose_relativity(origin, relativize)
58 rname = self.rname.choose_relativity(origin, relativize)
59 return '%s %s %d %d %d %d %d' % (
60 mname, rname, self.serial, self.refresh, self.retry,
61 self.expire, self.minimum )
63 def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
64 mname = tok.get_name()
65 rname = tok.get_name()
66 mname = mname.choose_relativity(origin, relativize)
67 rname = rname.choose_relativity(origin, relativize)
68 serial = tok.get_uint32()
69 refresh = tok.get_ttl()
71 expire = tok.get_ttl()
72 minimum = tok.get_ttl()
74 return cls(rdclass, rdtype, mname, rname, serial, refresh, retry,
77 from_text = classmethod(from_text)
79 def to_wire(self, file, compress = None, origin = None):
80 self.mname.to_wire(file, compress, origin)
81 self.rname.to_wire(file, compress, origin)
82 five_ints = struct.pack('!IIIII', self.serial, self.refresh,
83 self.retry, self.expire, self.minimum)
86 def to_digestable(self, origin = None):
87 return self.mname.to_digestable(origin) + \
88 self.rname.to_digestable(origin) + \
89 struct.pack('!IIIII', self.serial, self.refresh,
90 self.retry, self.expire, self.minimum)
92 def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
93 (mname, cused) = dns.name.from_wire(wire[: current + rdlen], current)
96 (rname, cused) = dns.name.from_wire(wire[: current + rdlen], current)
100 raise dns.exception.FormError
101 five_ints = struct.unpack('!IIIII',
102 wire[current : current + rdlen])
103 if not origin is None:
104 mname = mname.relativize(origin)
105 rname = rname.relativize(origin)
106 return cls(rdclass, rdtype, mname, rname,
107 five_ints[0], five_ints[1], five_ints[2], five_ints[3],
110 from_wire = classmethod(from_wire)
112 def choose_relativity(self, origin = None, relativize = True):
113 self.mname = self.mname.choose_relativity(origin, relativize)
114 self.rname = self.rname.choose_relativity(origin, relativize)
116 def _cmp(self, other):
117 v = cmp(self.mname, other.mname)
119 v = cmp(self.rname, other.rname)
121 self_ints = struct.pack('!IIIII', self.serial, self.refresh,
122 self.retry, self.expire, self.minimum)
123 other_ints = struct.pack('!IIIII', other.serial, other.refresh,
124 other.retry, other.expire,
126 v = cmp(self_ints, other_ints)