/home/lnzliplg/www/dns.zip
PKi�\��Yҹu�u%__pycache__/zone.cpython-36.opt-1.pycnu�[���3

ӕ�WZ��@sNdZddlmZddlZddlZddlZddlmZddlZ	ddl
Z	ddlZ	ddlZ	ddl
Z	ddlZ	ddlZ	ddlZ	ddlZ	ddlZ	ddlmZmZejdkZGdd	�d	e	jj�ZGd
d�de�ZGdd
�d
e�ZGdd�de�ZGdd�de�ZGdd�de�Z de	j!j"dedddfdd�Z#de	j!j"dedddfdd�Z$eddfdd�Z%dS)z
DNS Zones.�)�
generatorsN)�BytesIO�)�string_types�	text_type�c@seZdZdZdS)�BadZonezThe DNS zone is malformed.N)�__name__�
__module__�__qualname__�__doc__�r
r
�/usr/lib/python3.6/zone.pyr)src@seZdZdZdS)�NoSOAz)The DNS zone has no SOA RR at its origin.N)r	r
rrr
r
r
rr.src@seZdZdZdS)�NoNSz+The DNS zone has no NS RRset at its origin.N)r	r
rrr
r
r
rr3src@seZdZdZdS)�
UnknownOriginz!The DNS zone's origin is unknown.N)r	r
rrr
r
r
rr8src@sjeZdZdZejjZddddgZej	j
dfdd�Zd	d
�Zdd�Z
d
d�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �ZeZd!d"�Zd#d$�ZdCd&d'�ZdDd(d)�Zd*d+�Zejjd%fd,d-�Z ejjd%fd.d/�Z!ejjfd0d1�Z"d2d3�Z#ejjfd4d5�Z$ejjfd6d7�Z%ejj&ejjfd8d9�Z'ejj&ejjfd:d;�Z(dEd=d>�Z)dFd?d@�Z*dAdB�Z+d<S)G�ZoneaZA DNS zone.

    A Zone is a mapping from names to nodes.  The zone object may be
    treated like a Python dictionary, e.g. zone[name] will retrieve
    the node associated with that name.  The I{name} may be a
    dns.name.Name object, or it may be a string.  In the either case,
    if the name is relative it is treated as relative to the origin of
    the zone.

    @ivar rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @ivar origin: The origin of the zone.
    @type origin: dns.name.Name object
    @ivar nodes: A dictionary mapping the names of nodes in the zone to the
    nodes themselves.
    @type nodes: dict
    @ivar relativize: should names in the zone be relativized?
    @type relativize: bool
    @cvar node_factory: the factory used to create a new node
    @type node_factory: class or callable
    �rdclass�origin�nodes�
relativizeTcCsb|dk	rFt|t�r tjj|�}nt|tjj�s6td��|j�sFtd��||_||_	i|_
||_dS)z�Initialize a zone object.

        @param origin: The origin of the zone.
        @type origin: dns.name.Name object
        @param rdclass: The zone's rdata class; the default is class IN.
        @type rdclass: intNz2origin parameter must be convertible to a DNS namez)origin parameter must be an absolute name)�
isinstancer�dns�name�	from_text�Name�
ValueError�is_absoluterrrr)�selfrrrr
r
r�__init__Ys
z
Zone.__init__cCs:t|t�sdS|j|jks2|j|jks2|j|jkr6dSdS)ziTwo zones are equal if they have the same origin, class, and
        nodes.
        @rtype: bool
        FT)rrrrr)r�otherr
r
r�__eq__ns
zZone.__eq__cCs|j|�S)z6Are two zones not equal?
        @rtype: bool
        )r!)rr r
r
r�__ne__|szZone.__ne__cCsbt|t�rtjj|d�}nt|tjj�s0td��|j�r^|j|j	�sLtd��|j
r^|j
|j	�}|S)Nz0name parameter must be convertible to a DNS namez5name parameter must be a subdomain of the zone origin)rrrrrr�KeyErrorr�is_subdomainrr)rrr
r
r�_validate_name�s
zZone._validate_namecCs|j|�}|j|S)N)r%r)r�keyr
r
r�__getitem__�s
zZone.__getitem__cCs|j|�}||j|<dS)N)r%r)rr&�valuer
r
r�__setitem__�s
zZone.__setitem__cCs|j|�}|j|=dS)N)r%r)rr&r
r
r�__delitem__�s
zZone.__delitem__cCs
|jj�S)N)r�__iter__)rr
r
rr+�sz
Zone.__iter__cCstr|jj�S|jj�SdS)N)�_py3r�keys�iterkeys)rr
r
rr.�s
z
Zone.iterkeyscCs
|jj�S)N)rr-)rr
r
rr-�sz	Zone.keyscCstr|jj�S|jj�SdS)N)r,r�values�
itervalues)rr
r
rr0�s
zZone.itervaluescCs
|jj�S)N)rr/)rr
r
rr/�szZone.valuescCs
|jj�S)N)r�items)rr
r
rr1�sz
Zone.itemscCs|j|�}|jj|�S)N)r%r�get)rr&r
r
rr2�s
zZone.getcCs
||jkS)N)r)rr r
r
r�__contains__�szZone.__contains__FcCs<|j|�}|jj|�}|dkr8|s&t�|j�}||j|<|S)arFind a node in the zone, possibly creating it.

        @param name: the name of the node to find
        @type name: dns.name.Name object or string
        @param create: should the node be created if it doesn't exist?
        @type create: bool
        @raises KeyError: the name is not known and create was not specified.
        @rtype: dns.node.Node object
        N)r%rr2r#�node_factory)rr�create�noder
r
r�	find_node�s

zZone.find_nodecCs.y|j||�}Wntk
r(d}YnX|S)a�Get a node in the zone, possibly creating it.

        This method is like L{find_node}, except it returns None instead
        of raising an exception if the node does not exist and creation
        has not been requested.

        @param name: the name of the node to find
        @type name: dns.name.Name object or string
        @param create: should the node be created if it doesn't exist?
        @type create: bool
        @rtype: dns.node.Node object or None
        N)r7r#)rrr5r6r
r
r�get_node�s

z
Zone.get_nodecCs |j|�}||jkr|j|=dS)zhDelete the specified node if it exists.

        It is not an error if the node does not exist.
        N)r%r)rrr
r
r�delete_node�s

zZone.delete_nodecCsT|j|�}t|t�r tjj|�}t|t�r6tjj|�}|j||�}|j|j|||�S)a�Look for rdata with the specified name and type in the zone,
        and return an rdataset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        The rdataset returned is not a copy; changes to it will change
        the zone.

        KeyError is raised if the name or type are not found.
        Use L{get_rdataset} if you want to have None returned instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @param create: should the node and rdataset be created if they do not
        exist?
        @type create: bool
        @raises KeyError: the node or rdata could not be found
        @rtype: dns.rrset.RRset object
        )	r%rrr�	rdatatyperr7�
find_rdatasetr)rr�rdtype�coversr5r6r
r
rr;�s


zZone.find_rdatasetcCs2y|j||||�}Wntk
r,d}YnX|S)a�Look for rdata with the specified name and type in the zone,
        and return an rdataset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        The rdataset returned is not a copy; changes to it will change
        the zone.

        None is returned if the name or type are not found.
        Use L{find_rdataset} if you want to have KeyError raised instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @param create: should the node and rdataset be created if they do not
        exist?
        @type create: bool
        @rtype: dns.rrset.RRset object
        N)r;r#)rrr<r=r5�rdatasetr
r
r�get_rdatasets

zZone.get_rdatasetcCsr|j|�}t|t�r tjj|�}t|t�r6tjj|�}|j|�}|dk	rn|j|j||�t	|�dkrn|j
|�dS)a�Delete the rdataset matching I{rdtype} and I{covers}, if it
        exists at the node specified by I{name}.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        It is not an error if the node does not exist, or if there is no
        matching rdataset at the node.

        If the node has no rdatasets after the deletion, it will itself
        be deleted.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        Nr)r%rrrr:rr8�delete_rdatasetr�lenr9)rrr<r=r6r
r
rr@4s



zZone.delete_rdatasetcCs.|j|jkrtd��|j|d�}|j|�dS)a:Replace an rdataset at name.

        It is not an error if there is no rdataset matching I{replacement}.

        Ownership of the I{replacement} object is transferred to the zone;
        in other words, this method does not store a copy of I{replacement}
        at the node, it stores I{replacement} itself.

        If the I{name} node does not exist, it is created.

        @param name: the owner name
        @type name: DNS.name.Name object or string
        @param replacement: the replacement rdataset
        @type replacement: dns.rdataset.Rdataset
        z#replacement.rdclass != zone.rdclassTN)rrr7�replace_rdataset)rrZreplacementr6r
r
rrBUszZone.replace_rdatasetcCsn|j|�}t|t�r tjj|�}t|t�r6tjj|�}|j|j|j||�}tj	j
||j||�}|j|�|S)a�Look for rdata with the specified name and type in the zone,
        and return an RRset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        This method is less efficient than the similar
        L{find_rdataset} because it creates an RRset instead of
        returning the matching rdataset.  It may be more convenient
        for some uses since it returns an object which binds the owner
        name to the rdata.

        This method may not be used to create new nodes or rdatasets;
        use L{find_rdataset} instead.

        KeyError is raised if the name or type are not found.
        Use L{get_rrset} if you want to have None returned instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @raises KeyError: the node or rdata could not be found
        @rtype: dns.rrset.RRset object
        )r%rrrr:rrr;r�rrsetZRRset�update)rrr<r=r>rCr
r
r�
find_rrsetks



zZone.find_rrsetcCs0y|j|||�}Wntk
r*d}YnX|S)aJLook for rdata with the specified name and type in the zone,
        and return an RRset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        This method is less efficient than the similar L{get_rdataset}
        because it creates an RRset instead of returning the matching
        rdataset.  It may be more convenient for some uses since it
        returns an object which binds the owner name to the rdata.

        This method may not be used to create new nodes or rdatasets;
        use L{find_rdataset} instead.

        None is returned if the name or type are not found.
        Use L{find_rrset} if you want to have KeyError raised instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @rtype: dns.rrset.RRset object
        N)rEr#)rrr<r=rCr
r
r�	get_rrset�s

zZone.get_rrsetccs~t|t�rtjj|�}t|t�r,tjj|�}xL|j�D]@\}}x6|D].}|tjjksh|j|krD|j|krD||fVqDWq6WdS)a�Return a generator which yields (name, rdataset) tuples for
        all rdatasets in the zone which have the specified I{rdtype}
        and I{covers}.  If I{rdtype} is dns.rdatatype.ANY, the default,
        then all rdatasets will be matched.

        @param rdtype: int or string
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        N)	rrrr:r�	iteritems�ANYr<r=)rr<r=rr6�rdsr
r
r�iterate_rdatasets�s


zZone.iterate_rdatasetsccs�t|t�rtjj|�}t|t�r,tjj|�}x^|j�D]R\}}xH|D]@}|tjjksh|j|krD|j|krDx|D]}||j	|fVqnWqDWq6WdS)a�Return a generator which yields (name, ttl, rdata) tuples for
        all rdatas in the zone which have the specified I{rdtype}
        and I{covers}.  If I{rdtype} is dns.rdatatype.ANY, the default,
        then all rdatas will be matched.

        @param rdtype: int or string
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        N)
rrrr:rrGrHr<r=�ttl)rr<r=rr6rI�rdatar
r
r�iterate_rdatas�s



zZone.iterate_rdatasNcCs8t|t�rt|d�}d}nd}t|dd�}|dkr6d}|dkrPtjj|�}d}n"t|t�rf|j|�}n|}|j�}z�|r�t|j	��}|j
�n|j�}x�|D]�}	||	j|	|j
|d�}
t|
t�r�|
j|�}n|
}|
j�}
y|j|�|j|�Wq�tk
�r|j|
�|j|�Yq�Xq�WWd|�r2|j�XdS)	aWrite a zone to a file.

        @param f: file or string.  If I{f} is a string, it is treated
        as the name of a file to open.
        @param sorted: if True, the file will be written with the
        names sorted in DNSSEC order from least to greatest.  Otherwise
        the names will be written in whatever order they happen to have
        in the zone's dictionary.
        @param relativize: if True, domain names in the output will be
        relativized to the zone's origin (if possible).
        @type relativize: bool
        @param nl: The end of line string.  If not specified, the
        output will use the platform's native end-of-line marker (i.e.
        LF on POSIX, CRLF on Windows, CR on Macintosh).
        @type nl: string or None
        �wbTF�encodingNzutf-8�
)rr)rr�open�getattr�os�linesep�encode�decode�listr-�sortr.�to_textrr�write�	TypeError�close)r�f�sortedr�nl�
want_closeZfile_encZnl_b�names�n�lZl_br
r
r�to_file�sD







zZone.to_filecCs*t�}|j||||�|j�}|j�|S)a�Return a zone's text as though it were written to a file.

        @param sorted: if True, the file will be written with the
        names sorted in DNSSEC order from least to greatest.  Otherwise
        the names will be written in whatever order they happen to have
        in the zone's dictionary.
        @param relativize: if True, domain names in the output will be
        relativized to the zone's origin (if possible).
        @type relativize: bool
        @param nl: The end of line string.  If not specified, the
        output will use the platform's native end-of-line marker (i.e.
        LF on POSIX, CRLF on Windows, CR on Macintosh).
        @type nl: string or None
        )rrd�getvaluer\)rr^rr_Ztemp_bufferZreturn_valuer
r
rrY$s
zZone.to_textcCsJ|jrtjj}n|j}|j|tjj�dkr.t�|j|tjj	�dkrFt
�dS)z�Do some simple checking of the zone's origin.

        @raises dns.zone.NoSOA: there is no SOA RR
        @raises dns.zone.NoNS: there is no NS RRset
        @raises KeyError: there is no origin node
        N)rrr�emptyrr?r:ZSOArZNSr)rrr
r
r�check_origin9s
zZone.check_origin)F)F)TTN)TTN),r	r
rrrr6ZNoder4�	__slots__�
rdataclass�INrr!r"r%r'r)r*r+r.r-r0r/r1rGr2r3r7r8r9r:ZNONEr;r?r@rBrErFrHrJrMrdrYrgr
r
r
rr=sJ



# !("
@
rc@sHeZdZdZeddfdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dS)�
_MasterReadera�Read a DNS master file

    @ivar tok: The tokenizer
    @type tok: dns.tokenizer.Tokenizer object
    @ivar ttl: The default TTL
    @type ttl: int
    @ivar last_name: The last name read
    @type last_name: dns.name.Name object
    @ivar current_origin: The current origin
    @type current_origin: dns.name.Name object
    @ivar relativize: should names in the zone be relativized?
    @type relativize: bool
    @ivar zone: the zone
    @type zone: dns.zone.Zone object
    @ivar saved_state: saved reader state (used when processing $INCLUDE)
    @type saved_state: list of (tokenizer, current_origin, last_name, file)
    tuples.
    @ivar current_file: the file object of the $INCLUDed file being parsed
    (None if no $INCLUDE is active).
    @ivar allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @ivar check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    FTcCsbt|t�rtjj|�}||_||_||_d|_|j|_	||||d�|_
g|_d|_||_
||_dS)Nr)r)rrrrr�tok�current_originrrK�	last_name�zone�saved_state�current_file�
allow_includerg)rrlrrr�zone_factoryrrrgr
r
rrfs
z_MasterReader.__init__cCsx|jj�}|j�rPqWdS)N)rlr2�
is_eol_or_eof)r�tokenr
r
r�	_eat_lineus
z_MasterReader._eat_linec"Cs�|jdkrt�|jjdd�}|j�s:tjj|j|j�|_	n"|jj�}|j
�rPdS|jj|�|j	}|j|j
j�s||j�dS|jr�|j|j
j�}|jj�}|j�s�tjj�y,tjj|j�}|jj�}|j�s�tjj�Wntjjk
r�|j}YnXy.tjj|j�}|jj�}|j��s"tjj�Wn>tjjk
�rFtjj�Yntk
�rb|j
j}YnX||j
jk�r~tjjd��ytjj|j�}Wntjjd|j��YnX|j
jj|�}|dk�r�|j
j�}||j
j|<ytjj|||j|jd�}Wnltjjk
�r,tj�dd�\}}	|	�Yn<tj�dd�\}}	tjjdt|�t|	�f��YnX|j |j
j|j�|j!�}
|j"|||
d�}|j#||�dS)	z(Process one line from a DNS master file.NT)Zwant_leadingzRR class is not zone's classzunknown rdatatype '%s'F�zcaught exception %s: %s)$rmrrlr2Z
is_whitespacerrrr(rnrt�ungetr$rorrvr�
is_identifier�	exception�SyntaxErrorrK�BadTTLri�	Exceptionrr:rr4rL�sys�exc_info�str�choose_relativityr=r;�add)rrurrKrr<rb�rd�ty�var=rIr
r
r�_rr_line{sx







z_MasterReader._rr_linec
Cs�tjd�}tjd�}tjd�}|j|�}|rJ|j�\}}}}	}
|dkrJd}|j|�}|rz|j�\}}}|dkrrd}d}	d}
|j|�}|r�|j�\}}}}	|dkr�d}|j�d}	d}
|p�|p�|s�d}d}d}d}	d}
|
dkr�t��||||	|
fS)	Nz"^.*\$({(\+|-?)(\d+),(\d+),(.)}).*$z^.*\$({(\+|-?)(\d+)}).*$z^.*\$({(\+|-?)(\d+),(\d+)}).*$��+r�drw)�re�compile�match�groups�NotImplementedError)
rZsideZis_generate1Zis_generate2Zis_generate3Zg1�modZsign�offset�width�baseZg2Zg3r
r
r�
_parse_modify�s>





z_MasterReader._parse_modifyc!7Cs|jdkrt�|jj�}y2tjj|j�\}}}|jj�}|j�sHtj	j
�Wntj	j
�YnXy$|j}|jj�}|j�s�tj	j
�Wntj	j
�YnXy,tjj|j�}|jj�}|j�s�tj	j
�Wntjjk
r�|j}YnXy.tj
j|j�}|jj�}|j��stj	j
�Wn>tj	j
k
�r6tj	j
�Yntk
�rR|jj}YnX||jjk�rntj	j
d��y.tjj|j�}|jj�}|j��s�tj	j
�Wn(tk
�r�tj	j
d|j��YnXy
|j}	Wntj	j
�YnX|j|�\}
}}}
}|j|	�\}}}}}�x�t||d|�D�]�}|dk�r@|t|�}n|dk�rV|t|�}|dk�rn|t|�}n|dk�r�|t|�}t|�jt|
��}t|�jt|��}|jd|
|�}|	jd||�}tjj||j�|_|j}|j|jj��s�|j�dS|j�r|j|jj�}|jjj|�}|dk�r@|jj�}||jj|<ytj j||||jd�}Wnltj	j
k
�r�t!j"�dd	�\}}|�Yn<t!j"�dd	�\}}tj	j
d
t|�t|�f��YnX|j#|jj|j�|j$�}|j%|||d�} | j&||��q"WdS)zRProcess one line containing the GENERATE statement from a DNS
        master file.NzRR class is not zone's classzunknown rdatatype '%s'rr��-z$%sFrwzcaught exception %s: %sT)'rmrrlr2rZgrangerr(ryrzr{rKr|rir}rorr:r��range�intr��zfill�replacerrnr$rrvrrr4rLr~rr�r=r;r�)!rru�start�stop�stepZlhsrKrr<ZrhsZlmodZlsignZloffsetZlwidthZlbaseZrmodZrsignZroffsetZrwidthZrbase�iZlindex�rindexZlzfindexZrzfindexrrLrbr�r�r�r=rIr
r
r�_generate_line�s�















z_MasterReader._generate_linecCs��y�x|jjdd�}|j�rh|jdk	r2|jj�t|j�dkrb|jjd�\|_|_|_	|_|_
qP�n�|j�rvq�n�|j�r�|jj
�q�nx|jddk�r|jj�}|dkr�|jj�}|j�s�tjjd��tj
j|j�|_
|jj
�q|dk�r$|jj�|_|jj
�|jjdk�r|j|j_q|d	k�r�|j�r�|jj�}|j}|jj�}|j��rxtjj|j|j�}|jj
�n|j��s�tjjd
��n|j}|jj|j|j|j	|j|j
f�t|d�|_tjj|j|�|_||_q|dk�r�|j�qtjjd
|d��q|jj |�|j!�qWWnZtjjk
�rz}z8|jj"�\}}|dk�rTd}tjjd|||f��WYdd}~XnX|j#�r�|jj#�dS)z�Read a DNS master file and build a zone object.

        @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
        @raises dns.zone.NoNS: No NS RRset was found at the zone origin
        TNrr�$z$TTLzbad $TTLz$ORIGINz$INCLUDEzbad origin in $INCLUDE�rz	$GENERATEzUnknown master file directive '�'zsyntax errorz	%s:%d: %s���)$rlr2Zis_eofrqr\rArp�poprmrnrKZis_eolZ
is_commentZget_eolr(�upperryrrzr{rZget_namerorrrrrt�appendrQ�	tokenizer�	Tokenizerr�rxr��whererg)rru�c�filenameZ
new_originZdetailZline_numberr
r
r�reades�

 















"z_MasterReader.readN)r	r
rrrrrvr�r�r�r�r
r
r
rrkJsL)urkTFc
	Cs>|dkrd}tjj||�}t|||||||d�}	|	j�|	jS)arBuild a zone object from a master file format string.

    @param text: the master file format input
    @type text: string.
    @param origin: The origin of the zone; if not specified, the first
    $ORIGIN statement in the master file will determine the origin of the
    zone.
    @type origin: dns.name.Name object or string
    @param rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @param relativize: should names be relativized?  The default is True
    @type relativize: bool
    @param zone_factory: The zone factory to use
    @type zone_factory: function returning a Zone
    @param filename: The filename to emit when describing where an error
    occurred; the default is '<string>'.
    @type filename: string
    @param allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    Nz<string>)rrrg)rr�r�rkr�ro)
�textrrrrsr�rrrgrl�readerr
r
rr�s"rcCslt}d}	t||�r.|dkr|}t||	�}d}
n|dkr:d}d}
zt||||||||�}Wd|
rf|j�X|S)a�Read a master file and build a zone object.

    @param f: file or string.  If I{f} is a string, it is treated
    as the name of a file to open.
    @param origin: The origin of the zone; if not specified, the first
    $ORIGIN statement in the master file will determine the origin of the
    zone.
    @type origin: dns.name.Name object or string
    @param rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @param relativize: should names be relativized?  The default is True
    @type relativize: bool
    @param zone_factory: The zone factory to use
    @type zone_factory: function returning a Zone
    @param filename: The filename to emit when describing where an error
    occurred; the default is '<file>', or the value of I{f} if I{f} is a
    string.
    @type filename: string
    @param allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    ZrUNTz<file>F)rrrQrr\)r]rrrrsr�rrrgZstr_typeZoptsr`�zr
r
r�	from_file�s 


r�cCs�d}x�|D]�}|dkrH|r"|j}n|jdj}|jdj}||||d�}x||jD]r}|jj|j�}	|	sz|j�}	|	|j|j<|	j|j|j|j	d�}
|
j
|j�x$|D]}|j|j|�|
j
|�q�WqPWq
W|r�|j�|S)a�Convert the output of a zone transfer generator into a zone object.

    @param xfr: The xfr generator
    @type xfr: generator of dns.message.Message objects
    @param relativize: should names be relativized?  The default is True.
    It is essential that the relativize setting matches the one specified
    to dns.query.xfr().
    @type relativize: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    Nr)rT)rZanswerrrrr2r4r;r<r=Z
update_ttlrKr�r�rg)Zxfrrsrrgr�r�rrrCZznodeZzrdsr�r
r
r�from_xfrs,


r�)r)&rZ
__future__rr~r�rS�iorZ
dns.exceptionrZdns.nameZdns.nodeZdns.rdataclassZ
dns.rdatatypeZ	dns.rdataZ	dns.rrsetZ
dns.tokenizerZdns.ttlZ
dns.grangeZ_compatrr�version_infor,rzZDNSExceptionrrrr�objectrrkrirjrr�r�r
r
r
r�<module>sH
o*3PKi�\:��	�	&__pycache__/rcode.cpython-36.opt-1.pycnu�[���3

�b�W �
@s�dZddlZddlmZdZdZdZdZdZ	dZ
d	Zd
ZdZ
dZd
ZdZeeeee	e
eee
eeed�Zedd�ej�D��ZGdd�dejj�Zdd�Zdd�Zdd�Zdd�ZdS)zDNS Result Codes.�N�)�long��������	�
�)�NOERROR�FORMERR�SERVFAIL�NXDOMAIN�NOTIMP�REFUSED�YXDOMAIN�YXRRSET�NXRRSET�NOTAUTH�NOTZONE�BADVERSccs|]\}}||fVqdS)N�)�.0�x�yrr�/usr/lib/python3.6/rcode.py�	<genexpr>6src@seZdZdZdS)�UnknownRcodezA DNS rcode is unknown.N)�__name__�
__module__�__qualname__�__doc__rrrrr 9sr cCsB|j�r$t|�}|dkr$|dkr$|Stj|j��}|dkr>t�|S)z�Convert text into an rcode.

    @param text: the textual rcode
    @type text: string
    @raises UnknownRcode: the rcode is unknown
    @rtype: int
    ri�N)�isdigit�int�_by_text�get�upperr )�text�vrrr�	from_text>s	r,cCs0|d@|d?d@B}|dks$|dkr,td��|S)z�Return the rcode value encoded by flags and ednsflags.

    @param flags: the DNS flags
    @type flags: int
    @param ednsflags: the EDNS flags
    @type ednsflags: int
    @raises ValueError: rcode is < 0 or > 4095
    @rtype: int
    ��i�ri�zrcode must be >= 0 and <= 4095)�
ValueError)�flagsZ	ednsflags�valuerrr�
from_flagsQsr2cCs8|dks|dkrtd��|d@}t|d@�d>}||fS)z�Return a (flags, ednsflags) tuple which encodes the rcode.

    @param value: the rcode
    @type value: int
    @raises ValueError: rcode is < 0 or > 4095
    @rtype: (int, int) tuple
    ri�zrcode must be >= 0 and <= 4095r-i�r.)r/r)r1r+Zevrrr�to_flagsbs
	r3cCstj|�}|dkrt|�}|S)zbConvert rcode into text.

    @param value: the rcode
    @type value: int
    @rtype: string
    N)�	_by_valuer(�str)r1r*rrr�to_textrs
r6)r$Z
dns.exceptionZdnsZ_compatrrrrrrrrrrrrrr'�dict�itemsr4Z	exceptionZDNSExceptionr r,r2r3r6rrrr�<module>s@PKi�\o�o		#__pycache__/wiredata.cpython-36.pycnu�[���3

�b�W��@s^dZddlZddlZddlmZmZGdd�de�Ze�dd�ZGdd�de�Z	d	d
�Z
dS)zDNS Wire Data Helper�N�)�binary_type�string_typesc@s&eZdZdd�Zejdkr"dd�ZdS)�_SliceUnspecifiedBoundcCs|jS)N)�stop)�self�key�r	�/usr/lib/python3.6/wiredata.py�__getitem__ sz"_SliceUnspecifiedBound.__getitem__�cCs|jt||��S)N)r�slice)r�i�jr	r	r
�__getslice__$sz#_SliceUnspecifiedBound.__getslice__N)r)�__name__�
__module__�__qualname__r�sys�version_inforr	r	r	r
rs
rcs>eZdZ�fdd�Zejd
kr&dd�Zdd�Zdd	�Z�Z	S)�WireDatacs�y�t|t�r�|j}|j}tjdkrx|tkr2t|�}|dksB|dkrJtj	j
�||kr�tt|�j
|�tt|�j
|d�n6x4||fD](}|dkr�q�q�t|�t|�kr�tj	j
�q�Wttt|�j
t||���St|j��|Stk
r�tj	j
�YnXdS)Nrrr)r)�
isinstancer
�startrrr�_unspecified_bound�len�dns�	exception�	FormError�superrr�abs�	bytearray�unwrap�
IndexError)rrrr�index)�	__class__r	r
r-s,

zWireData.__getitem__rcCs|jt||��S)N)rr
)rrrr	r	r
rPszWireData.__getslice__ccsBd}x8y||V|d7}Wqtjjk
r8t�YqXqWdS)Nrr)rrr�
StopIteration)rrr	r	r
�__iter__Ss
zWireData.__iter__cCst|�S)N)r)rr	r	r
r!\szWireData.unwrap)r)
rrrrrrrr&r!�
__classcell__r	r	)r$r
r*s
"
	rcCsJt|t�r|St|t�r t|�St|t�r6t|j��Stdt|���dS)Nzunhandled type %s)rrrr�encode�
ValueError�type)Zwirer	r	r
�
maybe_wrap`s


r+)�__doc__rZ
dns.exceptionrZ_compatrrrrrr+r	r	r	r
�<module>s		6PKi�\�Ja�AA%__pycache__/tsig.cpython-36.opt-1.pycnu�[���3

�b�W&�@s~dZddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
mZGdd�dejj
�ZGdd�dejj
�ZGd	d
�d
ejj
�ZGdd�de�ZGd
d�de�ZGdd�de�ZGdd�de�Zejjd�Zejjd�Zejjd�Zejjd�Zejjd�Zejjd�ZedededededediZeZdZd Z d!Z!d"Z"dd#d$efd%d&�Z#dd#d$efd'd(�Z$d/d)d*�Z%d+d,�Z&d-d.�Z'dS)0zDNS TSIG support.�N�)�long�string_types�	text_typec@seZdZdZdS)�BadTimez8The current time is not within the TSIG's validity time.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/tsig.pyrsrc@seZdZdZdS)�BadSignaturez#The TSIG signature fails to verify.N)rrr	r
rrrrr
 sr
c@seZdZdZdS)�	PeerErrorz;Base class for all TSIG errors generated by the remote peerN)rrr	r
rrrrr%src@seZdZdZdS)�
PeerBadKeyz$The peer didn't know the key we usedN)rrr	r
rrrrr*src@seZdZdZdS)�PeerBadSignaturez*The peer didn't like the signature we sentN)rrr	r
rrrrr/src@seZdZdZdS)�PeerBadTimez%The peer didn't like the time we sentN)rrr	r
rrrrr4src@seZdZdZdS)�PeerBadTruncationz=The peer didn't like amount of truncation in the TSIG we sentN)rrr	r
rrrrr9srzHMAC-MD5.SIG-ALG.REG.INTz	hmac-sha1zhmac-sha224zhmac-sha256zhmac-sha384zhmac-sha512ZSHA224ZSHA256ZSHA384ZSHA512ZSHA1ZMD5����FTc
Cs�t|t�r|j�}t|�\}
}|r\tj||d�}	t|�}|dkr\|	jtj	d|��|	j|�tj	d|�}|	j|�|	j|dd��|r�|	j|j
��|	jtj	dtjj
��|	jtj	dd��|td�}|d?td�@}|td	�@}tj	d
|||�}|
|}t|�}|dk�rtd��tj	d||�|}|�rF|	j|�|	j|�n
|	j|�|	j�}tj	dt|��}|||||}|
�r�tj||d�}	t|�}|	jtj	d|��|	j|�nd}	|||	fS)
ajReturn a (tsig_rdata, mac, ctx) tuple containing the HMAC TSIG rdata
    for the input parameters, the HMAC MAC calculated by applying the
    TSIG signature algorithm, and the TSIG digest context.
    @rtype: (string, string, hmac.HMAC object)
    @raises ValueError: I{other_data} is too long
    @raises NotImplementedError: I{algorithm} is not supported
    )�	digestmodrz!H�Nz!I� i��l��z!HIHz TSIG Other Data is > 65535 bytesz!HH)�
isinstancer�encode�
get_algorithm�hmac�new�len�update�struct�pack�
to_digestable�dnsZ
rdataclass�ANYr�
ValueErrorZdigest)�wire�keyname�secret�time�fudge�original_id�error�
other_data�request_mac�ctx�multi�first�	algorithmZalgorithm_namerZml�idZ	long_time�
upper_time�
lower_timeZtime_macZpre_macZolZpost_mac�macZmpack�
tsig_rdatarrr�signWsN





r9c

Cs t||||||||||	|
||�
S)N)r9)
r'r(r)r*r+r,r-r.r/r0r1r2r3rrr�hmac_md5�sr:cCs�tjd|dd��\}|dkr&tjj�|d8}|dd�tjd|�|d|�}|}
tjj||
�\}}|
|}
tjd||
|
d��\}}}}|td�d>|td�}|
d7}
||
|
|�}|
|7}
tjd||
|
d	��\}}}|
d	7}
||
|
|�}|
|7}
|
||k�r tjj�|dk�rv|t	k�r:t
�n<|tk�rJt�n,|t
k�rZt�n|tk�rjt�ntd
|��||}||}||k�s�||k�r�t�t|||||||||||	|
|�
\}}}||k�r�t�|S)a*Validate the specified TSIG rdata against the other input parameters.

    @raises FormError: The TSIG is badly formed.
    @raises BadTime: There is too much time skew between the client and the
    server.
    @raises BadSignature: The TSIG signature did not validate
    @rtype: hmac.HMAC objectz!H�
�rrz!HIHHrz!HHH�zunknown TSIG error code %d)r!�unpackr$�	exception�	FormErrorr"�name�	from_wirer�BADSIGr�BADKEYr�BADTIMEr�BADTRUNCrrrr9r
)r'r(r)Znowr/Z
tsig_startr8�
tsig_rdlenr0r1r2ZadcountZnew_wire�current�aname�usedr5r6r+�mac_sizer*r7r,r-Z
other_sizer.Ztime_lowZ	time_highZjunkZour_macrrr�validate�sN
$ 





rLcCs\t|t�rtjj|�}y|j�tjjt|fSt	k
rVt
dt|�d��YnXdS)z�Returns the wire format string and the hash module to use for the
    specified TSIG algorithm

    @rtype: (string, hash constructor)
    @raises NotImplementedError: I{algorithm} is not supported
    zTSIG algorithm z is not supportedN)rrr$rA�	from_textr#�hashZhashes�_hashes�KeyError�NotImplementedError�str)r3rrrr�s
rcCsz|}tjj||�\}}||}tjd|||d��\}}}}	|d7}||||	�}
||	7}|||krrtjj�||
fS)zlReturn the tsig algorithm for the specified tsig_rdata
    @raises FormError: The TSIG is badly formed.
    z!HIHHr;)r$rArBr!r>r?r@)r'r8rGrHrIrJr5r6r+rKr7rrr�get_algorithm_and_mac�s rS)NFT)(r
rr!Z
dns.exceptionr$Zdns.hashZdns.rdataclassZdns.nameZ_compatrrrr?ZDNSExceptionrr
rrrrrrArMZHMAC_MD5Z	HMAC_SHA1ZHMAC_SHA224ZHMAC_SHA256ZHMAC_SHA384ZHMAC_SHA512rOZdefault_algorithmrCrDrErFr9r:rLrrSrrrr�<module>sL5
5PKi�\�Ja�AA__pycache__/tsig.cpython-36.pycnu�[���3

�b�W&�@s~dZddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
mZGdd�dejj
�ZGdd�dejj
�ZGd	d
�d
ejj
�ZGdd�de�ZGd
d�de�ZGdd�de�ZGdd�de�Zejjd�Zejjd�Zejjd�Zejjd�Zejjd�Zejjd�ZedededededediZeZdZd Z d!Z!d"Z"dd#d$efd%d&�Z#dd#d$efd'd(�Z$d/d)d*�Z%d+d,�Z&d-d.�Z'dS)0zDNS TSIG support.�N�)�long�string_types�	text_typec@seZdZdZdS)�BadTimez8The current time is not within the TSIG's validity time.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/tsig.pyrsrc@seZdZdZdS)�BadSignaturez#The TSIG signature fails to verify.N)rrr	r
rrrrr
 sr
c@seZdZdZdS)�	PeerErrorz;Base class for all TSIG errors generated by the remote peerN)rrr	r
rrrrr%src@seZdZdZdS)�
PeerBadKeyz$The peer didn't know the key we usedN)rrr	r
rrrrr*src@seZdZdZdS)�PeerBadSignaturez*The peer didn't like the signature we sentN)rrr	r
rrrrr/src@seZdZdZdS)�PeerBadTimez%The peer didn't like the time we sentN)rrr	r
rrrrr4src@seZdZdZdS)�PeerBadTruncationz=The peer didn't like amount of truncation in the TSIG we sentN)rrr	r
rrrrr9srzHMAC-MD5.SIG-ALG.REG.INTz	hmac-sha1zhmac-sha224zhmac-sha256zhmac-sha384zhmac-sha512ZSHA224ZSHA256ZSHA384ZSHA512ZSHA1ZMD5����FTc
Cs�t|t�r|j�}t|�\}
}|r\tj||d�}	t|�}|dkr\|	jtj	d|��|	j|�tj	d|�}|	j|�|	j|dd��|r�|	j|j
��|	jtj	dtjj
��|	jtj	dd��|td�}|d?td�@}|td	�@}tj	d
|||�}|
|}t|�}|dk�rtd��tj	d||�|}|�rF|	j|�|	j|�n
|	j|�|	j�}tj	dt|��}|||||}|
�r�tj||d�}	t|�}|	jtj	d|��|	j|�nd}	|||	fS)
ajReturn a (tsig_rdata, mac, ctx) tuple containing the HMAC TSIG rdata
    for the input parameters, the HMAC MAC calculated by applying the
    TSIG signature algorithm, and the TSIG digest context.
    @rtype: (string, string, hmac.HMAC object)
    @raises ValueError: I{other_data} is too long
    @raises NotImplementedError: I{algorithm} is not supported
    )�	digestmodrz!H�Nz!I� i��l��z!HIHz TSIG Other Data is > 65535 bytesz!HH)�
isinstancer�encode�
get_algorithm�hmac�new�len�update�struct�pack�
to_digestable�dnsZ
rdataclass�ANYr�
ValueErrorZdigest)�wire�keyname�secret�time�fudge�original_id�error�
other_data�request_mac�ctx�multi�first�	algorithmZalgorithm_namerZml�idZ	long_time�
upper_time�
lower_timeZtime_macZpre_macZolZpost_mac�macZmpack�
tsig_rdatarrr�signWsN





r9c

Cs t||||||||||	|
||�
S)N)r9)
r'r(r)r*r+r,r-r.r/r0r1r2r3rrr�hmac_md5�sr:cCs�tjd|dd��\}|dkr&tjj�|d8}|dd�tjd|�|d|�}|}
tjj||
�\}}|
|}
tjd||
|
d��\}}}}|td�d>|td�}|
d7}
||
|
|�}|
|7}
tjd||
|
d	��\}}}|
d	7}
||
|
|�}|
|7}
|
||k�r tjj�|dk�rv|t	k�r:t
�n<|tk�rJt�n,|t
k�rZt�n|tk�rjt�ntd
|��||}||}||k�s�||k�r�t�t|||||||||||	|
|�
\}}}||k�r�t�|S)a*Validate the specified TSIG rdata against the other input parameters.

    @raises FormError: The TSIG is badly formed.
    @raises BadTime: There is too much time skew between the client and the
    server.
    @raises BadSignature: The TSIG signature did not validate
    @rtype: hmac.HMAC objectz!H�
�rrz!HIHHrz!HHH�zunknown TSIG error code %d)r!�unpackr$�	exception�	FormErrorr"�name�	from_wirer�BADSIGr�BADKEYr�BADTIMEr�BADTRUNCrrrr9r
)r'r(r)Znowr/Z
tsig_startr8�
tsig_rdlenr0r1r2ZadcountZnew_wire�current�aname�usedr5r6r+�mac_sizer*r7r,r-Z
other_sizer.Ztime_lowZ	time_highZjunkZour_macrrr�validate�sN
$ 





rLcCs\t|t�rtjj|�}y|j�tjjt|fSt	k
rVt
dt|�d��YnXdS)z�Returns the wire format string and the hash module to use for the
    specified TSIG algorithm

    @rtype: (string, hash constructor)
    @raises NotImplementedError: I{algorithm} is not supported
    zTSIG algorithm z is not supportedN)rrr$rA�	from_textr#�hashZhashes�_hashes�KeyError�NotImplementedError�str)r3rrrr�s
rcCsz|}tjj||�\}}||}tjd|||d��\}}}}	|d7}||||	�}
||	7}|||krrtjj�||
fS)zlReturn the tsig algorithm for the specified tsig_rdata
    @raises FormError: The TSIG is badly formed.
    z!HIHHr;)r$rArBr!r>r?r@)r'r8rGrHrIrJr5r6r+rKr7rrr�get_algorithm_and_mac�s rS)NFT)(r
rr!Z
dns.exceptionr$Zdns.hashZdns.rdataclassZdns.nameZ_compatrrrr?ZDNSExceptionrr
rrrrrrArMZHMAC_MD5Z	HMAC_SHA1ZHMAC_SHA224ZHMAC_SHA256ZHMAC_SHA384ZHMAC_SHA512rOZdefault_algorithmrCrDrErFr9r:rLrrSrrrr�<module>sL5
5PKi�\��Yҹu�u__pycache__/zone.cpython-36.pycnu�[���3

ӕ�WZ��@sNdZddlmZddlZddlZddlZddlmZddlZ	ddl
Z	ddlZ	ddlZ	ddl
Z	ddlZ	ddlZ	ddlZ	ddlZ	ddlZ	ddlmZmZejdkZGdd	�d	e	jj�ZGd
d�de�ZGdd
�d
e�ZGdd�de�ZGdd�de�ZGdd�de�Z de	j!j"dedddfdd�Z#de	j!j"dedddfdd�Z$eddfdd�Z%dS)z
DNS Zones.�)�
generatorsN)�BytesIO�)�string_types�	text_type�c@seZdZdZdS)�BadZonezThe DNS zone is malformed.N)�__name__�
__module__�__qualname__�__doc__�r
r
�/usr/lib/python3.6/zone.pyr)src@seZdZdZdS)�NoSOAz)The DNS zone has no SOA RR at its origin.N)r	r
rrr
r
r
rr.src@seZdZdZdS)�NoNSz+The DNS zone has no NS RRset at its origin.N)r	r
rrr
r
r
rr3src@seZdZdZdS)�
UnknownOriginz!The DNS zone's origin is unknown.N)r	r
rrr
r
r
rr8src@sjeZdZdZejjZddddgZej	j
dfdd�Zd	d
�Zdd�Z
d
d�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �ZeZd!d"�Zd#d$�ZdCd&d'�ZdDd(d)�Zd*d+�Zejjd%fd,d-�Z ejjd%fd.d/�Z!ejjfd0d1�Z"d2d3�Z#ejjfd4d5�Z$ejjfd6d7�Z%ejj&ejjfd8d9�Z'ejj&ejjfd:d;�Z(dEd=d>�Z)dFd?d@�Z*dAdB�Z+d<S)G�ZoneaZA DNS zone.

    A Zone is a mapping from names to nodes.  The zone object may be
    treated like a Python dictionary, e.g. zone[name] will retrieve
    the node associated with that name.  The I{name} may be a
    dns.name.Name object, or it may be a string.  In the either case,
    if the name is relative it is treated as relative to the origin of
    the zone.

    @ivar rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @ivar origin: The origin of the zone.
    @type origin: dns.name.Name object
    @ivar nodes: A dictionary mapping the names of nodes in the zone to the
    nodes themselves.
    @type nodes: dict
    @ivar relativize: should names in the zone be relativized?
    @type relativize: bool
    @cvar node_factory: the factory used to create a new node
    @type node_factory: class or callable
    �rdclass�origin�nodes�
relativizeTcCsb|dk	rFt|t�r tjj|�}nt|tjj�s6td��|j�sFtd��||_||_	i|_
||_dS)z�Initialize a zone object.

        @param origin: The origin of the zone.
        @type origin: dns.name.Name object
        @param rdclass: The zone's rdata class; the default is class IN.
        @type rdclass: intNz2origin parameter must be convertible to a DNS namez)origin parameter must be an absolute name)�
isinstancer�dns�name�	from_text�Name�
ValueError�is_absoluterrrr)�selfrrrr
r
r�__init__Ys
z
Zone.__init__cCs:t|t�sdS|j|jks2|j|jks2|j|jkr6dSdS)ziTwo zones are equal if they have the same origin, class, and
        nodes.
        @rtype: bool
        FT)rrrrr)r�otherr
r
r�__eq__ns
zZone.__eq__cCs|j|�S)z6Are two zones not equal?
        @rtype: bool
        )r!)rr r
r
r�__ne__|szZone.__ne__cCsbt|t�rtjj|d�}nt|tjj�s0td��|j�r^|j|j	�sLtd��|j
r^|j
|j	�}|S)Nz0name parameter must be convertible to a DNS namez5name parameter must be a subdomain of the zone origin)rrrrrr�KeyErrorr�is_subdomainrr)rrr
r
r�_validate_name�s
zZone._validate_namecCs|j|�}|j|S)N)r%r)r�keyr
r
r�__getitem__�s
zZone.__getitem__cCs|j|�}||j|<dS)N)r%r)rr&�valuer
r
r�__setitem__�s
zZone.__setitem__cCs|j|�}|j|=dS)N)r%r)rr&r
r
r�__delitem__�s
zZone.__delitem__cCs
|jj�S)N)r�__iter__)rr
r
rr+�sz
Zone.__iter__cCstr|jj�S|jj�SdS)N)�_py3r�keys�iterkeys)rr
r
rr.�s
z
Zone.iterkeyscCs
|jj�S)N)rr-)rr
r
rr-�sz	Zone.keyscCstr|jj�S|jj�SdS)N)r,r�values�
itervalues)rr
r
rr0�s
zZone.itervaluescCs
|jj�S)N)rr/)rr
r
rr/�szZone.valuescCs
|jj�S)N)r�items)rr
r
rr1�sz
Zone.itemscCs|j|�}|jj|�S)N)r%r�get)rr&r
r
rr2�s
zZone.getcCs
||jkS)N)r)rr r
r
r�__contains__�szZone.__contains__FcCs<|j|�}|jj|�}|dkr8|s&t�|j�}||j|<|S)arFind a node in the zone, possibly creating it.

        @param name: the name of the node to find
        @type name: dns.name.Name object or string
        @param create: should the node be created if it doesn't exist?
        @type create: bool
        @raises KeyError: the name is not known and create was not specified.
        @rtype: dns.node.Node object
        N)r%rr2r#�node_factory)rr�create�noder
r
r�	find_node�s

zZone.find_nodecCs.y|j||�}Wntk
r(d}YnX|S)a�Get a node in the zone, possibly creating it.

        This method is like L{find_node}, except it returns None instead
        of raising an exception if the node does not exist and creation
        has not been requested.

        @param name: the name of the node to find
        @type name: dns.name.Name object or string
        @param create: should the node be created if it doesn't exist?
        @type create: bool
        @rtype: dns.node.Node object or None
        N)r7r#)rrr5r6r
r
r�get_node�s

z
Zone.get_nodecCs |j|�}||jkr|j|=dS)zhDelete the specified node if it exists.

        It is not an error if the node does not exist.
        N)r%r)rrr
r
r�delete_node�s

zZone.delete_nodecCsT|j|�}t|t�r tjj|�}t|t�r6tjj|�}|j||�}|j|j|||�S)a�Look for rdata with the specified name and type in the zone,
        and return an rdataset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        The rdataset returned is not a copy; changes to it will change
        the zone.

        KeyError is raised if the name or type are not found.
        Use L{get_rdataset} if you want to have None returned instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @param create: should the node and rdataset be created if they do not
        exist?
        @type create: bool
        @raises KeyError: the node or rdata could not be found
        @rtype: dns.rrset.RRset object
        )	r%rrr�	rdatatyperr7�
find_rdatasetr)rr�rdtype�coversr5r6r
r
rr;�s


zZone.find_rdatasetcCs2y|j||||�}Wntk
r,d}YnX|S)a�Look for rdata with the specified name and type in the zone,
        and return an rdataset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        The rdataset returned is not a copy; changes to it will change
        the zone.

        None is returned if the name or type are not found.
        Use L{find_rdataset} if you want to have KeyError raised instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @param create: should the node and rdataset be created if they do not
        exist?
        @type create: bool
        @rtype: dns.rrset.RRset object
        N)r;r#)rrr<r=r5�rdatasetr
r
r�get_rdatasets

zZone.get_rdatasetcCsr|j|�}t|t�r tjj|�}t|t�r6tjj|�}|j|�}|dk	rn|j|j||�t	|�dkrn|j
|�dS)a�Delete the rdataset matching I{rdtype} and I{covers}, if it
        exists at the node specified by I{name}.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        It is not an error if the node does not exist, or if there is no
        matching rdataset at the node.

        If the node has no rdatasets after the deletion, it will itself
        be deleted.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        Nr)r%rrrr:rr8�delete_rdatasetr�lenr9)rrr<r=r6r
r
rr@4s



zZone.delete_rdatasetcCs.|j|jkrtd��|j|d�}|j|�dS)a:Replace an rdataset at name.

        It is not an error if there is no rdataset matching I{replacement}.

        Ownership of the I{replacement} object is transferred to the zone;
        in other words, this method does not store a copy of I{replacement}
        at the node, it stores I{replacement} itself.

        If the I{name} node does not exist, it is created.

        @param name: the owner name
        @type name: DNS.name.Name object or string
        @param replacement: the replacement rdataset
        @type replacement: dns.rdataset.Rdataset
        z#replacement.rdclass != zone.rdclassTN)rrr7�replace_rdataset)rrZreplacementr6r
r
rrBUszZone.replace_rdatasetcCsn|j|�}t|t�r tjj|�}t|t�r6tjj|�}|j|j|j||�}tj	j
||j||�}|j|�|S)a�Look for rdata with the specified name and type in the zone,
        and return an RRset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        This method is less efficient than the similar
        L{find_rdataset} because it creates an RRset instead of
        returning the matching rdataset.  It may be more convenient
        for some uses since it returns an object which binds the owner
        name to the rdata.

        This method may not be used to create new nodes or rdatasets;
        use L{find_rdataset} instead.

        KeyError is raised if the name or type are not found.
        Use L{get_rrset} if you want to have None returned instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @raises KeyError: the node or rdata could not be found
        @rtype: dns.rrset.RRset object
        )r%rrrr:rrr;r�rrsetZRRset�update)rrr<r=r>rCr
r
r�
find_rrsetks



zZone.find_rrsetcCs0y|j|||�}Wntk
r*d}YnX|S)aJLook for rdata with the specified name and type in the zone,
        and return an RRset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        This method is less efficient than the similar L{get_rdataset}
        because it creates an RRset instead of returning the matching
        rdataset.  It may be more convenient for some uses since it
        returns an object which binds the owner name to the rdata.

        This method may not be used to create new nodes or rdatasets;
        use L{find_rdataset} instead.

        None is returned if the name or type are not found.
        Use L{find_rrset} if you want to have KeyError raised instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @rtype: dns.rrset.RRset object
        N)rEr#)rrr<r=rCr
r
r�	get_rrset�s

zZone.get_rrsetccs~t|t�rtjj|�}t|t�r,tjj|�}xL|j�D]@\}}x6|D].}|tjjksh|j|krD|j|krD||fVqDWq6WdS)a�Return a generator which yields (name, rdataset) tuples for
        all rdatasets in the zone which have the specified I{rdtype}
        and I{covers}.  If I{rdtype} is dns.rdatatype.ANY, the default,
        then all rdatasets will be matched.

        @param rdtype: int or string
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        N)	rrrr:r�	iteritems�ANYr<r=)rr<r=rr6�rdsr
r
r�iterate_rdatasets�s


zZone.iterate_rdatasetsccs�t|t�rtjj|�}t|t�r,tjj|�}x^|j�D]R\}}xH|D]@}|tjjksh|j|krD|j|krDx|D]}||j	|fVqnWqDWq6WdS)a�Return a generator which yields (name, ttl, rdata) tuples for
        all rdatas in the zone which have the specified I{rdtype}
        and I{covers}.  If I{rdtype} is dns.rdatatype.ANY, the default,
        then all rdatas will be matched.

        @param rdtype: int or string
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        N)
rrrr:rrGrHr<r=�ttl)rr<r=rr6rI�rdatar
r
r�iterate_rdatas�s



zZone.iterate_rdatasNcCs8t|t�rt|d�}d}nd}t|dd�}|dkr6d}|dkrPtjj|�}d}n"t|t�rf|j|�}n|}|j�}z�|r�t|j	��}|j
�n|j�}x�|D]�}	||	j|	|j
|d�}
t|
t�r�|
j|�}n|
}|
j�}
y|j|�|j|�Wq�tk
�r|j|
�|j|�Yq�Xq�WWd|�r2|j�XdS)	aWrite a zone to a file.

        @param f: file or string.  If I{f} is a string, it is treated
        as the name of a file to open.
        @param sorted: if True, the file will be written with the
        names sorted in DNSSEC order from least to greatest.  Otherwise
        the names will be written in whatever order they happen to have
        in the zone's dictionary.
        @param relativize: if True, domain names in the output will be
        relativized to the zone's origin (if possible).
        @type relativize: bool
        @param nl: The end of line string.  If not specified, the
        output will use the platform's native end-of-line marker (i.e.
        LF on POSIX, CRLF on Windows, CR on Macintosh).
        @type nl: string or None
        �wbTF�encodingNzutf-8�
)rr)rr�open�getattr�os�linesep�encode�decode�listr-�sortr.�to_textrr�write�	TypeError�close)r�f�sortedr�nl�
want_closeZfile_encZnl_b�names�n�lZl_br
r
r�to_file�sD







zZone.to_filecCs*t�}|j||||�|j�}|j�|S)a�Return a zone's text as though it were written to a file.

        @param sorted: if True, the file will be written with the
        names sorted in DNSSEC order from least to greatest.  Otherwise
        the names will be written in whatever order they happen to have
        in the zone's dictionary.
        @param relativize: if True, domain names in the output will be
        relativized to the zone's origin (if possible).
        @type relativize: bool
        @param nl: The end of line string.  If not specified, the
        output will use the platform's native end-of-line marker (i.e.
        LF on POSIX, CRLF on Windows, CR on Macintosh).
        @type nl: string or None
        )rrd�getvaluer\)rr^rr_Ztemp_bufferZreturn_valuer
r
rrY$s
zZone.to_textcCsJ|jrtjj}n|j}|j|tjj�dkr.t�|j|tjj	�dkrFt
�dS)z�Do some simple checking of the zone's origin.

        @raises dns.zone.NoSOA: there is no SOA RR
        @raises dns.zone.NoNS: there is no NS RRset
        @raises KeyError: there is no origin node
        N)rrr�emptyrr?r:ZSOArZNSr)rrr
r
r�check_origin9s
zZone.check_origin)F)F)TTN)TTN),r	r
rrrr6ZNoder4�	__slots__�
rdataclass�INrr!r"r%r'r)r*r+r.r-r0r/r1rGr2r3r7r8r9r:ZNONEr;r?r@rBrErFrHrJrMrdrYrgr
r
r
rr=sJ



# !("
@
rc@sHeZdZdZeddfdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dS)�
_MasterReadera�Read a DNS master file

    @ivar tok: The tokenizer
    @type tok: dns.tokenizer.Tokenizer object
    @ivar ttl: The default TTL
    @type ttl: int
    @ivar last_name: The last name read
    @type last_name: dns.name.Name object
    @ivar current_origin: The current origin
    @type current_origin: dns.name.Name object
    @ivar relativize: should names in the zone be relativized?
    @type relativize: bool
    @ivar zone: the zone
    @type zone: dns.zone.Zone object
    @ivar saved_state: saved reader state (used when processing $INCLUDE)
    @type saved_state: list of (tokenizer, current_origin, last_name, file)
    tuples.
    @ivar current_file: the file object of the $INCLUDed file being parsed
    (None if no $INCLUDE is active).
    @ivar allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @ivar check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    FTcCsbt|t�rtjj|�}||_||_||_d|_|j|_	||||d�|_
g|_d|_||_
||_dS)Nr)r)rrrrr�tok�current_originrrK�	last_name�zone�saved_state�current_file�
allow_includerg)rrlrrr�zone_factoryrrrgr
r
rrfs
z_MasterReader.__init__cCsx|jj�}|j�rPqWdS)N)rlr2�
is_eol_or_eof)r�tokenr
r
r�	_eat_lineus
z_MasterReader._eat_linec"Cs�|jdkrt�|jjdd�}|j�s:tjj|j|j�|_	n"|jj�}|j
�rPdS|jj|�|j	}|j|j
j�s||j�dS|jr�|j|j
j�}|jj�}|j�s�tjj�y,tjj|j�}|jj�}|j�s�tjj�Wntjjk
r�|j}YnXy.tjj|j�}|jj�}|j��s"tjj�Wn>tjjk
�rFtjj�Yntk
�rb|j
j}YnX||j
jk�r~tjjd��ytjj|j�}Wntjjd|j��YnX|j
jj|�}|dk�r�|j
j�}||j
j|<ytjj|||j|jd�}Wnltjjk
�r,tj�dd�\}}	|	�Yn<tj�dd�\}}	tjjdt|�t|	�f��YnX|j |j
j|j�|j!�}
|j"|||
d�}|j#||�dS)	z(Process one line from a DNS master file.NT)Zwant_leadingzRR class is not zone's classzunknown rdatatype '%s'F�zcaught exception %s: %s)$rmrrlr2Z
is_whitespacerrrr(rnrt�ungetr$rorrvr�
is_identifier�	exception�SyntaxErrorrK�BadTTLri�	Exceptionrr:rr4rL�sys�exc_info�str�choose_relativityr=r;�add)rrurrKrr<rb�rd�ty�var=rIr
r
r�_rr_line{sx







z_MasterReader._rr_linec
Cs�tjd�}tjd�}tjd�}|j|�}|rJ|j�\}}}}	}
|dkrJd}|j|�}|rz|j�\}}}|dkrrd}d}	d}
|j|�}|r�|j�\}}}}	|dkr�d}|j�d}	d}
|p�|p�|s�d}d}d}d}	d}
|
dkr�t��||||	|
fS)	Nz"^.*\$({(\+|-?)(\d+),(\d+),(.)}).*$z^.*\$({(\+|-?)(\d+)}).*$z^.*\$({(\+|-?)(\d+),(\d+)}).*$��+r�drw)�re�compile�match�groups�NotImplementedError)
rZsideZis_generate1Zis_generate2Zis_generate3Zg1�modZsign�offset�width�baseZg2Zg3r
r
r�
_parse_modify�s>





z_MasterReader._parse_modifyc!7Cs|jdkrt�|jj�}y2tjj|j�\}}}|jj�}|j�sHtj	j
�Wntj	j
�YnXy$|j}|jj�}|j�s�tj	j
�Wntj	j
�YnXy,tjj|j�}|jj�}|j�s�tj	j
�Wntjjk
r�|j}YnXy.tj
j|j�}|jj�}|j��stj	j
�Wn>tj	j
k
�r6tj	j
�Yntk
�rR|jj}YnX||jjk�rntj	j
d��y.tjj|j�}|jj�}|j��s�tj	j
�Wn(tk
�r�tj	j
d|j��YnXy
|j}	Wntj	j
�YnX|j|�\}
}}}
}|j|	�\}}}}}�x�t||d|�D�]�}|dk�r@|t|�}n|dk�rV|t|�}|dk�rn|t|�}n|dk�r�|t|�}t|�jt|
��}t|�jt|��}|jd|
|�}|	jd||�}tjj||j�|_|j}|j|jj��s�|j�dS|j�r|j|jj�}|jjj|�}|dk�r@|jj�}||jj|<ytj j||||jd�}Wnltj	j
k
�r�t!j"�dd	�\}}|�Yn<t!j"�dd	�\}}tj	j
d
t|�t|�f��YnX|j#|jj|j�|j$�}|j%|||d�} | j&||��q"WdS)zRProcess one line containing the GENERATE statement from a DNS
        master file.NzRR class is not zone's classzunknown rdatatype '%s'rr��-z$%sFrwzcaught exception %s: %sT)'rmrrlr2rZgrangerr(ryrzr{rKr|rir}rorr:r��range�intr��zfill�replacerrnr$rrvrrr4rLr~rr�r=r;r�)!rru�start�stop�stepZlhsrKrr<ZrhsZlmodZlsignZloffsetZlwidthZlbaseZrmodZrsignZroffsetZrwidthZrbase�iZlindex�rindexZlzfindexZrzfindexrrLrbr�r�r�r=rIr
r
r�_generate_line�s�















z_MasterReader._generate_linecCs��y�x|jjdd�}|j�rh|jdk	r2|jj�t|j�dkrb|jjd�\|_|_|_	|_|_
qP�n�|j�rvq�n�|j�r�|jj
�q�nx|jddk�r|jj�}|dkr�|jj�}|j�s�tjjd��tj
j|j�|_
|jj
�q|dk�r$|jj�|_|jj
�|jjdk�r|j|j_q|d	k�r�|j�r�|jj�}|j}|jj�}|j��rxtjj|j|j�}|jj
�n|j��s�tjjd
��n|j}|jj|j|j|j	|j|j
f�t|d�|_tjj|j|�|_||_q|dk�r�|j�qtjjd
|d��q|jj |�|j!�qWWnZtjjk
�rz}z8|jj"�\}}|dk�rTd}tjjd|||f��WYdd}~XnX|j#�r�|jj#�dS)z�Read a DNS master file and build a zone object.

        @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
        @raises dns.zone.NoNS: No NS RRset was found at the zone origin
        TNrr�$z$TTLzbad $TTLz$ORIGINz$INCLUDEzbad origin in $INCLUDE�rz	$GENERATEzUnknown master file directive '�'zsyntax errorz	%s:%d: %s���)$rlr2Zis_eofrqr\rArp�poprmrnrKZis_eolZ
is_commentZget_eolr(�upperryrrzr{rZget_namerorrrrrt�appendrQ�	tokenizer�	Tokenizerr�rxr��whererg)rru�c�filenameZ
new_originZdetailZline_numberr
r
r�reades�

 















"z_MasterReader.readN)r	r
rrrrrvr�r�r�r�r
r
r
rrkJsL)urkTFc
	Cs>|dkrd}tjj||�}t|||||||d�}	|	j�|	jS)arBuild a zone object from a master file format string.

    @param text: the master file format input
    @type text: string.
    @param origin: The origin of the zone; if not specified, the first
    $ORIGIN statement in the master file will determine the origin of the
    zone.
    @type origin: dns.name.Name object or string
    @param rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @param relativize: should names be relativized?  The default is True
    @type relativize: bool
    @param zone_factory: The zone factory to use
    @type zone_factory: function returning a Zone
    @param filename: The filename to emit when describing where an error
    occurred; the default is '<string>'.
    @type filename: string
    @param allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    Nz<string>)rrrg)rr�r�rkr�ro)
�textrrrrsr�rrrgrl�readerr
r
rr�s"rcCslt}d}	t||�r.|dkr|}t||	�}d}
n|dkr:d}d}
zt||||||||�}Wd|
rf|j�X|S)a�Read a master file and build a zone object.

    @param f: file or string.  If I{f} is a string, it is treated
    as the name of a file to open.
    @param origin: The origin of the zone; if not specified, the first
    $ORIGIN statement in the master file will determine the origin of the
    zone.
    @type origin: dns.name.Name object or string
    @param rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @param relativize: should names be relativized?  The default is True
    @type relativize: bool
    @param zone_factory: The zone factory to use
    @type zone_factory: function returning a Zone
    @param filename: The filename to emit when describing where an error
    occurred; the default is '<file>', or the value of I{f} if I{f} is a
    string.
    @type filename: string
    @param allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    ZrUNTz<file>F)rrrQrr\)r]rrrrsr�rrrgZstr_typeZoptsr`�zr
r
r�	from_file�s 


r�cCs�d}x�|D]�}|dkrH|r"|j}n|jdj}|jdj}||||d�}x||jD]r}|jj|j�}	|	sz|j�}	|	|j|j<|	j|j|j|j	d�}
|
j
|j�x$|D]}|j|j|�|
j
|�q�WqPWq
W|r�|j�|S)a�Convert the output of a zone transfer generator into a zone object.

    @param xfr: The xfr generator
    @type xfr: generator of dns.message.Message objects
    @param relativize: should names be relativized?  The default is True.
    It is essential that the relativize setting matches the one specified
    to dns.query.xfr().
    @type relativize: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    Nr)rT)rZanswerrrrr2r4r;r<r=Z
update_ttlrKr�r�rg)Zxfrrsrrgr�r�rrrCZznodeZzrdsr�r
r
r�from_xfrs,


r�)r)&rZ
__future__rr~r�rS�iorZ
dns.exceptionrZdns.nameZdns.nodeZdns.rdataclassZ
dns.rdatatypeZ	dns.rdataZ	dns.rrsetZ
dns.tokenizerZdns.ttlZ
dns.grangeZ_compatrr�version_infor,rzZDNSExceptionrrrr�objectrrkrirjrr�r�r
r
r
r�<module>sH
o*3PKi�\�VJ��8�8$__pycache__/tokenizer.cpython-36.pycnu�[���3

�b�W�G�@s�dZddlmZddlZddlZddlZddlZddlm	Z	m
Z
mZdddddddd�ZddiZ
dZdZd	Zd
ZdZdZd
ZGdd�dejj�ZGdd�de�ZGdd�de�ZdS)zTokenize DNS master file format�)�StringION�)�long�	text_type�binary_typeT)� �	�
�;�(�)�"r
�����c@seZdZdZdS)�UngetBufferFullzDAn attempt was made to unget a token when the unget buffer was full.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/tokenizer.pyr.src@s�eZdZdZd%dd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$S)&�Tokenz�A DNS master file format token.

    @ivar ttype: The token type
    @type ttype: int
    @ivar value: The token value
    @type value: string
    @ivar has_escape: Does the token value contain escapes?
    @type has_escape: bool
    �FcCs||_||_||_dS)aInitialize a token instance.

        @param ttype: The token type
        @type ttype: int
        @param value: The token value
        @type value: string
        @param has_escape: Does the token value contain escapes?
        @type has_escape: bool
        N)�ttype�value�
has_escape)�selfrrrrrr�__init__?s
zToken.__init__cCs
|jtkS)N)r�EOF)rrrr�is_eofMszToken.is_eofcCs
|jtkS)N)r�EOL)rrrr�is_eolPszToken.is_eolcCs
|jtkS)N)r�
WHITESPACE)rrrr�
is_whitespaceSszToken.is_whitespacecCs
|jtkS)N)r�
IDENTIFIER)rrrr�
is_identifierVszToken.is_identifiercCs
|jtkS)N)r�
QUOTED_STRING)rrrr�is_quoted_stringYszToken.is_quoted_stringcCs
|jtkS)N)r�COMMENT)rrrr�
is_comment\szToken.is_commentcCs
|jtkS)N)r�	DELIMITER)rrrr�is_delimiter_szToken.is_delimitercCs|jtkp|jtkS)N)rr#r!)rrrr�
is_eol_or_eofbszToken.is_eol_or_eofcCs&t|t�sdS|j|jko$|j|jkS)NF)�
isinstancerrr)r�otherrrr�__eq__es
zToken.__eq__cCs&t|t�sdS|j|jkp$|j|jkS)NT)r0rrr)rr1rrr�__ne__ks
zToken.__ne__cCsd|j|jfS)Nz%d "%s")rr)rrrr�__str__qsz
Token.__str__cCs|js
|Sd}t|j�}d}x�||kr�|j|}|d7}|dkr�||krPtjj�|j|}|d7}|j�r�||krztjj�|j|}|d7}||kr�tjj�|j|}|d7}|j�o�|j�s�tjj�tt	|�dt	|�dt	|��}||7}qWt
|j|�S)Nrrr�\�d�
)r�lenr�dns�	exception�
UnexpectedEnd�isdigit�SyntaxError�chr�intrr)rZ	unescaped�l�i�c�c2�c3rrr�unescapets6





$zToken.unescapecCsdS)Nrr)rrrr�__len__�sz
Token.__len__cCst|j|jf�S)N)�iterrr)rrrr�__iter__�szToken.__iter__cCs$|dkr|jS|dkr|jSt�dS)Nrr)rr�
IndexError)rrArrr�__getitem__�s
zToken.__getitem__N)rF)rrrrr r"r$r&r(r*r,r.r/r2r3r4rErFrHrJrrrrr3s"

rc@s�eZdZdZejdfdd�Zdd�Zdd�Zd	d
�Z	dd�Z
d(dd�Zdd�Zdd�Z
e
Zdd�Zdd�Zdd�Zdd�Zdd�Zd)dd�Zd*d d!�Zd+d"d#�Zd$d%�Zd&d'�ZdS),�	Tokenizera�A DNS master file format tokenizer.

    A token is a (type, value) tuple, where I{type} is an int, and
    I{value} is a string.  The valid types are EOF, EOL, WHITESPACE,
    IDENTIFIER, QUOTED_STRING, COMMENT, and DELIMITER.

    @ivar file: The file to tokenize
    @type file: file
    @ivar ungotten_char: The most recently ungotten character, or None.
    @type ungotten_char: string
    @ivar ungotten_token: The most recently ungotten token, or None.
    @type ungotten_token: (int, string) token tuple
    @ivar multiline: The current multiline level.  This value is increased
    by one every time a '(' delimiter is read, and decreased by one every time
    a ')' delimiter is read.
    @type multiline: int
    @ivar quoting: This variable is true if the tokenizer is currently
    reading a quoted string.
    @type quoting: bool
    @ivar eof: This variable is true if the tokenizer has encountered EOF.
    @type eof: bool
    @ivar delimiters: The current delimiter dictionary.
    @type delimiters: dict
    @ivar line_number: The current line number
    @type line_number: int
    @ivar filename: A filename that will be returned by the L{where} method.
    @type filename: string
    NcCs�t|t�r t|�}|dkr`d}n@t|t�rDt|j��}|dkr`d}n|dkr`|tjkr\d}nd}||_d|_d|_	d|_
d|_d|_t
|_d|_||_dS)a�Initialize a tokenizer instance.

        @param f: The file to tokenize.  The default is sys.stdin.
        This parameter may also be a string, in which case the tokenizer
        will take its input from the contents of the string.
        @type f: file or string
        @param filename: the name of the filename that the L{where} method
        will return.
        @type filename: string
        Nz<string>z<stdin>z<file>rFr)r0rrr�decode�sys�stdin�file�
ungotten_char�ungotten_token�	multiline�quoting�eof�_DELIMITERS�
delimiters�line_number�filename)r�frXrrrr �s*


zTokenizer.__init__cCsZ|jdkrJ|jrd}qV|jjd�}|dkr2d|_qV|dkrV|jd7_n|j}d|_|S)z<Read a character from input.
        @rtype: string
        NrrTr	)rPrTrO�readrW)rrBrrr�	_get_char�s
zTokenizer._get_charcCs|j|jfS)z�Return the current location in the input.

        @rtype: (string, int) tuple.  The first item is the filename of
        the input, the second is the current line number.
        )rXrW)rrrr�where�szTokenizer.wherecCs|jdk	rt�||_dS)aEUnget a character.

        The unget buffer for characters is only one character large; it is
        an error to try to unget a character when the unget buffer is not
        empty.

        @param c: the character to unget
        @type c: string
        @raises UngetBufferFull: there is already an ungotten char
        N)rPr)rrBrrr�_unget_chars
zTokenizer._unget_charcCsLd}xB|j�}|dkr<|dkr<|dks.|jr<|j|�|S|d7}qWdS)a(Consume input until a non-whitespace character is encountered.

        The non-whitespace character is then ungotten, and the number of
        whitespace characters consumed is returned.

        If the tokenizer is in multiline mode, then newlines are whitespace.

        @rtype: int
        rrrr	rN)r[rRr])r�skippedrBrrr�skip_whitespaces
zTokenizer.skip_whitespaceFc
CsT|jdk	r>|j}d|_|j�r(|r>|Sn|j�r:|r>|Sn|S|j�}|r\|dkr\ttd�Sd}t}d}�x�|j�}|dks�||jk�r|dkr�|j	r�t
jj�|dko�|t
k�r|dkr�|jd7_|j�ql�q|dk�r
|jdkr�t
jj�|jd8_|j�qln�|d	k�rH|j	�s0d
|_	t|_t
}qlnd|_	t|_|j�qln�|dk�r\ttd�S|dk�r�x,|j�}|dk�s�|dk�r�P||7}�qhW|�r�|j|�tt|�S|dk�r�|j�r�t
jjd
��tt�S|j�r�|j�d}qln
ttd�Sn|}t}n
|j|�P�n�|j	�r�|dk�r�|j�}|dk�r>t
jj�|j��r�|j�}|dk�rbt
jj�|j�}	|dk�r|t
jj�|j��o�|	j��s�t
jj�tt|�dt|�dt|	��}n|dk�rt
jjd��n:|dk�r||7}d
}|j�}|dk�s|dk�rt
jj�||7}qlW|dk�rH|t
k�rH|j�rDt
jjd
��t}t|||�S)aGet the next token.

        @param want_leading: If True, return a WHITESPACE token if the
        first character read is whitespace.  The default is False.
        @type want_leading: bool
        @param want_comment: If True, return a COMMENT token if the
        first token read is a comment.  The default is False.
        @type want_comment: bool
        @rtype: Token object
        @raises dns.exception.UnexpectedEnd: input ended prematurely
        @raises dns.exception.SyntaxError: input was badly formed
        NrrrFrrrr
Tr	r
zunbalanced parenthesesr5r6r7znewline in quoted string)rQr&r,r_rr%r'r[rVrSr9r:r;r)rRr=�_QUOTING_DELIMITERSrUr#r]r+r!r-r<r>r?)
rZwant_leadingZwant_comment�tokenr^rrrBrCrDrrr�get%s�
















&

z
Tokenizer.getcCs|jdk	rt�||_dS)a@Unget a token.

        The unget buffer for tokens is only one token large; it is
        an error to try to unget a token when the unget buffer is not
        empty.

        @param token: the token to unget
        @type token: Token object
        @raises UngetBufferFull: there is already an ungotten token
        N)rQr)rrarrr�unget�s
zTokenizer.ungetcCs|j�}|j�rt�|S)zLReturn the next item in an iteration.
        @rtype: (int, string)
        )rbr"�
StopIteration)rrarrr�next�szTokenizer.nextcCs|S)Nr)rrrrrH�szTokenizer.__iter__cCs@|j�j�}|j�s tjjd��|jj�s6tjjd��t|j�S)z|Read the next token and interpret it as an integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        zexpecting an identifierzexpecting an integer)	rbrEr(r9r:r=rr<r?)rrarrr�get_int�s
zTokenizer.get_intcCs,|j�}|dks|dkr(tjjd|��|S)z�Read the next token and interpret it as an 8-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        r�z#%d is not an unsigned 8-bit integer)rfr9r:r=)rrrrr�	get_uint8�s

zTokenizer.get_uint8cCs,|j�}|dks|dkr(tjjd|��|S)z�Read the next token and interpret it as a 16-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        ri��z$%d is not an unsigned 16-bit integer)rfr9r:r=)rrrrr�
get_uint16�s

zTokenizer.get_uint16cCsh|j�j�}|j�s tjjd��|jj�s6tjjd��t|j�}|dksT|td�krdtjjd|��|S)z�Read the next token and interpret it as a 32-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        zexpecting an identifierzexpecting an integerrlz$%d is not an unsigned 32-bit integer)	rbrEr(r9r:r=rr<r)rrarrrr�
get_uint32�s


zTokenizer.get_uint32cCs.|j�j�}|j�p|j�s(tjjd��|jS)z}Read the next token and interpret it as a string.

        @raises dns.exception.SyntaxError:
        @rtype: string
        zexpecting a string)rbrEr(r*r9r:r=r)r�originrarrr�
get_string�szTokenizer.get_stringcCs&|j�j�}|j�s tjjd��|jS)z�Read the next token and raise an exception if it is not an identifier.

        @raises dns.exception.SyntaxError:
        @rtype: string
        zexpecting an identifier)rbrEr(r9r:r=r)rrkrarrr�get_identifier
szTokenizer.get_identifiercCs,|j�}|j�stjjd��tjj|j|�S)z�Read the next token and interpret it as a DNS name.

        @raises dns.exception.SyntaxError:
        @rtype: dns.name.Name objectzexpecting an identifier)rbr(r9r:r=�name�	from_textr)rrkrarrr�get_nameszTokenizer.get_namecCs.|j�}|j�s(tjjd|j|jf��|jS)z�Read the next token and raise an exception if it isn't EOL or
        EOF.

        @raises dns.exception.SyntaxError:
        @rtype: string
        z expected EOL or EOF, got %d "%s")rbr/r9r:r=rr)rrarrr�get_eol!szTokenizer.get_eolcCs.|j�j�}|j�s tjjd��tjj|j�S)Nzexpecting an identifier)	rbrEr(r9r:r=Zttlror)rrarrr�get_ttl0szTokenizer.get_ttl)FF)N)N)N)rrrrrMrNr r[r\r]r_rbrcre�__next__rHrfrhrirjrlrmrprqrrrrrrrK�s($	
{



rK)r�iorrMZ
dns.exceptionr9Zdns.nameZdns.ttlZ_compatrrrrUr`r!r#r%r'r)r+r-r:ZDNSExceptionr�objectrrKrrrr�<module>s0oPKi�\�8�Yww __pycache__/rrset.cpython-36.pycnu�[���3

�$�Wk�@sldZddlZddlZddlZddlZddlmZGdd�dejj	�Z
ddd�Zd	d
�Zddd�Z
d
d�ZdS)z)DNS RRsets (an RRset is a named rdataset)�N�)�string_typescs�eZdZdZddgZejjdf�fdd�	Z�fdd�Z	d	d
�Z
dd�Z�fd
d�Zd�fdd�	Z
d�fdd�	Zd�fdd�	Zdd�Z�ZS)�RRseta6A DNS RRset (named rdataset).

    RRset inherits from Rdataset, and RRsets can be treated as
    Rdatasets in most cases.  There are, however, a few notable
    exceptions.  RRsets have different to_wire() and to_text() method
    arguments, reflecting the fact that RRsets always have an owner
    name.
    �name�deletingNcs$tt|�j|||�||_||_dS)zCreate a new RRset.N)�superr�__init__rr)�selfr�rdclass�rdtype�coversr)�	__class__��/usr/lib/python3.6/rrset.pyr'szRRset.__init__cs"tt|�j�}|j|_|j|_|S)N)rr�_clonerr)r	�obj)r
rrr/szRRset._clonecCs�|jdkrd}ndtjj|j�d}|jdk	rDdtjj|j�}nd}dt|j�dtjj|j�dtjj|j	�||dS)	Nr��(�)z delete=z<DNS � z RRset>)
r�dns�	rdatatype�to_textr�
rdataclass�strrr
r)r	ZctextZdtextrrr�__repr__5s

zRRset.__repr__cCs|j�S)N)r)r	rrr�__str__Bsz
RRset.__str__cs.t|t�sdS|j|jkrdStt|�j|�S)zcTwo RRsets are equal if they have the same name and the same
        rdataset

        @rtype: boolF)�
isinstancerrr�__eq__)r	�other)r
rrrEs

zRRset.__eq__cs4tt|�j|||�sdS|j|ks,|j|kr0dSdS)zaReturns True if this rrset matches the specified class, type,
        covers, and deletion state.FT)rr�matchrr)r	rr
rrr)r
rrr Ps
zRRset.matchTcstt|�j|j|||jf|�S)a�Convert the RRset into DNS master file format.

        @see: L{dns.name.Name.choose_relativity} for more information
        on how I{origin} and I{relativize} determine the way names
        are emitted.

        Any additional keyword arguments are passed on to the rdata
        to_text() method.

        @param origin: The origin for relative names, or None.
        @type origin: dns.name.Name object
        @param relativize: True if names should names be relativized
        @type relativize: bool)rrrrr)r	�originZ
relativize�kw)r
rrrZsz
RRset.to_textcs tt|�j|j||||jf|�S)z!Convert the RRset to wire format.)rr�to_wirerr)r	�file�compressr!r")r
rrr#lsz
RRset.to_wirecCstjj|jt|��S)zYConvert an RRset into an Rdataset.

        @rtype: dns.rdataset.Rdataset object
        )r�rdataset�from_rdata_list�ttl�list)r	rrr�to_rdatasetrszRRset.to_rdataset)N)NT)NN)�__name__�
__module__�__qualname__�__doc__�	__slots__rrZNONErrrrrr rr#r*�
__classcell__rr)r
rrs	

rc	Cs�t|t�rtjj|d|d�}t|t�r2tjj|�}t|t�rHtjj|�}t|||�}|j|�x*|D]"}tj	j|j
|j|�}|j|�qdW|S)z�Create an RRset with the specified name, TTL, class, and type, and with
    the specified list of rdatas in text format.

    @rtype: dns.rrset.RRset object
    N)�
idna_codec)
rrrr�	from_textrrr�
update_ttlZrdatar
r�add)	rr(r
r�text_rdatasr1�r�t�rdrrr�from_text_listzs




r9cGst|||||�S)z�Create an RRset with the specified name, TTL, class, and type and with
    the specified rdatas in text format.

    @rtype: dns.rrset.RRset object
    )r9)rr(r
rr5rrrr2�sr2cCsrt|t�rtjj|d|d�}t|�dkr0td��d}x8|D]0}|dkr`t||j|j	�}|j
|�|j|�q:W|S)z�Create an RRset with the specified name and TTL, and with
    the specified list of rdata objects.

    @rtype: dns.rrset.RRset object
    N)r1rzrdata list must not be empty)rrrrr2�len�
ValueErrorrr
rr3r4)rr(�rdatasr1r6r8rrrr'�s


r'cGst|||�S)z�Create an RRset with the specified name and TTL, and with
    the specified rdata objects.

    @rtype: dns.rrset.RRset object
    )r')rr(r<rrr�
from_rdata�sr=)N)N)r.Zdns.namerZdns.rdatasetZdns.rdataclassZdns.rendererZ_compatrr&ZRdatasetrr9r2r'r=rrrr�<module>sa


PKi�\b�CI(__pycache__/_compat.cpython-36.opt-1.pycnu�[���3

�b�W!�@s�ddlZddlZddlmZejdkr0eZeZneZeZejd
krfeZ	e
ZefZe
Zdd�Zdd�Zn"eZ	eZefZeZdd�Zd	d�Zd
d�ZdS)�N)�Context�cCs|j�S)N)�decode)�x�r�/usr/lib/python3.6/_compat.py�maybe_decodesrcCs|j�S)N)�encode)rrrr�maybe_encodesr
cCs|S)Nr)rrrrrscCs|S)Nr)rrrrr
scCs,tttt|���tjd�jt|��}t|�S)z�
    Python 2 and Python 3 use different rounding strategies in round(). This
    function ensures that results are python2/3 compatible and backward
    compatible with previous py2 releases
    :param what: float
    :return: rounded long
    )ZprecZrounding)r�len�str�long�decimalZ
ROUND_HALF_UPZcreate_decimal)Zwhat�drrr�round_py2_compat#s


r)r)r)�sysrr�version_info�intr
�rangeZxrangerZ	text_type�bytesZbinary_typeZstring_types�chrZunichrrr
ZunicodeZ
basestringrrrrr�<module>s*


PKi�\��Z��!__pycache__/grange.cpython-36.pycnu�[���3

�b�W��@sdZddlZdd�ZdS)zDNS GENERATE range conversion.�NcCs�d}d}d}|r(|ddkr(tjjd��xj|D]b}|dkrT|dkrTt|�}d}d}q.|dkrnt|�}d}d}q.|j�r�||7}q.tjjd	|��q.W|dkr�tjj��|dkr�t|�}|dkr�t|�}|dks�t�|dks�t�||ks�t�|||fS)z�Convert the text form of a range in a GENERATE statement to an
    integer.

    @param text: the textual range
    @type text: string
    @return: The start, stop and step values.
    @rtype: tuple
    ��r�-z!Start cannot be a negative number��/�zCould not parse %s�)rr)�dnsZ	exception�SyntaxError�int�isdigit�AssertionError)�text�stepZcur�state�c�start�stop�r�/usr/lib/python3.6/grange.py�	from_texts6


r)�__doc__r	rrrrr�<module>sPKi�\�=���"__pycache__/version.cpython-36.pycnu�[���3

�b�W��@s�dZdZdZdZdZdZedkr0deeefZn,edkrJdeeeefZndeeeeefZed>ed>Bed	>Bed
>BeBZdS)z&dnspython release version information.���z%d.%d.%dz%d.%d.%dx%dz%d.%d.%d%x%d����N)�__doc__ZMAJORZMINORZMICROZRELEASELEVELZSERIAL�version�
hexversion�rr�/usr/lib/python3.6/version.py�<module>sPKi�\���!
!
&__pycache__/reversename.cpython-36.pycnu�[���3

�b�W��@sXdZddlZddlZddlZddlZddlZejjd�Z	ejjd�Z
dd�Zdd�ZdS)	aDNS Reverse Map Names.

@var ipv4_reverse_domain: The DNS IPv4 reverse-map domain, in-addr.arpa.
@type ipv4_reverse_domain: dns.name.Name object
@var ipv6_reverse_domain: The DNS IPv6 reverse-map domain, ip6.arpa.
@type ipv6_reverse_domain: dns.name.Name object
�Nz
in-addr.arpa.z	ip6.arpa.cCs�yztjj|�}tjj|�rXtjdkr<dd�|dd�D�}ndd�|dd�D�}t}n dd�ttj	|�j
��D�}t}Wn2tk
r�dd�t
tjj|��D�}t}YnX|j�tjjd	j|�|d
�S)aConvert an IPv4 or IPv6 address in textual form into a Name object whose
    value is the reverse-map domain name of the address.
    @param text: an IPv4 or IPv6 address in textual form (e.g. '127.0.0.1',
    '::1')
    @type text: str
    @rtype: dns.name.Name object
    �cSsg|]}d|�qS)z%d�)�.0�byterr�!/usr/lib/python3.6/reversename.py�
<listcomp>/sz from_address.<locals>.<listcomp>�NcSsg|]}dt|��qS)z%d)�ord)rrrrrr1scSsg|]}|�qSrr)r�xrrrr4scSsg|]}d|�qS)z%dr)rrrrrr7s�.)�origin)r)�dns�ipv6�	inet_atonZ	is_mapped�sys�version_info�ipv4_reverse_domain�str�binasciiZhexlify�decode�ipv6_reverse_domain�	Exception�	bytearray�ipv4�reverse�name�	from_text�join)�textZv6�partsrrrr�from_address#s

r cCs�|jt�rD|jt�}t|j�}|j�dj|�}tjj	tjj
|��S|jt�r�|jt�}t|j�}|j�g}d}t|�}x0||kr�|j
dj|||d���|d7}q|Wdj|�}tjj	tjj
|��Stjjd��dS)z�Convert a reverse map domain name into textual address form.
    @param name: an IPv4 or IPv6 address in reverse-map form.
    @type name: dns.name.Name object
    @rtype: str
    �.r���:z"unknown reverse-map address familyN)Zis_subdomainrZ
relativize�list�labelsrrr
rZ	inet_ntoarr�len�appendrZ	exception�SyntaxError)rr&rr�i�lrrr�
to_address>s&








r,)
�__doc__rrZdns.namer
Zdns.ipv6Zdns.ipv4rrrrr r,rrrr�<module>sPKi�\{��_��$__pycache__/set.cpython-36.opt-1.pycnu�[���3

�b�W#�@sdZGdd�de�ZdS)zA simple Set class.c@seZdZdZdgZdDdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Z d<d=�Z!d>d?�Z"d@dA�Z#dBdC�Z$dS)E�Seta'A simple set class.

    Sets are not in Python until 2.3, and rdata are not immutable so
    we cannot use sets.Set anyway.  This class implements subset of
    the 2.3 Set interface using a list as the container.

    @ivar items: A list of the items which are in the set
    @type items: list�itemsNcCs*g|_|dk	r&x|D]}|j|�qWdS)zvInitialize the set.

        @param items: the initial set of items
        @type items: any iterable or None
        N)r�add)�selfr�item�r�/usr/lib/python3.6/set.py�__init__ s
zSet.__init__cCsdt|j�S)Nzdns.simpleset.Set(%s))�reprr)rrrr�__repr__,szSet.__repr__cCs||jkr|jj|�dS)zAdd an item to the set.N)r�append)rrrrrr/s
zSet.addcCs|jj|�dS)zRemove an item from the set.N)r�remove)rrrrrr4sz
Set.removecCs*y|jj|�Wntk
r$YnXdS)z'Remove an item from the set if present.N)rr�
ValueError)rrrrr�discard8szSet.discardcCs |j}|j|�}t|j�|_|S)a�Make a (shallow) copy of the set.

        There is a 'clone protocol' that subclasses of this class
        should use.  To make a copy, first call your super's _clone()
        method, and use the object returned as the new instance.  Then
        make shallow copies of the attributes defined in the subclass.

        This protocol allows us to write the set algorithms that
        return new instances (e.g. union) once, and keep using them in
        subclasses.
        )�	__class__�__new__�listr)r�cls�objrrr�_clone?s

z
Set._clonecCs|j�S)z!Make a (shallow) copy of the set.)r)rrrr�__copy__QszSet.__copy__cCs|j�S)z!Make a (shallow) copy of the set.)r)rrrr�copyUszSet.copycCs<t|t�std��||krdSx|jD]}|j|�q&WdS)z�Update the set, adding any elements from other which are not
        already in the set.
        @param other: the collection of items with which to update the set
        @type other: Set object
        zother must be a Set instanceN)�
isinstancerr
rr)r�otherrrrr�union_updateYs
zSet.union_updatecCsLt|t�std��||krdSx(t|j�D]}||jkr*|jj|�q*WdS)z�Update the set, removing any elements from other which are not
        in both sets.
        @param other: the collection of items with which to update the set
        @type other: Set object
        zother must be a Set instanceN)rrr
rrr)rrrrrr�intersection_updatefs

zSet.intersection_updatecCs@t|t�std��||kr"g|_nx|jD]}|j|�q*WdS)z�Update the set, removing any elements from other which are in
        the set.
        @param other: the collection of items with which to update the set
        @type other: Set object
        zother must be a Set instanceN)rrr
rr)rrrrrr�difference_updatevs
zSet.difference_updatecCs|j�}|j|�|S)z�Return a new set which is the union of I{self} and I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        )rr)rrrrrr�union�s
z	Set.unioncCs|j�}|j|�|S)z�Return a new set which is the intersection of I{self} and I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        )rr)rrrrrr�intersection�s
zSet.intersectioncCs|j�}|j|�|S)z�Return a new set which I{self} - I{other}, i.e. the items
        in I{self} which are not also in I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        )rr)rrrrrr�
difference�s	
zSet.differencecCs
|j|�S)N)r)rrrrr�__or__�sz
Set.__or__cCs
|j|�S)N)r)rrrrr�__and__�szSet.__and__cCs
|j|�S)N)r)rrrrr�__add__�szSet.__add__cCs
|j|�S)N)r)rrrrr�__sub__�szSet.__sub__cCs|j|�|S)N)r)rrrrr�__ior__�s
zSet.__ior__cCs|j|�|S)N)r)rrrrr�__iand__�s
zSet.__iand__cCs|j|�|S)N)r)rrrrr�__iadd__�s
zSet.__iadd__cCs|j|�|S)N)r)rrrrr�__isub__�s
zSet.__isub__cCsx|D]}|j|�qWdS)z�Update the set, adding any elements from other which are not
        already in the set.
        @param other: the collection of items with which to update the set
        @type other: any iterable typeN)r)rrrrrr�update�s
z
Set.updatecCs
g|_dS)zMake the set empty.N)r)rrrr�clear�sz	Set.clearcCs@x|jD]}||jkrdSqWx|jD]}||jkr&dSq&WdS)NFT)r)rrrrrr�__eq__�s

z
Set.__eq__cCs|j|�S)N)r))rrrrr�__ne__�sz
Set.__ne__cCs
t|j�S)N)�lenr)rrrr�__len__�szSet.__len__cCs
t|j�S)N)�iterr)rrrr�__iter__�szSet.__iter__cCs
|j|S)N)r)r�irrr�__getitem__�szSet.__getitem__cCs|j|=dS)N)r)rr/rrr�__delitem__�szSet.__delitem__cCs4t|t�std��x|jD]}||jkrdSqWdS)z?Is I{self} a subset of I{other}?

        @rtype: bool
        zother must be a Set instanceFT)rrr
r)rrrrrr�issubset�s

zSet.issubsetcCs4t|t�std��x|jD]}||jkrdSqWdS)zAIs I{self} a superset of I{other}?

        @rtype: bool
        zother must be a Set instanceFT)rrr
r)rrrrrr�
issuperset�s

zSet.issuperset)N)%�__name__�
__module__�__qualname__�__doc__�	__slots__rr
rrrrrrrrrrrrrr r!r"r#r$r%r&r'r(r)r*r,r.r0r1r2r3rrrrrsD	



rN)r7�objectrrrrr�<module>sPKi�\]��)zz __pycache__/flags.cpython-36.pycnu�[���3

�b�Wh
�@s�dZdZdZdZdZdZdZdZdZeeeeeeed�Z	d	eiZ
ed
d�e	j�D��Z
edd�e
j�D��Zd
d�Zee
�Zee�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�ZdS)zDNS Message Flags.i�ii��� �)�QR�AA�TC�RD�RA�AD�CD�DOccs|]\}}||fVqdS)N�)�.0�x�yr
r
�/usr/lib/python3.6/flags.py�	<genexpr>3srccs|]\}}||fVqdS)Nr
)rrrr
r
rr5scCs t|j��}|j�|j�|S)N)�list�items�sort�reverse)�table�orderr
r
r�_order_flags8srcCs.d}|j�}x|D]}|||j�B}qW|S)N�)�split�upper)�textr�flags�tokens�tr
r
r�
_from_textCs

r!cCs6g}x&|D]\}}||@dkr
|j|�q
Wdj|�S)Nr� )�append�join)rrrZ
text_flags�k�vr
r
r�_to_textKs
r'cCs
t|t�S)zZConvert a space-separated list of flag text values into a flags
    value.
    @rtype: int)r!�_by_text)rr
r
r�	from_textSsr)cCst|tt�S)z]Convert a flags value into a space-separated list of flag text
    values.
    @rtype: string)r'�	_by_value�_flags_order)rr
r
r�to_text[sr,cCs
t|t�S)zdConvert a space-separated list of EDNS flag text values into a EDNS
    flags value.
    @rtype: int)r!�
_edns_by_text)rr
r
r�edns_from_textcsr.cCst|tt�S)zhConvert an EDNS flags value into a space-separated list of EDNS flag
    text values.
    @rtype: string)r'�_edns_by_value�_edns_flags_order)rr
r
r�edns_to_textksr1N)�__doc__rrrrr	r
rrr(r-�dictrr*r/rr+r0r!r'r)r,r.r1r
r
r
r�<module>s6PKi�\5�
nn(__pycache__/message.cpython-36.opt-1.pycnu�[���3

�@�Wy��
@s�dZddlmZddlmZddlZddlZddlZddl	Zddl
ZddlZddlZddl
ZddlZddlZddlZddlZddlZddlZddlZddlZddlmZmZmZGdd�dejj�ZGd	d
�d
ejj�ZGdd�dejj�ZGd
d�dejj�Z Gdd�dejj�Z!Gdd�dejj�Z"Gdd�de#�Z$Gdd�de#�Z%d(dd�Z&Gdd�de#�Z'dd�Z(d d!�Z)ej*j+ddddddfd"d#�Z,d)d&d'�Z-dS)*zDNS Messages�)�absolute_import)�StringION�)�long�xrange�string_typesc@seZdZdZdS)�ShortHeaderz2The DNS packet passed to from_wire() is too short.N)�__name__�
__module__�__qualname__�__doc__�r
r
�/usr/lib/python3.6/message.pyr*src@seZdZdZdS)�TrailingJunkzEThe DNS packet passed to from_wire() has extra junk at the end of it.N)r	r
rrr
r
r
rr/src@seZdZdZdS)�UnknownHeaderFieldzVThe header field name was not recognized when converting from text
    into a message.N)r	r
rrr
r
r
rr4src@seZdZdZdS)�BadEDNSzVOPT record occurred somewhere other than the start of
    the additional data section.N)r	r
rrr
r
r
rr:src@seZdZdZdS)�BadTSIGzWA TSIG record occurred somewhere other than the end of
    the additional data section.N)r	r
rrr
r
r
rr@src@seZdZdZdS)�UnknownTSIGKeyz(A TSIG with an unknown key was received.N)r	r
rrr
r
r
rrFsrc@s�eZdZdZd-dd�Zdd�Zdd�Zd.d
d�Zdd
�Zdd�Z	dd�Z
dd�Zej
jdddfdd�Zej
jdddfdd�Zd/dd�Zdddddejjfdd�Zd0d!d"�Zd1d#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�ZdS)2�Messagea,
A DNS message.

    @ivar id: The query id; the default is a randomly chosen id.
    @type id: int
    @ivar flags: The DNS flags of the message.  @see: RFC 1035 for an
    explanation of these flags.
    @type flags: int
    @ivar question: The question section.
    @type question: list of dns.rrset.RRset objects
    @ivar answer: The answer section.
    @type answer: list of dns.rrset.RRset objects
    @ivar authority: The authority section.
    @type authority: list of dns.rrset.RRset objects
    @ivar additional: The additional data section.
    @type additional: list of dns.rrset.RRset objects
    @ivar edns: The EDNS level to use.  The default is -1, no Edns.
    @type edns: int
    @ivar ednsflags: The EDNS flags
    @type ednsflags: long
    @ivar payload: The EDNS payload size.  The default is 0.
    @type payload: int
    @ivar options: The EDNS options
    @type options: list of dns.edns.Option objects
    @ivar request_payload: The associated request's EDNS payload size.
    @type request_payload: int
    @ivar keyring: The TSIG keyring to use.  The default is None.
    @type keyring: dict
    @ivar keyname: The TSIG keyname to use.  The default is None.
    @type keyname: dns.name.Name object
    @ivar keyalgorithm: The TSIG algorithm to use; defaults to
    dns.tsig.default_algorithm.  Constants for TSIG algorithms are defined
    in dns.tsig, and the currently implemented algorithms are
    HMAC_MD5, HMAC_SHA1, HMAC_SHA224, HMAC_SHA256, HMAC_SHA384, and
    HMAC_SHA512.
    @type keyalgorithm: string
    @ivar request_mac: The TSIG MAC of the request message associated with
    this message; used when validating TSIG signatures.   @see: RFC 2845 for
    more information on TSIG fields.
    @type request_mac: string
    @ivar fudge: TSIG time fudge; default is 300 seconds.
    @type fudge: int
    @ivar original_id: TSIG original id; defaults to the message's id
    @type original_id: int
    @ivar tsig_error: TSIG error code; default is 0.
    @type tsig_error: int
    @ivar other_data: TSIG other data.
    @type other_data: string
    @ivar mac: The TSIG MAC for this message.
    @type mac: string
    @ivar xfr: Is the message being used to contain the results of a DNS
    zone transfer?  The default is False.
    @type xfr: bool
    @ivar origin: The origin of the zone in messages which are used for
    zone transfers or for DNS dynamic updates.  The default is None.
    @type origin: dns.name.Name object
    @ivar tsig_ctx: The TSIG signature context associated with this
    message.  The default is None.
    @type tsig_ctx: hmac.HMAC object
    @ivar had_tsig: Did the message decoded from wire format have a TSIG
    signature?
    @type had_tsig: bool
    @ivar multi: Is this message part of a multi-message sequence?  The
    default is false.  This variable is used when validating TSIG signatures
    on messages which are part of a zone transfer.
    @type multi: bool
    @ivar first: Is this message standalone, or the first of a multi
    message sequence?  This variable is used when validating TSIG signatures
    on messages which are part of a zone transfer.
    @type first: bool
    @ivar index: An index of rrsets in the message.  The index key is
    (section, name, rdclass, rdtype, covers, deleting).  Indexing can be
    disabled by setting the index to None.
    @type index: dict
    NcCs�|dkrtjj�|_n||_d|_g|_g|_g|_g|_d|_	d|_
d|_g|_d|_
d|_d|_tjj|_d|_d|_d|_d|_|j|_d|_d|_d|_d|_d|_d|_d|_i|_dS)Nrr�i,FT���) �dnsZentropyZ	random_16�id�flags�question�answer�	authority�
additional�edns�	ednsflags�payload�options�request_payload�keyring�keyname�tsig�default_algorithm�keyalgorithm�request_mac�
other_data�
tsig_error�fudge�original_id�mac�xfr�origin�tsig_ctx�had_tsig�multi�first�index)�selfrr
r
r�__init__�s:
zMessage.__init__cCsdt|j�dS)Nz<DNS message, ID �>)�reprr)r5r
r
r�__repr__�szMessage.__repr__cCs|j�S)N)�to_text)r5r
r
r�__str__�szMessage.__str__TcKst�}|jd|j�|jdtjjtjj|j���tjj|j|j	�}|jdtjj|��|jdtjj|j��|j
dkr�|jd|j
�|j	dkr�|jdtjj|j	��|jd|j�tjj
|j�}|r�|jd	�n
|jd
�x.|jD]$}|j|j||f|��|jd�q�W|�r,|jd�n
|jd
�x0|jD]&}|j|j||f|��|jd��q>W|�rz|jd�n
|jd�x0|jD]&}|j|j||f|��|jd��q�W|jd�x0|jD]&}|j|j||f|��|jd��q�W|j�dd�S)z�Convert the message to text.

        The I{origin}, I{relativize}, and any other keyword
        arguments are passed to the rrset to_wire() method.

        @rtype: string
        zid %d
z
opcode %s
z	rcode %s
z	flags %s
rzedns %s
z
eflags %s
zpayload %d
z;ZONE
z
;QUESTION
�
z;PREREQ
z;ANSWER
z;UPDATE
z;AUTHORITY
z;ADDITIONAL
Nrr)r�writerr�opcoder:�
from_flagsr�rcoderrZedns_to_textr �	is_updaterrrr�getvalue)r5r/�
relativize�kw�sZrcrA�rrsetr
r
rr:�sJ	





zMessage.to_textcCs�t|t�sdS|j|jkrdS|j|jkr.dSx|jD]}||jkr6dSq6Wx|jD]}||jkrTdSqTWx|jD]}||jkrrdSqrWx|jD]}||jkr�dSq�Wx|jD]}||jkr�dSq�Wx|jD]}||jkr�dSq�WdS)z�Two messages are equal if they have the same content in the
        header, question, answer, and authority sections.
        @rtype: boolFT)�
isinstancerrrrrr)r5�other�nr
r
r�__eq__�s2






zMessage.__eq__cCs|j|�S)z0Are two messages not equal?
        @rtype: bool)rJ)r5rHr
r
r�__ne__szMessage.__ne__cCs�|jtjj@dks:|j|jks:tjj|j�tjj|j�kr>dStjj|j|j�tjjkr\dStjj	|j�rndSx|j
D]}||j
krvdSqvWx|j
D]}||j
kr�dSq�WdS)z1Is other a response to self?
        @rtype: boolrFT)rr�QRrr>r?r@rZNOERRORrAr)r5rHrIr
r
r�is_responses"


zMessage.is_responsecCsD||jkrdS||jkrdS||jkr*dS||jkr8dStd��dS)Nrr��zunknown section)rrrr�
ValueError)r5�sectionr
r
r�section_number-s



zMessage.section_numberFc	Cs�|j|�|||||f}	|sb|jdk	r>|jj|	�}
|
dk	rb|
Sn$x"|D]}
|
j|||||�rD|
SqDW|sjt�tjj|||||�}
|j|
�|jdk	r�|
|j|	<|
S)aFind the RRset with the given attributes in the specified section.

        @param section: the section of the message to look in, e.g.
        self.answer.
        @type section: list of dns.rrset.RRset objects
        @param name: the name of the RRset
        @type name: dns.name.Name object
        @param rdclass: the class of the RRset
        @type rdclass: int
        @param rdtype: the type of the RRset
        @type rdtype: int
        @param covers: the covers value of the RRset
        @type covers: int
        @param deleting: the deleting value of the RRset
        @type deleting: int
        @param create: If True, create the RRset if it is not found.
        The created RRset is appended to I{section}.
        @type create: bool
        @param force_unique: If True and create is also True, create a
        new RRset regardless of whether a matching RRset exists already.
        @type force_unique: bool
        @raises KeyError: the RRset was not found and create was False
        @rtype: dns.rrset.RRset objectN)	rRr4�get�match�KeyErrorrrFZRRset�append)r5rQ�name�rdclass�rdtype�covers�deleting�create�force_unique�keyrFr
r
r�
find_rrset9s"




zMessage.find_rrsetc	
Cs:y|j||||||||�}	Wntk
r4d}	YnX|	S)aGet the RRset with the given attributes in the specified section.

        If the RRset is not found, None is returned.

        @param section: the section of the message to look in, e.g.
        self.answer.
        @type section: list of dns.rrset.RRset objects
        @param name: the name of the RRset
        @type name: dns.name.Name object
        @param rdclass: the class of the RRset
        @type rdclass: int
        @param rdtype: the type of the RRset
        @type rdtype: int
        @param covers: the covers value of the RRset
        @type covers: int
        @param deleting: the deleting value of the RRset
        @type deleting: int
        @param create: If True, create the RRset if it is not found.
        The created RRset is appended to I{section}.
        @type create: bool
        @param force_unique: If True and create is also True, create a
        new RRset regardless of whether a matching RRset exists already.
        @type force_unique: bool
        @rtype: dns.rrset.RRset object or NoneN)r_rU)
r5rQrWrXrYrZr[r\r]rFr
r
r�	get_rrsetgs
zMessage.get_rrsetrc	KsR|dkr|jdkr|j}nd}|dkr,d}n|dkr8d}tjj|j|j||�}x"|jD]}|j|j|j	|j
�qVWx"|jD]}|jtjj
|f|�qzWx"|jD]}|jtjj|f|�q�W|jdkr�|j|j|j|j|j�x"|jD]}|jtjj|f|�q�W|j�|jdk	�rJ|j|j|j|j|j|j|j|j|j|j �|j!|_!|j"�S)a7Return a string containing the message in DNS compressed wire
        format.

        Additional keyword arguments are passed to the rrset to_wire()
        method.

        @param origin: The origin to be appended to any relative names.
        @type origin: dns.name.Name object
        @param max_size: The maximum size of the wire format output; default
        is 0, which means 'the message's request payload, if nonzero, or
        65536'.
        @type max_size: int
        @raises dns.exception.TooBig: max_size was exceeded
        @rtype: string
        ri��iN)#r"rZrendererZRendererrrrZadd_questionrWrYrXrZ	add_rrset�ANSWERr�	AUTHORITYrZadd_ednsrr r!r�
ADDITIONALZwrite_headerr$Zadd_tsigr#r+r,r*r)r(r'r-Zget_wire)r5r/Zmax_sizerD�rrFr
r
r�to_wire�s6

zMessage.to_wirei,rcCst||_|dkr$t|jj��d|_nt|t�r:tjj|�}||_||_	||_
|dkr^|j|_n||_||_
||_dS)awWhen sending, a TSIG signature using the specified keyring
        and keyname should be added.

        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @type keyname: dns.name.Name or string
        @param fudge: TSIG time fudge; default is 300 seconds.
        @type fudge: int
        @param original_id: TSIG original id; defaults to the message's id
        @type original_id: int
        @param tsig_error: TSIG error code; default is 0.
        @type tsig_error: int
        @param other_data: TSIG other data.
        @type other_data: string
        @param algorithm: The TSIG algorithm to use; defaults to
        dns.tsig.default_algorithm
        Nr)r#�list�keysr$rGrrrW�	from_textr'r+rr,r*r))r5r#r$r+r,r*r)�	algorithmr
r
r�use_tsig�s

zMessage.use_tsig�cCs�|dks|dkrd}|dkr d}|dkr,|}|dkrFd}d}d}g}n$|td�M}||d>O}|dkrjg}||_||_||_||_||_dS)	a_Configure EDNS behavior.
        @param edns: The EDNS level to use.  Specifying None, False, or -1
        means 'do not use EDNS', and in this case the other parameters are
        ignored.  Specifying True is equivalent to specifying 0, i.e. 'use
        EDNS0'.
        @type edns: int or bool or None
        @param ednsflags: EDNS flag values.
        @type ednsflags: int
        @param payload: The EDNS sender's payload field, which is the maximum
        size of UDP datagram the sender can handle.
        @type payload: int
        @param request_payload: The EDNS payload size to use when sending
        this message.  If not specified, defaults to the value of payload.
        @type request_payload: int or None
        @param options: The EDNS options
        @type options: None or list of dns.edns.Option objects
        @see: RFC 2671
        NFrTrl�~�r)rrrr r!r")r5rrr r"r!r
r
r�use_edns�s(zMessage.use_ednscCsL|r*|jdkr|j�|jtjjO_n|jdkrH|jtjjM_dS)a
Enable or disable 'DNSSEC desired' flag in requests.
        @param wanted: Is DNSSEC desired?  If True, EDNS is enabled if
        required, and then the DO bit is set.  If False, the DO bit is
        cleared if EDNS is enabled.
        @type wanted: bool
        rN)rrmrrrZDO)r5Zwantedr
r
r�want_dnssecs

zMessage.want_dnsseccCstjj|j|j�S)z.Return the rcode.
        @rtype: int
        )rr@r?rr)r5r
r
rr@sz
Message.rcodecCsjtjj|�\}}|jdM_|j|O_|jtd�M_|j|O_|jdkrf|jdkrfd|_dS)zPSet the rcode.
        @param rcode: the rcode
        @type rcode: int
        i�i���rN)rr@�to_flagsrrrr)r5r@�valueZevaluer
r
r�	set_rcode"szMessage.set_rcodecCstjj|j�S)z/Return the opcode.
        @rtype: int
        )rr>r?r)r5r
r
rr>/szMessage.opcodecCs(|jdM_|jtjj|�O_dS)zTSet the opcode.
        @param opcode: the opcode
        @type opcode: int
        i��N)rrr>ro)r5r>r
r
r�
set_opcode5szMessage.set_opcode)N)NT)Nr)rrrkNN)T)r	r
rrr6r9r;r:rJrKrMrRr�	rdatatype�NONEr_r`rer%r&rjrmrnr@rqr>rrr
r
r
rrKs0K
 
7
-
!
.)
*

rc@s2eZdZdZddd�Zdd�Zdd�Zd	d
�ZdS)
�_WireReadera�Wire format reader.

    @ivar wire: the wire-format message.
    @type wire: string
    @ivar message: The message object being built
    @type message: dns.message.Message object
    @ivar current: When building a message object from wire format, this
    variable contains the offset from the beginning of wire of the next octet
    to be read.
    @type current: int
    @ivar updating: Is the message a dynamic update?
    @type updating: bool
    @ivar one_rr_per_rrset: Put each RR into its own RRset?
    @type one_rr_per_rrset: bool
    @ivar ignore_trailing: Ignore trailing junk at end of request?
    @type ignore_trailing: bool
    @ivar zone_rdclass: The class of the zone in messages which are
    DNS dynamic updates.
    @type zone_rdclass: int
    FcCs@tjj|�|_||_d|_d|_tjj|_	||_
||_||_dS)NrF)
rZwiredataZ
maybe_wrap�wire�message�current�updating�
rdataclass�IN�zone_rdclass�
question_only�one_rr_per_rrset�ignore_trailing)r5rvrwr}r~rr
r
rr6Us
z_WireReader.__init__c	Cs�|jr|dkrtjj�x�td|�D]�}tjj|j|j�\}}|j	j
dk	rV|j|j	j
�}|j||_tj
d|j|j|jd��\}}|jd|_|j	j|j	j|||ddd�|jr"||_q"WdS)z�Read the next I{qcount} records from the wire data and add them to
        the question section.
        @param qcount: the number of questions in the message
        @type qcount: intrrNz!HH�T)r\r])ryr�	exception�	FormErrorrrW�	from_wirervrxrwr/rC�struct�unpackr_rr|)r5�qcount�i�qname�usedrYrXr
r
r�
_get_question`sz_WireReader._get_questionc
CsH|js|jrd}nd}d}�x&td|�D�]}|j}tjj|j|j�\}}|}	|jj	dk	rh|j
|jj	�}|j||_tjd|j|j|jd��\}
}}}
|jd|_|
tj
jk�rn||jjk	s�|r�t�||j_||j_|d@d?|j_g|j_|j}|
}xj|dk�rdtjd	|j||d
��\}}|d
}tjj||j||�}|jjj|�||}|d
|}q�Wd}�n�|
tj
jk�rH||jjk�o�||dk�s�t�|jjdk�r�td��|jjj|	�}|dk�r�td
|��|	|j_tjj|j|j|
�\|j_|j_ tjj!|j|	|t"t#j#��|jj$||j|
|jj%|jj&|jj'�|j_%d|j_(n�|dk�rVd}|j�r�|tj)j*k�sz|tj)j+k�r�|}|j,}nd}|tj)j*k�s�|tj)j+k�r�||jj-k�r�tj
j+}d}n&tj.j||
|j|j|
|jj	�}|j/�}|jj0�r|
tj
j1k�rd}|jj2||||
||d|�}|dk	�r4|j3||�|j|
|_q(WdS)a/Read the next I{count} records from the wire data and add them to
        the specified section.
        @param section: the section of the message to which to add records
        @type section: list of dns.rrset.RRset objects
        @param count: the number of records to read
        @type count: intTFrNz!HHIH�
i�rlz!HHr�rz"got signed message without keyringzkey '%s' unknown)4ryr~rrxrrWr�rvrwr/rCr�r�rs�OPTrrr rrr!Zoption_from_wirerVZTSIGrr#rrSr$r%Zget_algorithm_and_macr'r-Zvalidate�int�timer(r0r2r3r1rz�ANYrtr|r�rdatarZr.ZSOAr_�add)r5rQ�countr]Zseen_optr�Zrr_startrWr�Z
absolute_namerYrX�ttlZrdlenrxZoptslenZotypeZolen�optZsecretr[rZ�rdrFr
r
r�_get_sectionxs� 








z_WireReader._get_sectioncCs�t|j�}|dkrt�tjd|jdd��\|j_|j_}}}}d|_t	j
j|jj�r\d|_|j
|�|jrpdS|j|jj|�|j|jj|�|j|jj|�|jr�|j|kr�t�|jjr�|jjr�|jjr�|jjj|j�dS)zNRead a wire format DNS message and build a dns.message.Message
        object.�z!HHHHHHNT)�lenrvrr�r�rwrrrxrr>rAryr�r}r�rrrrrr2r0r1�update)r5�lr�ZancountZaucountZadcountr
r
r�read�s$
*

z_WireReader.readN)FFF)r	r
rrr6r�r�r�r
r
r
rru>s

crurFTc
CsPtdd�}||_||_||_||_||_||_||_t||||	|
�}|j	�|S)a)Convert a DNS wire format message into a message
    object.

    @param keyring: The keyring to use if the message is signed.
    @type keyring: dict
    @param request_mac: If the message is a response to a TSIG-signed request,
    I{request_mac} should be set to the MAC of that request.
    @type request_mac: string
    @param xfr: Is this message part of a zone transfer?
    @type xfr: bool
    @param origin: If the message is part of a zone transfer, I{origin}
    should be the origin name of the zone.
    @type origin: dns.name.Name object
    @param tsig_ctx: The ongoing TSIG context, used when validating zone
    transfers.
    @type tsig_ctx: hmac.HMAC object
    @param multi: Is this message part of a multiple message sequence?
    @type multi: bool
    @param first: Is this message standalone, or the first of a multi
    message sequence?
    @type first: bool
    @param question_only: Read only up to the end of the question section?
    @type question_only: bool
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    @param ignore_trailing: Ignore trailing junk at end of request?
    @type ignore_trailing: bool
    @raises ShortHeader: The message is less than 12 octets long.
    @raises TrailingJunk: There were octets in the message past the end
    of the proper DNS message.
    @raises BadEDNS: An OPT record was in the wrong section, or occurred more
    than once.
    @raises BadTSIG: A TSIG record was not the last record of the additional
    data section.
    @rtype: dns.message.Message objectr)r)
rr#r(r.r/r0r2r3rur�)
rvr#r(r.r/r0r2r3r}r~r�m�readerr
r
rr��s(

r�c@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�_TextReaderaText format reader.

    @ivar tok: the tokenizer
    @type tok: dns.tokenizer.Tokenizer object
    @ivar message: The message object being built
    @type message: dns.message.Message object
    @ivar updating: Is the message a dynamic update?
    @type updating: bool
    @ivar zone_rdclass: The class of the zone in messages which are
    DNS dynamic updates.
    @type zone_rdclass: int
    @ivar last_name: The most recently read name when building a message object
    from text format.
    @type last_name: dns.name.Name object
    cCs.||_tjj|�|_d|_tjj|_d|_	dS)NF)
rwrZ	tokenizer�	Tokenizer�tok�	last_namerzr{r|ry)r5�textrwr
r
rr6>s

z_TextReader.__init__cCs�|jj�}|j}|dkr*|jj�|j_�n�|dkr�x>|jj�}|j�sT|jj|�P|jjt	jj
|j�B|j_q4Wt	jj|jj�r�d|_
�n&|dkr�|jj�|j_|jj|jjd>B|j_n�|dk�r|jjdkr�d|j_x�|jj�}|j��s�|jj|�P|jjt	jj|j�B|j_q�Wn�|dk�rN|jj�|j_|jjdk�r�d|j_nd|d	k�r�|jj�}|jjt	jjt	jj
|��B|j_n.|d
k�r�|jj�}|jjt	jj
|��nt�|jj�dS)z5Process one line from the text format header section.rrTrrlZeflagsrr r>r@N)r�rSrpZget_intrwr�
is_identifier�ungetrrrhr>rAryrrZedns_from_textr Z
get_stringrorqr@r�get_eol)r5rQ�tokenZwhatr�r
r
r�_header_lineEsR











z_TextReader._header_linecCs�|jjdd�}|j�s(tjj|jd�|_|j}|jj�}|j�sHtj	j
�y,tjj|j�}|jj�}|j�srtj	j
�Wn:tj	j
k
r�tj	j
�Yntk
r�tjj
}YnXtjj|j�}|jj|jj|||ddd�|jr�||_|jj�dS)z7Process one line from the text format question section.T)�want_leadingN)r\r])r�rS�
is_whitespacerrWrhrpr�r�r��SyntaxErrorrz�	Exceptionr{rsrwr_rryr|r�)r5rQr�rWrXrYr
r
r�_question_liness.

z_TextReader._question_linecCs�d}|jjdd�}|j�s,tjj|jd�|_|j}|jj�}|j�sLtj	j
�y*t|jd�}|jj�}|j�sttj	j
�Wn6tj	j
k
r�tj	j
�Yntk
r�d}YnXyPtj
j|j�}|jj�}|j�s�tj	j
�|tj
jks�|tj
jk�r�|}|j}Wn>tj	j
k
�r tj	j
�Yntk
�r<tj
j}YnXtjj|j�}|jj�}|j��s�|jj|�tjj|||jd�}|j�}	nd}tjj}	|jj|||||	|d|j�}
|dk	�r�|
j||�dS)zfProcess one line from the text format answer, authority, or
        additional data sections.
        NT)r�r)r�rSr�rrWrhrpr�r�r�r�r�r�rzr�rtr|r{rs�
is_eol_or_eofr�r�rZrwr_ryr�)r5rQr[r�rWr�rXrYr�rZrFr
r
r�_rr_line�sT









z_TextReader._rr_linecCs�|j}d}x�|jjdd�}|j�r$P|j�r�|jj�}|dkrF|j}nv|dksV|dkrf|j}|jj	}nV|dksv|dkr�|j
}|jj}n6|dks�|d	kr�|j
}|jj}n|d
kr�|j
}|jj
}|jj�q|jj|�||�qWdS)zNRead a text format DNS message and build a dns.message.Message
        object.NTZHEADERZQUESTIONZZONEraZPREREQrbZUPDATErc)r�r�rSr�Z
is_commentrp�upperr�rwrr�rrrr�r�)r5Zline_methodrQr��ur
r
rr��s4




z_TextReader.readN)	r	r
rrr6r�r�r�r�r
r
r
rr�,s.5r�cCst�}t||�}|j�|S)z�Convert the text format message into a message object.

    @param text: The text format message.
    @type text: string
    @raises UnknownHeaderField:
    @raises dns.exception.SyntaxError:
    @rtype: dns.message.Message object)rr�r�)r�r�r�r
r
rrh�s

rhc
CsFt}d}t||�r"t||�}d}nd}zt|�}Wd|r@|j�X|S)aRead the next text format message from the specified file.

    @param f: file or string.  If I{f} is a string, it is treated
    as the name of a file to open.
    @raises UnknownHeaderField:
    @raises dns.exception.SyntaxError:
    @rtype: dns.message.Message objectZrUTFN)rrG�openrh�close)�fZstr_typeZoptsZ
want_closer�r
r
r�	from_file�s	


r�c	Cst|t�rtjj|�}t|t�r,tjj|�}t|t�rBtjj|�}t�}	|	jtjj	O_|	j
|	j|||ddd�i}
|dk	r�||
d<|dkr�d}|dk	r�||
d<|dkr�d}|dk	r�||
d<|dkr�d}|dk	r�||
d<|dkr�d}||
d	<|	jf|
�|	j
|�|	S)
aVMake a query message.

    The query name, type, and class may all be specified either
    as objects of the appropriate type, or as strings.

    The query will have a randomly chosen query id, and its DNS flags
    will be set to dns.flags.RD.

    @param qname: The query name.
    @type qname: dns.name.Name object or string
    @param rdtype: The desired rdata type.
    @type rdtype: int
    @param rdclass: The desired rdata class; the default is class IN.
    @type rdclass: int
    @param use_edns: The EDNS level to use; the default is None (no EDNS).
    See the description of dns.message.Message.use_edns() for the possible
    values for use_edns and their meanings.
    @type use_edns: int or bool or None
    @param want_dnssec: Should the query indicate that DNSSEC is desired?
    @type want_dnssec: bool
    @param ednsflags: EDNS flag values.
    @type ednsflags: int
    @param payload: The EDNS sender's payload field, which is the maximum
    size of UDP datagram the sender can handle.
    @type payload: int
    @param request_payload: The EDNS payload size to use when sending
    this message.  If not specified, defaults to the value of payload.
    @type request_payload: int or None
    @param options: The EDNS options
    @type options: None or list of dns.edns.Option objects
    @see: RFC 2671
    @rtype: dns.message.Message objectT)r\r]Nrrr r"r!r)rGrrrWrhrsrzrr�RDr_rrmrn)r�rYrXrmrnrr r"r!r��kwargsr
r
r�
make_querys>$



r�� �,cCs�|jtjj@rtjjd��tjj|j�}tjj|jtjj@B|_|rV|jtjj	O_|j
|j��t|j
�|_
|jdkr�|jdd||j�|jr�|j|j|j|ddd|j�|j|_|S)aMake a message which is a response for the specified query.
    The message returned is really a response skeleton; it has all
    of the infrastructure required of a response, but none of the
    content.

    The response's question section is a shallow copy of the query's
    question section, so the query's question RRsets should not be
    changed.

    @param query: the query to respond to
    @type query: dns.message.Message object
    @param recursion_available: should RA be set in the response?
    @type recursion_available: bool
    @param our_payload: payload size to advertise in EDNS responses; default
    is 8192.
    @type our_payload: int
    @param fudge: TSIG time fudge; default is 300 seconds.
    @type fudge: int
    @rtype: dns.message.Message objectz&specified query message is not a queryrNr)rrrLr�r�rwrrr�ZRArrr>rfrrrmr r1rjr#r$r'r-r()ZqueryZrecursion_availableZour_payloadr+Zresponser
r
r�
make_response\s
r�)
NrFNNFTFFF)Fr�r�).rZ
__future__r�iorr�r�Zdns.ednsrZ
dns.exceptionZ	dns.flagsZdns.nameZ
dns.opcodeZdns.entropyZ	dns.rcodeZ	dns.rdataZdns.rdataclassZ
dns.rdatatypeZ	dns.rrsetZdns.rendererZdns.tsigZdns.wiredataZ_compatrrrr�r�rrZDNSExceptionrrrr�objectrrur�r�rhr�rzr{r�r�r
r
r
r�<module>sXv7
5:FPKi�\���"		__pycache__/inet.cpython-36.pycnu�[���3

�b�W��@sjdZddlZddlZddlZejZy
ejZWnek
rDdZYnXdd�Zdd�Z	dd	�Z
d
d�ZdS)z*Generic Internet address helper functions.�Ni'cCs0|tkrtjj|�S|tkr(tjj|�St�dS)a*Convert the textual form of a network address into its binary form.

    @param family: the address family
    @type family: int
    @param text: the textual address
    @type text: string
    @raises NotImplementedError: the address family specified is not
    implemented.
    @rtype: string
    N)�AF_INET�dns�ipv4�	inet_aton�AF_INET6�ipv6�NotImplementedError)�family�text�r�/usr/lib/python3.6/inet.py�	inet_pton&s
r
cCs0|tkrtjj|�S|tkr(tjj|�St�dS)a/Convert the binary form of a network address into its textual form.

    @param family: the address family
    @type family: int
    @param address: the binary address
    @type address: string
    @raises NotImplementedError: the address family specified is not
    implemented.
    @rtype: string
    N)rrrZ	inet_ntoarrr)r	Zaddressrrr�	inet_ntop:s
rcCsLytjj|�tStk
rFytjj|�tSt�YnXYnXdS)z�Determine the address family of a textual-form network address.

    @param text: the textual address
    @type text: string
    @raises ValueError: the address family cannot be determined from the input.
    @rtype: int
    N)rrrr�	Exceptionrr�
ValueError)r
rrr�af_for_addressMsrcCsty$ttjj|�d�}|dko$|dkStk
rnyttjj|�d�}|dkStk
rht�YnXYnXdS)z�Is the textual-form network address a multicast address?

    @param text: the textual address
    @raises ValueError: the address family cannot be determined from the input.
    @rtype: bool
    r�����N)�ordrrrrrr)r
�firstrrr�is_multicast`sr)�__doc__ZsocketZdns.ipv4rZdns.ipv6rr�AttributeErrorr
rrrrrrr�<module>s

PKi�\�drNN%__pycache__/ipv4.cpython-36.opt-1.pycnu�[���3

�b�W��@s4dZddlZddlZddlmZdd�Zdd�ZdS)	zIPv4 helper functions.�N�)�binary_typecCsJt|�dkrtjj�t|t�s&t|�}d|d|d|d|dfj�S)z�Convert an IPv4 address in network form to text form.

    @param address: The IPv4 address
    @type address: string
    @returns: string
    �z%u.%u.%u.%urr��)�len�dns�	exception�SyntaxError�
isinstance�	bytearray�encode)Zaddress�r�/usr/lib/python3.6/ipv4.py�	inet_ntoas
rc	Cs�t|t�s|j�}|jd�}t|�dkr0tjj�x<|D]4}|j�sJtjj�t|�dkr6|ddkr6tjj�q6Wydd�|D�}t	j
d
|��Stjj�YnXd	S)z�Convert an IPv4 address in text form to network form.

    @param text: The IPv4 address
    @type text: string
    @returns: string
    �.rrr�0cSsg|]}t|��qSr)�int)�.0�partrrr�
<listcomp>8szinet_aton.<locals>.<listcomp>�BBBBN)r)rrr
�splitrrr	r
�isdigit�struct�pack)�text�partsr�bytesrrr�	inet_aton%s


r)�__doc__rZ
dns.exceptionrZ_compatrrrrrrr�<module>s
PKi�\���	�	+__pycache__/rdataclass.cpython-36.opt-1.pycnu�[���3

�b�W��@s�dZddlZddlZdZdZdZdZdZdZ	eeeeee	d�Z
ed	d
�e
j�D��Z
e
jeeed��ede	diZejd
ej�ZGdd�dejj�Zdd�Zdd�Zdd�ZdS)akDNS Rdata Classes.

@var _by_text: The rdata class textual name to value mapping
@type _by_text: dict
@var _by_value: The rdata class value to textual name mapping
@type _by_value: dict
@var _metaclasses: If an rdataclass is a metaclass, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _metaclasses: dict�N�����)�	RESERVED0�IN�CH�HS�NONE�ANYccs|]\}}||fVqdS)N�)�.0�x�yr
r
� /usr/lib/python3.6/rdataclass.py�	<genexpr>2sr)ZINTERNETZCHAOSZHESIODTzCLASS([0-9]+)$c@seZdZdZdS)�UnknownRdataclasszA DNS class is unknown.N)�__name__�
__module__�__qualname__�__doc__r
r
r
rrEsrcCsVtj|j��}|dkrRtj|�}|dkr,t�t|jd��}|dksJ|dkrRtd��|S)z�Convert text into a DNS rdata class value.
    @param text: the text
    @type text: string
    @rtype: int
    @raises dns.rdataclass.UnknownRdataclass: the class is unknown
    @raises ValueError: the rdata class value is not >= 0 and <= 65535
    Nrri��z'class must be between >= 0 and <= 65535)	�_by_text�get�upper�_unknown_class_pattern�matchr�int�group�
ValueError)�text�valuerr
r
r�	from_textJs	
r"cCs:|dks|dkrtd��tj|�}|dkr6dt|�}|S)z�Convert a DNS rdata class to text.
    @param value: the rdata class value
    @type value: int
    @rtype: string
    @raises ValueError: the rdata class value is not >= 0 and <= 65535
    ri��z'class must be between >= 0 and <= 65535NZCLASS)r�	_by_valuer�repr)r!r r
r
r�to_text^s
r%cCs|tkrdSdS)zmTrue if the class is a metaclass.
    @param rdclass: the rdata class
    @type rdclass: int
    @rtype: boolTF)�_metaclasses)Zrdclassr
r
r�is_metaclassnsr')r�reZ
dns.exceptionZdnsrrr	r
rrr�dict�itemsr#�updater&�compile�IrZ	exceptionZDNSExceptionrr"r%r'r
r
r
r�<module>s4
PKi�\-^�L��%__pycache__/hash.cpython-36.opt-1.pycnu�[���3

�b�WL�@sXdZddlZiZejed<ejed<ejed<ejed<ejed<ejed<d	d
�Z	dS)z'Hashing backwards compatibility wrapper�NZMD5ZSHA1ZSHA224ZSHA256ZSHA384ZSHA512cCst|j�S)N)�hashes�upper)�	algorithm�r�/usr/lib/python3.6/hash.py�getsr)
�__doc__ZhashlibrZmd5Zsha1Zsha224Zsha256Zsha384Zsha512rrrrr�<module>s





PKi�\i?N%N%#__pycache__/rdataset.cpython-36.pycnu�[���3

�b�W$-�@s�dZddlZddlmZddlZddlZddlZddlZddl	Zddl
ZddlmZej
jZGdd�dejj�ZGdd	�d	ejj�ZGd
d�dej
j�Zdd
�Zdd�Zdd�Zdd�ZdS)zHDNS rdatasets (an rdataset is a set of rdatas of a given type and class)�N)�StringIO�)�string_typesc@seZdZdZdS)�DifferingCoversz~An attempt was made to add a DNS SIG/RRSIG whose covered type
    is not the same as that of the other rdatas in the rdataset.N)�__name__�
__module__�__qualname__�__doc__�r
r
�/usr/lib/python3.6/rdataset.pyr!src@seZdZdZdS)�IncompatibleTypesz?An attempt was made to add DNS RR data of an incompatible type.N)rrrr	r
r
r
rr'srcs�eZdZdZddddgZejjf�fdd�	Z�fdd	�Z	d
d�Z
d$�fd
d�	Z�fdd�Z�fdd�Z
�fdd�Zdd�Zdd�Z�fdd�Zdd�Zd%dd�Zd&d d!�Zd"d#�Z�ZS)'�Rdataseta�A DNS rdataset.

    @ivar rdclass: The class of the rdataset
    @type rdclass: int
    @ivar rdtype: The type of the rdataset
    @type rdtype: int
    @ivar covers: The covered type.  Usually this value is
    dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
    dns.rdatatype.RRSIG, then the covers value will be the rdata
    type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
    types as if they were a family of
    types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
    easier to work with than if RRSIGs covering different rdata
    types were aggregated into a single RRSIG rdataset.
    @type covers: int
    @ivar ttl: The DNS TTL (Time To Live) value
    @type ttl: int
    �rdclass�rdtype�covers�ttlcs*tt|�j�||_||_||_d|_dS)z�Create a new rdataset of the specified class and type.

        @see: the description of the class instance variables for the
        meaning of I{rdclass} and I{rdtype}rN)�superr
�__init__rrrr)�selfrrr)�	__class__r
rrCs
zRdataset.__init__cs2tt|�j�}|j|_|j|_|j|_|j|_|S)N)rr
�_clonerrrr)r�obj)rr
rrOszRdataset._clonecCs(t|�dkr||_n||jkr$||_dS)z�Set the TTL of the rdataset to be the lesser of the set's current
        TTL or the specified TTL.  If the set contains no rdatas, set the TTL
        to the specified TTL.
        @param ttl: The TTL
        @type ttl: intrN)�lenr)rrr
r
r�
update_ttlWs
zRdataset.update_ttlNcs�|j|jks|j|jkrt�|dk	r.|j|�|jtjjksJ|jtjjkr�|j�}t	|�dkrt|jtjj
krt||_n|j|kr�t�tjj|j�r�t	|�dkr�|j
�tt|�j|�dS)a%Add the specified rdata to the rdataset.

        If the optional I{ttl} parameter is supplied, then
        self.update_ttl(ttl) will be called prior to adding the rdata.

        @param rd: The rdata
        @type rd: dns.rdata.Rdata object
        @param ttl: The TTL
        @type ttl: intNr)rrrr�dns�	rdatatypeZRRSIGZSIGrr�NONErZis_singleton�clearrr
�add)r�rdrr)rr
rrcs

zRdataset.addcs |j|j�tt|�j|�dS)N)rrrr
�union_update)r�other)rr
rr �szRdataset.union_updatecs |j|j�tt|�j|�dS)N)rrrr
�intersection_update)rr!)rr
rr"�szRdataset.intersection_updatecs |j|j�tt|�j|�dS)z�Add all rdatas in other to self.

        @param other: The rdataset from which to update
        @type other: dns.rdataset.Rdataset objectN)rrrr
�update)rr!)rr
rr#�szRdataset.updatecCsR|jdkrd}ndtjj|j�d}dtjj|j�dtjj|j�|dS)Nr��(�)z<DNS � z
 rdataset>)rrr�to_text�
rdataclassrr)rZctextr
r
r�__repr__�s
zRdataset.__repr__cCs|j�S)N)r()rr
r
r�__str__�szRdataset.__str__csFt|t�sdS|j|jks2|j|jks2|j|jkr6dStt|�j|�S)zTwo rdatasets are equal if they have the same class, type, and
        covers, and contain the same rdata.
        @rtype: boolF)�
isinstancer
rrrr�__eq__)rr!)rr
rr-�s
zRdataset.__eq__cCs|j|�S)N)r-)rr!r
r
r�__ne__�szRdataset.__ne__Tc
Ks�|dk	r"|j||�}t|�}d}nd}d}t�}|dk	r>|}	n|j}	t|�dkrz|jd||tjj|	�tj	j|j
�f�nNxL|D]D}
|jd|||jtjj|	�tj	j|j
�|
jf||d�|��f�q�W|j�dd	�S)
a�Convert the rdataset into DNS master file format.

        @see: L{dns.name.Name.choose_relativity} for more information
        on how I{origin} and I{relativize} determine the way names
        are emitted.

        Any additional keyword arguments are passed on to the rdata
        to_text() method.

        @param name: If name is not None, emit a RRs with I{name} as
        the owner name.
        @type name: dns.name.Name object
        @param origin: The origin for relative names, or None.
        @type origin: dns.name.Name object
        @param relativize: True if names should names be relativized
        @type relativize: boolNr'r$rz
%s%s%s %s
z%s%s%d %s %s %s
)�origin�
relativizer���)
Zchoose_relativity�strrrr�writerr)r(rrr�getvalue)r�namer/r0�override_rdclass�kwZntextZpad�srrr
r
rr(�s*


zRdataset.to_textc
Cs&|dk	r|}d}n|j}|jdd�t|�dkr`|j|||�tjd|j|dd�}|j|�dS|rxt|�}	t	j
|	�n|}	x�|	D]�}
|j|||�tjd|j||jd�}|j|�|j�}|
j|||�|j�}||dks�t
�|j|d�tjd||�}|j|�|jdd�q�Wt|�SdS)	a,Convert the rdataset to wire format.

        @param name: The owner name of the RRset that will be emitted
        @type name: dns.name.Name object
        @param file: The file to which the wire format data will be appended
        @type file: file
        @param compress: The compression table to use; the default is None.
        @type compress: dict
        @param origin: The origin to be appended to any relative names when
        they are emitted.  The default is None.
        @returns: the number of records emitted
        @rtype: int
        NFr�z!HHIHriz!H)r�seekr�to_wire�struct�packrr3�list�randomZshuffler�tell�AssertionError)
rr5�file�compressr/r6Zwant_shufflerZstuff�lr�start�endr
r
rr;�s8




zRdataset.to_wirecCs&|j|kr"|j|kr"|j|kr"dSdS)zSReturns True if this rdataset matches the specified class, type,
        and coversTF)rrr)rrrrr
r
r�matchs



zRdataset.match)N)NNTN)NNNT)rrrr	�	__slots__rrrrrrrr r"r#r*r+r-r.r(r;rG�
__classcell__r
r
)rrr
,s$ 	

2
/r
cCspt|t�rtjj|�}t|t�r,tjj|�}t||�}|j|�x*|D]"}tjj|j	|j
|�}|j|�qFW|S)z�Create an rdataset with the specified class, type, and TTL, and with
    the specified list of rdatas in text format.

    @rtype: dns.rdataset.Rdataset object
    )r,rrr)�	from_textrr
rZrdatarrr)rrr�text_rdatas�r�trr
r
r�from_text_lists




rNcGst||||�S)z�Create an rdataset with the specified class, type, and TTL, and with
    the specified rdatas in text format.

    @rtype: dns.rdataset.Rdataset object
    )rN)rrrrKr
r
rrJ/srJcCsTt|�dkrtd��d}x6|D].}|dkrBt|j|j�}|j|�|j|�qW|S)z�Create an rdataset with the specified TTL, and with
    the specified list of rdata objects.

    @rtype: dns.rdataset.Rdataset object
    rzrdata list must not be emptyN)r�
ValueErrorr
rrrr)r�rdatasrLrr
r
r�from_rdata_list9s

rQcGs
t||�S)z�Create an rdataset with the specified TTL, and with
    the specified rdata objects.

    @rtype: dns.rdataset.Rdataset object
    )rQ)rrPr
r
r�
from_rdataKsrR)r	r?�iorr<Z
dns.exceptionrZ
dns.rdatatypeZdns.rdataclassZ	dns.rdataZdns.setZ_compatr�set�SetZ	SimpleSetZ	exceptionZDNSExceptionrrr
rNrJrQrRr
r
r
r�<module>s$q
PKi�\z}��&&)__pycache__/renderer.cpython-36.opt-1.pycnu�[���3

�b�W�.�@shdZddlmZddlZddlZddlZddlZddlZddl	m
Z
dZdZdZ
dZGdd	�d	e�ZdS)
z*Help for building DNS wire format messages�)�BytesION�)�long��c@steZdZdZddd�Zdd�Zd	d
�Zejj	fdd�Z
d
d�Zdd�Zddd�Z
ejjfdd�Zdd�Zdd�ZdS)�RendereraiHelper class for building DNS wire-format messages.

    Most applications can use the higher-level L{dns.message.Message}
    class and its to_wire() method to generate wire-format messages.
    This class is for those applications which need finer control
    over the generation of messages.

    Typical use::

        r = dns.renderer.Renderer(id=1, flags=0x80, max_size=512)
        r.add_question(qname, qtype, qclass)
        r.add_rrset(dns.renderer.ANSWER, rrset_1)
        r.add_rrset(dns.renderer.ANSWER, rrset_2)
        r.add_rrset(dns.renderer.AUTHORITY, ns_rrset)
        r.add_edns(0, 0, 4096)
        r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_1)
        r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_2)
        r.write_header()
        r.add_tsig(keyname, secret, 300, 1, 0, '', request_mac)
        wire = r.get_wire()

    @ivar output: where rendering is written
    @type output: BytesIO object
    @ivar id: the message id
    @type id: int
    @ivar flags: the message flags
    @type flags: int
    @ivar max_size: the maximum size of the message
    @type max_size: int
    @ivar origin: the origin to use when rendering relative names
    @type origin: dns.name.Name object
    @ivar compress: the compression table
    @type compress: dict
    @ivar section: the section currently being rendered
    @type section: int (dns.renderer.QUESTION, dns.renderer.ANSWER,
    dns.renderer.AUTHORITY, or dns.renderer.ADDITIONAL)
    @ivar counts: list of the number of RRs in each section
    @type counts: int list of length 4
    @ivar mac: the MAC of the rendered message (if TSIG was used)
    @type mac: string
    Nr�cCsht�|_|dkr tjdd�|_n||_||_||_||_i|_t	|_
ddddg|_|jjd�d|_
dS)a�Initialize a new renderer.

        @param id: the message id
        @type id: int
        @param flags: the DNS message flags
        @type flags: int
        @param max_size: the maximum message size; the default is 65535.
        If rendering results in a message greater than I{max_size},
        then L{dns.exception.TooBig} will be raised.
        @type max_size: int
        @param origin: the origin to use when rendering relative names
        @type origin: dns.name.Name or None.
        Nri�����s)r�output�randomZrandint�id�flags�max_size�origin�compress�QUESTION�section�counts�write�mac)�selfrrrr�r�/usr/lib/python3.6/renderer.py�__init__NszRenderer.__init__cCs^|jj|�|jj�g}x(|jj�D]\}}||kr&|j|�q&Wx|D]}|j|=qJWdS)z�Truncate the output buffer at offset I{where}, and remove any
        compression table entries that pointed beyond the truncation
        point.

        @param where: the offset
        @type where: int
        N)r�seek�truncater�items�append)r�whereZkeys_to_delete�k�vrrr�	_rollbackks	

zRenderer._rollbackcCs&|j|kr"|j|krtjj�||_dS)aZSet the renderer's current section.

        Sections must be rendered order: QUESTION, ANSWER, AUTHORITY,
        ADDITIONAL.  Sections may be empty.

        @param section: the section
        @type section: int
        @raises dns.exception.FormError: an attempt was made to set
        a section value less than the current section.
        N)r�dns�	exceptionZ	FormError)rrrrr�_set_section}s

zRenderer._set_sectioncCsz|jt�|jj�}|j|j|j|j�|jjtj	d||��|jj�}||j
krd|j|�tj
j�|jtd7<dS)aAdd a question to the message.

        @param qname: the question name
        @type qname: dns.name.Name
        @param rdtype: the question rdata type
        @type rdtype: int
        @param rdclass: the question rdata class
        @type rdclass: int
        z!HHrN)r&rr�tell�to_wirerrr�struct�packrr#r$r%�TooBigr)rZqnameZrdtypeZrdclass�before�afterrrr�add_question�s




zRenderer.add_questioncKsh|j|�|jj�}|j|j|j|jf|�}|jj�}||jkrR|j|�tj	j
�|j||7<dS)aAdd the rrset to the specified section.

        Any keyword arguments are passed on to the rdataset's to_wire()
        routine.

        @param section: the section
        @type section: int
        @param rrset: the rrset
        @type rrset: dns.rrset.RRset object
        N)r&rr'r(rrrr#r$r%r+r)rrZrrset�kwr,�nr-rrr�	add_rrset�s




zRenderer.add_rrsetcKsj|j|�|jj�}|j||j|j|jf|�}|jj�}||jkrT|j|�tj	j
�|j||7<dS)a�Add the rdataset to the specified section, using the specified
        name as the owner name.

        Any keyword arguments are passed on to the rdataset's to_wire()
        routine.

        @param section: the section
        @type section: int
        @param name: the owner name
        @type name: dns.name.Name object
        @param rdataset: the rdataset
        @type rdataset: dns.rdataset.Rdataset object
        N)r&rr'r(rrrr#r$r%r+r)rr�nameZrdatasetr/r,r0r-rrr�add_rdataset�s




zRenderer.add_rdatasetc
Csf|td�M}||d>O}|jt�|jj�}|jjtjddtj	j
||d��|dk	�r(|jj�}x�|D]z}tjd|jd�}|jj|�|jj�}	|j|j�|jj�}
|jj
|	d�tjd|
|	�}|jj|�|jj
dd�qfW|jj�}|jj
|d�tjd||�}|jj|�|jj
dd�|jj�}||jk�rP|j|�tjj�|jtd	7<dS)
a�Add an EDNS OPT record to the message.

        @param edns: The EDNS level to use.
        @type edns: int
        @param ednsflags: EDNS flag values.
        @type ednsflags: int
        @param payload: The EDNS sender's payload field, which is the maximum
        size of UDP datagram the sender can handle.
        @type payload: int
        @param options: The EDNS options list
        @type options: list of dns.edns.Option instances
        @see: RFC 2671
        l�~�z!BHHIHrNz!HHrz!Hr)rr&�
ADDITIONALrr'rr)r*r$�	rdatatype�OPTZotyper(rrr#r%r+r)
rZednsZ	ednsflagsZpayloadZoptionsr,Zlstart�optZstuff�start�endZlendr-rrr�add_edns�s8










zRenderer.add_ednsc	Cs2|jt�|jj�}	|jj�}
tjj|
||tt	j	��||||||d�
\}|_
}|j|j|j|j
�|jjtjdtjjtjjdd��|jj�}
|jj|�|jj�}||jkr�|j|	�tjj�|jj|
d�|jjtjd||
��|jtd7<|jjd�|jjtjd|jt��|jjdd�dS)	a�Add a TSIG signature to the message.

        @param keyname: the TSIG key name
        @type keyname: dns.name.Name object
        @param secret: the secret to use
        @type secret: string
        @param fudge: TSIG time fudge
        @type fudge: int
        @param id: the message id to encode in the tsig signature
        @type id: int
        @param tsig_error: TSIG error code; default is 0.
        @type tsig_error: int
        @param other_data: TSIG other data.
        @type other_data: string
        @param request_mac: This message is a response to the request which
        had the specified MAC.
        @type request_mac: string
        @param algorithm: the TSIG algorithm to use
        @type algorithm: dns.name.Name object
        )�	algorithmz!HHIHrrz!Hr�
N)r&r5rr'�getvaluer$�tsigZsign�int�timerr(rrrr)r*r6ZTSIG�
rdataclass�ANYrr#r%r+rr)rZkeynameZsecretZfudgerZ
tsig_errorZ
other_dataZrequest_macr<r,�sZ
tsig_rdataZctxZrdata_startr-rrr�add_tsigs8







zRenderer.add_tsigc
CsX|jjd�|jjtjd|j|j|jd|jd|jd|jd��|jjdd�dS)z�Write the DNS message header.

        Writing the DNS message header is done after all sections
        have been rendered, but before the optional TSIG signature
        is added.
        rz!HHHHHHrrrN)rrrr)r*rrr)rrrr�write_header5s
zRenderer.write_headercCs
|jj�S)z@Return the wire format message.

        @rtype: string
        )rr>)rrrr�get_wireCszRenderer.get_wire)NrrN)N)�__name__�
__module__�__qualname__�__doc__rr#r&r$rB�INr.r1r3r;r?Zdefault_algorithmrErFrGrrrrr"s*

04r)rK�iorr)r
rAZ
dns.exceptionr$Zdns.tsigZ_compatrrZANSWERZ	AUTHORITYr5�objectrrrrr�<module>sPKi�\b�?,__pycache__/tsigkeyring.cpython-36.opt-1.pycnu�[���3

�b�W��@s8dZddlmZmZddlZddlZdd�Zdd�ZdS)zA place to store TSIG keys.�)�maybe_decode�maybe_encodeNcCs<i}x2|D]*}tjj|�}tjt||��}|||<q
W|S)z�Convert a dictionary containing (textual DNS name, base64 secret) pairs
    into a binary keyring which has (dns.name.Name, binary secret) pairs.
    @rtype: dict)�dns�name�	from_text�base64Zdecodestringr)�textring�keyring�keytext�keyname�secret�r
�!/usr/lib/python3.6/tsigkeyring.pyrs
rcCs<i}x2|D]*}t|j��}ttj||��}|||<q
W|S)z�Convert a dictionary containing (dns.name.Name, binary secret) pairs
    into a text keyring which has (textual DNS name, base64 secret) pairs.
    @rtype: dict)r�to_textrZencodestring)r	rrr
rr
r
rr&s
r)	�__doc__Zdns._compatrrrZdns.namerrrr
r
r
r�<module>s

PKi�\0
�	��%__pycache__/node.cpython-36.opt-1.pycnu�[���3

�b�W��@s<dZddlmZddlZddlZddlZGdd�de�ZdS)z)DNS nodes.  A node is a set of rdatasets.�)�StringIONc@s�eZdZdZdgZdd�Zdd�Zdd�Zd	d
�Zdd�Z	d
d�Z
dd�Zej
jdfdd�Zej
jdfdd�Zej
jfdd�Zdd�ZdS)�Nodez�A DNS node.

    A node is a set of rdatasets

    @ivar rdatasets: the node's rdatasets
    @type rdatasets: list of dns.rdataset.Rdataset objects�	rdatasetscCs
g|_dS)zInitialize a DNS node.
        N)r)�self�r�/usr/lib/python3.6/node.py�__init__$sz
Node.__init__cKsPt�}x8|jD].}t|�dkr|j|j|f|��|jd�qW|j�dd�S)a+Convert a node to text format.

        Each rdataset at the node is printed.  Any keyword arguments
        to this method are passed on to the rdataset's to_text() method.
        @param name: the owner name of the rdatasets
        @type name: dns.name.Name object
        @rtype: string
        r�
N����)rr�len�write�to_text�getvalue)r�name�kw�s�rdsrrrr*s
zNode.to_textcCsdtt|��dS)Nz
<DNS node �>)�str�id)rrrr�__repr__;sz
Node.__repr__cCs@x|jD]}||jkrdSqWx|jD]}||jkr&dSq&WdS)zSTwo nodes are equal if they have the same rdatasets.

        @rtype: bool
        FT)r)r�otherZrdrrr�__eq__>s

zNode.__eq__cCs|j|�S)N)r)rrrrr�__ne__NszNode.__ne__cCs
t|j�S)N)rr)rrrr�__len__QszNode.__len__cCs
t|j�S)N)�iterr)rrrr�__iter__Tsz
Node.__iter__FcCsHx |jD]}|j|||�r|SqW|s*t�tjj||�}|jj|�|S)aFind an rdataset matching the specified properties in the
        current node.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.  Usually this value is
        dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
        dns.rdatatype.RRSIG, then the covers value will be the rdata
        type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
        types as if they were a family of
        types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
        easier to work with than if RRSIGs covering different rdata
        types were aggregated into a single RRSIG rdataset.
        @type covers: int
        @param create: If True, create the rdataset if it is not found.
        @type create: bool
        @raises KeyError: An rdataset of the desired type and class does
        not exist and I{create} is not True.
        @rtype: dns.rdataset.Rdataset object
        )r�match�KeyError�dns�rdataset�Rdataset�append)r�rdclass�rdtype�covers�createrrrr�
find_rdatasetWszNode.find_rdatasetcCs2y|j||||�}Wntk
r,d}YnX|S)aEGet an rdataset matching the specified properties in the
        current node.

        None is returned if an rdataset of the specified type and
        class does not exist and I{create} is not True.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.
        @type covers: int
        @param create: If True, create the rdataset if it is not found.
        @type create: bool
        @rtype: dns.rdataset.Rdataset object or None
        N)r(r)rr$r%r&r'rrrr�get_rdatasetys

zNode.get_rdatasetcCs&|j|||�}|dk	r"|jj|�dS)azDelete the rdataset matching the specified properties in the
        current node.

        If a matching rdataset does not exist, it is not an error.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.
        @type covers: int
        N)r)r�remove)rr$r%r&rrrr�delete_rdataset�szNode.delete_rdatasetcCs:t|tjj�std��|j|j|j|j�|j	j
|�dS)a8Replace an rdataset.

        It is not an error if there is no rdataset matching I{replacement}.

        Ownership of the I{replacement} object is transferred to the node;
        in other words, this method does not store a copy of I{replacement}
        at the node, it stores I{replacement} itself.
        zreplacement is not an rdatasetN)�
isinstancer r!r"�
ValueErrorr+r$r%r&rr#)rZreplacementrrr�replace_rdataset�s

zNode.replace_rdatasetN)�__name__�
__module__�__qualname__�__doc__�	__slots__rrrrrrrr Z	rdatatypeZNONEr(r)r+r.rrrrrs!r)	r2�iorZdns.rdatasetr Z
dns.rdatatypeZdns.renderer�objectrrrrr�<module>s
PKi�\]���5�5 __pycache__/query.cpython-36.pycnu�[���3

�Of�L�@s�dZddlmZddlZddlZddlZddlZddlZddlZddl	Z
ddlZ
ddlZ
ddl
Z
ddlZ
ddlZ
ddlmZmZejd/kr�eZnejZejZGdd�de
jj�ZGd	d
�d
e
jj�Zdd�Zd
d�Zdd�Zdd�Z dd�Z!e"ed�r�ea#nea#dd�Z$dd�Z%dd�Z&dd�Z'dd�Z(d0d"d#�Z)d$d%�Z*d&d'�Z+d(d)�Z,d1d*d+�Z-e
j.j/e
j0j1dd ddd,dddddd!e
j2j3fd-d.�Z4dS)2zTalk to a DNS server.�)�
generatorsN�)�long�string_types�c@seZdZdZdS)�UnexpectedSourcez=A DNS query response came from an unexpected address or port.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/query.pyr,src@seZdZdZdS)�BadResponsez<A DNS query response does not respond to the question asked.N)rr	r
rrrrr
r1srcCs|dkrdStj�|SdS)N)�time)�timeoutrrr
�_compute_expiration6srcCsjd}|r|tjO}|r |tjO}|r.|tjO}tj�}|j||�|rZ|jt|d��}n|j�}t|�S)aqPoll polling backend.
    @param fd: File descriptor
    @type fd: int
    @param readable: Whether to wait for readability
    @type readable: bool
    @param writable: Whether to wait for writability
    @type writable: bool
    @param timeout: Deadline timeout (expiration time, in seconds)
    @type timeout: float
    @return True on success, False on timeout
    ri�)�selectZPOLLINZPOLLOUTZPOLLERR�poll�registerr�bool)�fd�readable�writable�errorrZ
event_maskZpollableZ
event_listrrr
�	_poll_for=s


rcCsrggg}}}|r|g}|r$|g}|r.|g}|dkrLtj|||�\}}	}
ntj||||�\}}	}
t|pn|	pn|
�S)asSelect polling backend.
    @param fd: File descriptor
    @type fd: int
    @param readable: Whether to wait for readability
    @type readable: bool
    @param writable: Whether to wait for writability
    @type writable: bool
    @param timeout: Deadline timeout (expiration time, in seconds)
    @type timeout: float
    @return True on success, False on timeout
    N)rr)rrrrrZrsetZwsetZxsetZrcountZwcountZxcountrrr
�_select_for\srcCs�d}x�|s�|dkrd}n|tj�}|dkr4tjj�yt|||||�sNtjj�Wn6tk
r�}z|jdtjkrv|�WYdd}~XnXd}qWdS)NFgrT)	r�dns�	exceptionZTimeout�_polling_backend�select_error�args�errnoZEINTR)rrrr�
expiration�doner�errr
�	_wait_forysr%cCs|adS)z#
    Internal API. Do not use.
    N)r)�fnrrr
�_set_polling_backend�sr'rcCst|ddd|�dS)NTF)r%)�sr"rrr
�_wait_for_readable�sr)cCst|ddd|�dS)NFT)r%)r(r"rrr
�_wait_for_writable�sr*cCsDtjj||d�}tjj||d�}||koB|dd�|dd�kS)Nrr)r�inetZ	inet_pton)�afZa1Za2Zn1Zn2rrr
�_addresses_equal�sr-cCs`|sdSt|||�s<tjj|d�r@|dd�|dd�kr@dS|rHdStd|�d|����dS)NTrrFzgot a response from z instead of )r-rr+Zis_multicastr)r,�from_address�destination�ignore_unexpectedrrr
�_matches_destination�s(r1cCs�|dkr6ytjj|�}Wntk
r4tjj}YnX|tjjkrp||f}|dk	sZ|dkr�|dkrfd}||f}n@|tjjkr�||ddf}|dk	s�|dkr�|dkr�d}||ddf}|||fS)Nrz0.0.0.0z::)rr+Zaf_for_address�	ExceptionZAF_INETZAF_INET6)r,�where�port�source�source_portr/rrr
�_destination_and_source�s$
r7�5Fc
Cs"|j�}
t|||||�\}}}t|tjd�}d}
z�t|�}|jd�|dk	rV|j|�t||�t	j	�}
|j
|
|�x�t||�|jd�\}
}t
|j|||�s�qvt	j	�|
}y"tjj|
|j|j|d�}||_	Wntk
r�|	r�wvn�YnX|j|��r�|S|	�rqvqvt�qvWWd|j�XdS)a�Return the response obtained after sending a query via UDP.

    @param q: the query
    @type q: dns.message.Message
    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param timeout: The number of seconds to wait before the query times out.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @rtype: dns.message.Message object
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param ignore_unexpected: If True, ignore responses from unexpected
    sources.  The default is False.
    @type ignore_unexpected: bool
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    rNi��)�keyring�request_mac�one_rr_per_rrset)�to_wirer7�socket_factory�socket�
SOCK_DGRAMr�setblocking�bindr*rZsendtor)�recvfromr1Zfamilyr�message�	from_wirer9�macr2�is_responser�close)�qr3rr4r,r5r6r0r;�
ignore_errors�wirer/r(�
begin_timer"r.�
response_time�rrrr
�udp�sD




rNcCsJd}x@|dkrDt||�|j|�}|dkr.t�|t|�}||}qW|S)z�Read the specified number of bytes from sock.  Keep trying until we
    either get the desired amount, or we hit EOF.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    �r)r)Zrecv�EOFError�len)�sock�countr"r(�nrrr
�	_net_reads


rUcCs>d}t|�}x,||kr8t||�||j||d��7}qWdS)z�Write the specified data to the socket.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    rN)rQr*�send)rR�datar"Zcurrent�lrrr
�
_net_write/s


rYcCspy|j|�Wn\tjk
rjtj�dd�\}}t|d�rF|j}n|d}|tjtjtj	gkrf|�YnXdS)N�r!r)
Zconnectr>r�sys�exc_info�hasattrr!ZEINPROGRESSZEWOULDBLOCKZEALREADY)r(ZaddressZty�vZv_errrrr
�_connect;s
r_cCs|j�}t|||||�\}}	}t|tjd�}
d}z�t|�}|
jd�tj�}|dk	r^|
j|�t	|
|	�t
|�}
tjd|
�|}t
|
||�t|
d|�}tjd|�\}
t|
|
|�}Wd|dkr�d}ntj�|}|
j�Xtjj||j|j|d�}||_|j|��st�|S)aReturn the response obtained after sending a query via TCP.

    @param q: the query
    @type q: dns.message.Message object
    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param timeout: The number of seconds to wait before the query times out.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @rtype: dns.message.Message object
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    rNz!HrZ)r9r:r;)r<r7r=r>�SOCK_STREAMrr@rrAr_rQ�struct�packrYrU�unpackrGrrCrDr9rErFr)rHr3rr4r,r5r6r;rJr/r(rKr"rX�tcpmsg�ldatarLrMrrr
�tcpIs8



rfTc&cs�t|t�rtjj|�}t|t�r,tjj|�}tjj|||�}|tjjkrltj	j|dddd|
�}|j
j|�|dk	r�|j|||d�|j
�}t|	||||�\}	}}|r�|tjjkr�td��t|	tjd�}nt|	tjd�}|jd�|dk	r�|j|�t|
�}t||�t|�}|�r*t||�|j|�ntjd|�|}t|||�d	}d
}d	}d}|�rj|}tjj}nd}|}d}d
}�x6|�s�t|�} | dk�s�|dk	�r�| |k�r�|} |�r�t||�|j d�\}}!n&t!|d| �}"tj"d|"�\}t!||| �}|tjjk}#tjj#||j$|j%d
||d
||#d
�	}$|$j&}d	}d}%|dk�r�|$j'�sV|$j'dj|k�rbtj(j)d��|$j'd}|j*tjj+k�r�tj(j)d��d}%|j,�}|tjjk�r�|dj-|
k�r�d
}nd
}x�|$j'|%d�D]�}|�r�tj(j)d��|j*tjj+k�rl|j|k�rl|�r&|dj-|
k�r tj(j)d��d	}n|tjjk�r:|}||k�r~|tjj.k�sf|tjjk�r~|�r~d
}n|�r�tjj.}d	}�q�W|�r�|j$�r�|$j/�r�tj(j)d��|$V�q~W|j0�dS)a�Return a generator for the responses to a zone transfer.

    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param zone: The name of the zone to transfer
    @type zone: dns.name.Name object or string
    @param rdtype: The type of zone transfer.  The default is
    dns.rdatatype.AXFR.
    @type rdtype: int or string
    @param rdclass: The class of the zone transfer.  The default is
    dns.rdataclass.IN.
    @type rdclass: int or string
    @param timeout: The number of seconds to wait for each response message.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param keyring: The TSIG keyring to use
    @type keyring: dict
    @param keyname: The name of the TSIG key to use
    @type keyname: dns.name.Name object or string
    @param relativize: If True, all names in the zone will be relativized to
    the zone origin.  It is essential that the relativize setting matches
    the one specified to dns.zone.from_xfr().
    @type relativize: bool
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @param lifetime: The total number of seconds to spend doing the transfer.
    If None, the default, then there is no limit on the time the transfer may
    take.
    @type lifetime: float
    @rtype: generator of dns.message.Message objects.
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param serial: The SOA serial number to use as the base for an IXFR diff
    sequence (only meaningful if rdtype == dns.rdatatype.IXFR).
    @type serial: int
    @param use_udp: Use UDP (only meaningful for IXFR)
    @type use_udp: bool
    @param keyalgorithm: The TSIG algorithm to use; defaults to
    dns.tsig.default_algorithm
    @type keyalgorithm: string
    r�IN�SOAz. . %u 0 0 0 0N)�	algorithmzcannot do a UDP AXFRz!HFTi��rZ)r9r:�xfr�origin�tsig_ctxZmulti�firstr;z No answer or RRset not for qnamezfirst RRset is not an SOArzanswers after final SOAzIXFR base serial mismatchzmissing TSIG)1�
isinstancerr�nameZ	from_text�	rdatatyperCZ
make_queryZIXFR�rrsetZ	authority�appendZuse_tsigr<r7�
ValueErrorr=r>r?r`r@rArr_rQr*rVrarbrY�emptyr)rBrUrcrDr9rErlZanswerr�	FormError�rdtyperh�copy�serial�AXFRZhad_tsigrG)&r3ZzonervZrdclassrr4r9ZkeynameZ
relativizer,Zlifetimer5r6rxZuse_udpZkeyalgorithmrHrqrJr/r(r"rXrdr#Zdelete_modeZ
expecting_SOAZ	soa_rrsetrkZonamerlrmZmexpirationr.reZis_ixfrrMZanswer_indexrrr
rj�s�5














rj)r)Nr8NNrFFF)Nr8NNrF)5rZ
__future__rr!rr>rar[rZ
dns.exceptionrZdns.inetZdns.nameZdns.messageZdns.rdataclassZ
dns.rdatatypeZ_compatrr�version_info�OSErrorrrr=rZDNSExceptionrrurrrrr%r'r]rr)r*r-r1r7rNrUrYr_rfrpryZ
rdataclassrgZtsigZdefault_algorithmrjrrrr
�<module>sX

	
I
?

PKi�\�f5���(__pycache__/entropy.cpython-36.opt-1.pycnu�[���3

�b�Wq�@s�ddlZddlZddlZddlmZmZyddlZWnek
rPddl	ZYnXGdd�de
�Ze�Zyej
�ZWnek
r�dZYnXdd�Zdd	�ZdS)
�N�)�long�binary_typec@sHeZdZddd�Zddd�Zdd�Zd	d
�Zdd�Zd
d�Zdd�Z	dS)�EntropyPoolNcCs�d|_d|_d|_tj�|_yddl}|j�|_d|_	Wn^t
k
r�yddl}|j�|_d|_	Wn,t
k
r�ddl
}|j�|_d|_	YnXYnXtd|j	�|_|dk	r�|jt|��d|_tj�|_nd|_d|_dS)Nr���TF)�
pool_index�digest�	next_byte�
_threadingZLock�lock�hashlibZsha1�hash�hash_len�ImportError�sha�new�md5�	bytearray�pool�stir�seeded�os�getpid�seed_pid)�self�seedrrr�r�/usr/lib/python3.6/entropy.py�__init__s0





zEntropyPool.__init__FcCsr|s|jj�zNxH|D]@}|j|jkr,d|_|d@}|j|j|N<|jd7_qWWd|sl|jj�XdS)Nr�r)r
�acquirer	rr�release)rZentropyZalready_locked�c�brrrr7s

zEntropyPool.stircCs�|js|jtj�kr�ytjd�}Wn`tk
r�y*tddd�}z|jd�}Wd|j�XWn tk
r~t	t
j
��}YnXYnXd|_tj�|_d|_t|�}|j
|d�dS)Nrz/dev/urandom�rbrT)rrrr�urandom�	Exception�open�read�close�str�timer
rr)rr�rrrr�_maybe_seedEs 
zEntropyPool._maybe_seedc
Cs�|jj�zr|j�|jdks*|j|jkr`|jjt|j	��t
|jj��|_|j|jd�d|_|j|j}|jd7_Wd|jj�X|S)NTrr)
r
r"r/r
rrr�updaterrrrr#)r�valuerrr�random_8Xs
zEntropyPool.random_8cCs|j�d|j�S)N�)r2)rrrr�	random_16gszEntropyPool.random_16cCs|j�d|j�S)Ni)r4)rrrr�	random_32jszEntropyPool.random_32cCsl||d}|td�kr td��|dkr8|j}td�}n|dkrL|j}d}n
|j}d}|||�|dS)	Nrlztoo bigil��r3i��r!)r�
ValueErrorr5r4r2)r�first�last�sizeZrand�maxrrr�random_betweenms
zEntropyPool.random_between)N)F)
�__name__�
__module__�__qualname__r rr/r2r4r5r;rrrrrs

rcCs tdk	rtjdd�Stj�SdS)Nri)�
system_random�	randrangerr4rrrrr4�sr4cCs(tdk	rtj||d�Stj||�SdS)Nr)r?r@rr;)r7r8rrr�between�srA)rZrandomr-Z_compatrrZ	threadingrrZdummy_threading�objectrrZSystemRandomr?r(r4rArrrr�<module>sb
PKi�\YZ
88 __pycache__/rdata.cpython-36.pycnu�[���3

�b�W�:�@s�dZddlmZddlZddlZddlZddlZddlZddl	Zddl
ZddlZddlm
Z
mZmZdZefdd�ZdZefd	d
�Zed�Zdd
�Zdd�ZGdd�de�ZGdd�de�ZiZdZdd�Zddd�Zddd�ZdS)a�DNS rdata.

@var _rdata_modules: A dictionary mapping a (rdclass, rdtype) tuple to
the module which implements that type.
@type _rdata_modules: dict
@var _module_prefix: The prefix to use when forming modules names.  The
default is 'dns.rdtypes'.  Changing this value will break the library.
@type _module_prefix: string
@var _hex_chunk: At most this many octets that will be represented in each
chunk of hexstring that _hexify() produces before whitespace occurs.
@type _hex_chunk: int�)�BytesION�)�xrange�string_types�	text_type� cs4tj|��dj��fdd�tdt����D��j�S)aConvert a binary string into its hex encoding, broken up into chunks
    of I{chunksize} characters separated by a space.

    @param data: the binary string
    @type data: string
    @param chunksize: the chunk size.  Default is L{dns.rdata._hex_chunksize}
    @rtype: string
    � csg|]}�||���qS�r	)�.0�i)�	chunksize�liner	�/usr/lib/python3.6/rdata.py�
<listcomp>6sz_hexify.<locals>.<listcomp>r)�binasciiZhexlify�join�range�len�decode)�datarr	)rr
r�_hexify+s

rcs4tj|��dj��fdd�tdt����D��j�S)a$Convert a binary string into its base64 encoding, broken up into chunks
    of I{chunksize} characters separated by a space.

    @param data: the binary string
    @type data: string
    @param chunksize: the chunk size.  Default is
    L{dns.rdata._base64_chunksize}
    @rtype: string
    rcsg|]}�||���qSr	r	)r
r)rr
r	rrIsz_base64ify.<locals>.<listcomp>r)�base64Z	b64encoderrrr)rrr	)rr
r�
_base64ify=s
rs"\cCs~t|t�r|j�}t|t�s$t|�}d}xP|D]H}|tkrL|dt|�7}q.|dkrj|dkrj|t|�7}q.|d|7}q.W|S)z�Escape the characters in a quoted string which need it.

    @param qstring: the string
    @type qstring: string
    @returns: the escaped string
    @rtype: string
    ��\r�z\%03d)�
isinstancer�encode�	bytearray�	__escaped�chr)Zqstring�text�cr	r	r�	_escapifyOs	


r#cCsFx8tt|�ddd�D] }||dkr|d|d�SqW|dd�S)z�Determine the index of greatest byte that isn't all zeros, and
    return the bitmap that contains all the bytes less than that index.

    @param what: a string of octets representing a bitmap.
    @type what: string
    @rtype: string
    rr���r$)rr)Zwhatrr	r	r�_truncate_bitmaphs	r%c@s�eZdZdZddgZdd�Zdd�Zdd	�Zd.dd
�Zd/dd�Z	d0dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zed1d(d)��Zed2d*d+��Zd3d,d-�Zd
S)4�Rdataz(Base class for all DNS rdata types.
    �rdclass�rdtypecCs||_||_dS)z�Initialize an rdata.
        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        N)r'r()�selfr'r(r	r	r�__init__~szRdata.__init__cCstjjS)a_DNS SIG/RRSIG rdatas apply to a specific type; this type is
        returned by the covers() function.  If the rdata type is not
        SIG or RRSIG, dns.rdatatype.NONE is returned.  This is useful when
        creating rdatasets, allowing the rdataset to contain only RRSIGs
        of a particular type, e.g. RRSIG(NS).
        @rtype: int
        )�dns�	rdatatype�NONE)r)r	r	r�covers�s	zRdata.coverscCs|j�d>|jBS)z�Return a 32-bit type value, the least significant 16 bits of
        which are the ordinary DNS type, and the upper 16 bits of which are
        the "covered" type, if any.
        @rtype: int
        �)r.r()r)r	r	r�extended_rdatatype�szRdata.extended_rdatatypeNTcKst�dS)z@Convert an rdata to text format.
        @rtype: string
        N)�NotImplementedError)r)�origin�
relativize�kwr	r	r�to_text�sz
Rdata.to_textcCst�dS)z@Convert an rdata to wire format.
        @rtype: string
        N)r1)r)�file�compressr2r	r	r�to_wire�sz
Rdata.to_wirecCst�}|j|d|�|j�S)zlConvert rdata to a format suitable for digesting in hashes.  This
        is also the DNSSEC canonical form.N)rr8�getvalue)r)r2�fr	r	r�
to_digestable�szRdata.to_digestablecCstjj|j|j|j��dS)z�Check that the current contents of the rdata's fields are
        valid.  If you change an rdata by assigning to its fields,
        it is a good idea to call validate() when you are done making
        changes.
        N)r+�rdata�	from_textr'r(r5)r)r	r	r�validate�szRdata.validatecCsf|j�}|tjjkrd}ndtjj|�d}dtjj|j�dtjj|j�|dt|�dS)Nr�(�)z<DNS � z rdata: �>)	r.r+r,r-r5�
rdataclassr'r(�str)r)r.Zctextr	r	r�__repr__�s
zRdata.__repr__cCs|j�S)N)r5)r)r	r	r�__str__�sz
Rdata.__str__cCs8|jtjj�}|jtjj�}||kr(dS||kr4dSdS)z�Compare an rdata with another rdata of the same rdtype and
        rdclass.  Return < 0 if self < other in the DNSSEC ordering,
        0 if self == other, and > 0 if self > other.
        rrr$)r;r+�name�root)r)�otherZourZtheirr	r	r�_cmp�sz
Rdata._cmpcCs8t|t�sdS|j|jks&|j|jkr*dS|j|�dkS)NFr)rr&r'r(rJ)r)rIr	r	r�__eq__�s

zRdata.__eq__cCs8t|t�sdS|j|jks&|j|jkr*dS|j|�dkS)NTr)rr&r'r(rJ)r)rIr	r	r�__ne__�s

zRdata.__ne__cCs6t|t�s$|j|jks$|j|jkr(tS|j|�dkS)Nr)rr&r'r(�NotImplementedrJ)r)rIr	r	r�__lt__�szRdata.__lt__cCs6t|t�s$|j|jks$|j|jkr(tS|j|�dkS)Nr)rr&r'r(rMrJ)r)rIr	r	r�__le__�szRdata.__le__cCs6t|t�s$|j|jks$|j|jkr(tS|j|�dkS)Nr)rr&r'r(rMrJ)r)rIr	r	r�__ge__�szRdata.__ge__cCs6t|t�s$|j|jks$|j|jkr(tS|j|�dkS)Nr)rr&r'r(rMrJ)r)rIr	r	r�__gt__�szRdata.__gt__cCst|jtjj��S)N)�hashr;r+rGrH)r)r	r	r�__hash__�szRdata.__hash__cCst�dS)a�Build an rdata object from text format.

        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        @param tok: The tokenizer
        @type tok: dns.tokenizer.Tokenizer
        @param origin: The origin to use for relative names
        @type origin: dns.name.Name
        @param relativize: should names be relativized?
        @type relativize: bool
        @rtype: dns.rdata.Rdata instance
        N)r1)�clsr'r(�tokr2r3r	r	rr=�szRdata.from_textcCst�dS)a<Build an rdata object from wire format

        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        @param wire: The wire-format message
        @type wire: string
        @param current: The offset in wire of the beginning of the rdata.
        @type current: int
        @param rdlen: The length of the wire-format rdata
        @type rdlen: int
        @param origin: The origin to use for relative names
        @type origin: dns.name.Name
        @rtype: dns.rdata.Rdata instance
        N)r1)rTr'r(�wire�current�rdlenr2r	r	r�	from_wireszRdata.from_wirecCsdS)zWConvert any domain names in the rdata to the specified
        relativization.
        Nr	)r)r2r3r	r	r�choose_relativity&szRdata.choose_relativity)NT)NN)N)NT)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__r*r.r0r5r8r;r>rErFrJrKrLrNrOrPrQrS�classmethodr=rYrZr	r	r	rr&ws0	



r&csVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�GenericRdataz�Generate Rdata Class

    This class is used for rdata types for which we have no better
    implementation.  It implements the DNS "unknown RRs" scheme.
    rcstt|�j||�||_dS)N)�superrar*r)r)r'r(r)�	__class__r	rr*8szGenericRdata.__init__NTcKsdt|j�t|j�S)Nz\# %d )rrr)r)r2r3r4r	r	rr5<szGenericRdata.to_textcCs�|j�}|j�s|jdkr(tjjd��|j�}g}x&|j�}|j�rHP|j|jj	��q6Wdj
|�}	tj|	�}
t
|
�|kr�tjjd��||||
�S)Nz\#z$generic rdata does not start with \#�z'generic rdata hex data has wrong length)�get�
is_identifier�valuer+Z	exception�SyntaxErrorZget_intZ
is_eol_or_eof�appendrrrZ	unhexlifyr)rTr'r(rUr2r3�tokenZlengthZchunks�hexrr	r	rr=?s"

zGenericRdata.from_textcCs|j|j�dS)N)�writer)r)r6r7r2r	r	rr8SszGenericRdata.to_wirecCs|||||||��S)Nr	)rTr'r(rVrWrXr2r	r	rrYVszGenericRdata.from_wire)NT)NT)NN)N)r[r\r]r^r_r*r5r`r=r8rY�
__classcell__r	r	)rcrra.s

razdns.rdtypescCs�dd�}tj||f�}tjj|�}tjj|�}|jdd�}|s�tjtjj|f�}|s�y$|djt	||g��}|t||f<WnVt
k
r�y(|djt	d|g��}|ttjj|f<Wnt
k
r�d}YnXYnX|r�t||�}nt}|S)NcSs6t|�}|jd�}x|dd�D]}t||�}q W|S)N�.r)�
__import__�split�getattr)rG�modZ
components�compr	r	r�
import_module`s

z&get_rdata_class.<locals>.import_module�-�_rn�ANY)
�_rdata_modulesrer+rCr5r,�replacerwr�_module_prefix�ImportErrorrqra)r'r(rtrrZrdclass_textZrdtype_textrTr	r	r�get_rdata_class^s.r|TcCs�t|t�rtjj|�}t||�}|tkrx|j�}|j|�|j	�rx|j
dkrxtj|||||�}t|||j
dt|j
�|�S|j|||||�S)adBuild an rdata object from text format.

    This function attempts to dynamically load a class which
    implements the specified rdata class and type.  If there is no
    class-and-type-specific implementation, the GenericRdata class
    is used.

    Once a class is chosen, its from_text() class method is called
    with the parameters to this function.

    If I{tok} is a string, then a tokenizer is created and the string
    is used as its input.

    @param rdclass: The rdata class
    @type rdclass: int
    @param rdtype: The rdata type
    @type rdtype: int
    @param tok: The tokenizer or input text
    @type tok: dns.tokenizer.Tokenizer or string
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name
    @param relativize: Should names be relativized?
    @type relativize: bool
    @rtype: dns.rdata.Rdata instancez\#r)rrr+Z	tokenizer�	Tokenizerr|rareZungetrfrgr=rYrr)r'r(rUr2r3rTrjr<r	r	rr=�s



r=cCs*tjj|�}t||�}|j||||||�S)a>Build an rdata object from wire format

    This function attempts to dynamically load a class which
    implements the specified rdata class and type.  If there is no
    class-and-type-specific implementation, the GenericRdata class
    is used.

    Once a class is chosen, its from_wire() class method is called
    with the parameters to this function.

    @param rdclass: The rdata class
    @type rdclass: int
    @param rdtype: The rdata type
    @type rdtype: int
    @param wire: The wire-format message
    @type wire: string
    @param current: The offset in wire of the beginning of the rdata.
    @type current: int
    @param rdlen: The length of the wire-format rdata
    @type rdlen: int
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name
    @rtype: dns.rdata.Rdata instance)r+ZwiredataZ
maybe_wrapr|rY)r'r(rVrWrXr2rTr	r	rrY�s
rY)NT)N) r^�iorrrZ
dns.exceptionr+Zdns.nameZdns.rdataclassZ
dns.rdatatypeZ
dns.tokenizerZdns.wiredataZ_compatrrrZ_hex_chunksizerZ_base64_chunksizerrrr#r%�objectr&rarxrzr|r=rYr	r	r	r�<module>s28,"
/PKi�\�M�����#__pycache__/resolver.cpython-36.pycnu�[���3

>D�W���@s�dZddlZddlZddlZddlZyddlZWnek
rLddlZYnXddl	Z
ddlZ
ddlZ
ddl
Z
ddlZ
ddlZ
ddlZ
ddlZ
ddlZ
ddlZ
ddlZ
ddlZ
ddlmZmZejdkr�yddlZWnek
r�ddlZYnXGdd�de
jj�ZGdd	�d	e
jj�Ze
jj Z Gd
d�de
jj�Z!Gdd
�d
e
jj�Z"Gdd�de
jj�Z#Gdd�de
jj�Z$Gdd�de
jj�Z%Gdd�de&�Z'Gdd�de&�Z(Gdd�de&�Z)Gdd�de&�Z*Gdd�de&�Z+da,dd�Z-d d!�Z.e
j/j0e
j1j2d"dd#dfd$d%�Z3e
j1j2d"dfd&d'�Z4ej5ej6gej7ej8giZ9da:ej;Z<ej=Z>ej?Z@ejAZBejCZDejEZFddejGdddfd(d)�ZHd8d*d+�ZId9d,d-�ZJd.d/�ZKd0d1�ZLd2d3�ZMd:d4d5�ZNd6d7�ZOdS);z{DNS stub resolver.

@var default_resolver: The default resolver object
@type default_resolver: dns.resolver.Resolver object�N�)�xrange�string_types�win32csVeZdZdZeddg�ZdZddd�Z�fdd�Zd	d
�Z	e
e	dd�Z	d
d�Z�ZS)�NXDOMAINz"The DNS query name does not exist.�qnames�	responsesNcCs\t|tttf�std��t|�dkr,td��|dkr:i}nt|t�sLtd��t||d�}|S)Nz#qnames must be a list, tuple or setrz(qnames must contain at least one elementz(responses must be a dict(qname=response))rr)�
isinstance�list�tuple�set�AttributeError�len�dict)�selfrr�kwargs�r�/usr/lib/python3.6/resolver.py�
_check_kwargs9s
zNXDOMAIN._check_kwargscs^d|jkrtt|�j�S|jd}t|�dkr4d}n|jdd�}djtt|��}d||fS)NrrzNone of DNS query names existz, z%s: %s���)	r�superr�__str__r�__doc__�join�map�str)rr�msg)�	__class__rrrEs

zNXDOMAIN.__str__cCs�d|jkrtd��tjj}tjj}d}xj|jdD]\}|jd|}x4|jD]*}|j|ksL|j	|krfqL|j
djj�}qLW|dk	r2tj
j|�Sq2W|jddS)Nrzparametrized exception requiredrr)r�	TypeError�dns�
rdataclass�IN�	rdatatype�CNAME�answer�rdtype�rdclass�items�target�to_text�name�	from_text)rr!r#�cname�qname�responser$rrr�canonical_namePs
zNXDOMAIN.canonical_namez%Return the unresolved canonical name.)�doccCs|t|jjdg��}t|jjdi��}|jjdi�}x<|jjdg�D]*}||krX|j|�||krB||||<qBWt||d�S)z3Augment by results from another NXDOMAIN exception.rr)rr)r
r�getr�appendr)rZe_nxZqnames0Z
responses0Z
responses1Zqname1rrr�__add__bs
zNXDOMAIN.__add__)N)
�__name__�
__module__�__qualname__rr�supp_kwargs�fmtrrr/�propertyr3�
__classcell__rr)rrr3s
rc@seZdZdZdS)�YXDOMAINz8The DNS query name is too long after DNAME substitution.N)r4r5r6rrrrrr;osr;cs.eZdZdZdZedg�Z�fdd�Z�ZS)�NoAnswerz<The DNS response does not contain an answer to the question.z,The DNS response does not contain an answer zto the question: {query}r.cstt|�j|djd�S)Nr.)�query)rr<�_fmt_kwargs�question)rr)rrrr>�s
zNoAnswer._fmt_kwargszDThe DNS response does not contain an answer to the question: {query})	r4r5r6rr8rr7r>r:rr)rrr<zs

r<cs@eZdZdZdZdedd
�Zeddg�Z�fdd	�Z�Z	S)�
NoNameserversz�All nameservers failed to answer the query.

    errors: list of servers and respective errors
    The type of errors is
    [(server ip address, any object convertible to string)].
    Non-empty errors list will add explanatory message ()
    z+All nameservers failed to answer the query.z%s {query}: {errors}Nr�request�errorscsdg}x>|dD]2}|jd|d|dr*dnd|d|df�qWtt|�j|d	jd
j|�d�S)NrBz Server %s %s port %s answered %srrZTCPZUDP��rAz; )r=rB)r2rr@r>r?r)rrZsrv_msgs�err)rrrr>�s&
zNoNameservers._fmt_kwargsr)
r4r5r6rrr8rr7r>r:rr)rrr@�s
r@c@seZdZdZdS)�NotAbsolutezEAn absolute domain name is required but a relative name was provided.N)r4r5r6rrrrrrF�srFc@seZdZdZdS)�	NoRootSOAzBThere is no SOA RR at the DNS root name. This should never happen!N)r4r5r6rrrrrrG�srGc@seZdZdZdS)�
NoMetaqueriesz DNS metaqueries are not allowed.N)r4r5r6rrrrrrH�srHc@sBeZdZdZddd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dS)�Answera9DNS stub resolver answer

    Instances of this class bundle up the result of a successful DNS
    resolution.

    For convenience, the answer object implements much of the sequence
    protocol, forwarding to its rrset.  E.g. "for a in answer" is
    equivalent to "for a in answer.rrset", "answer[i]" is equivalent
    to "answer.rrset[i]", and "answer[i:j]" is equivalent to
    "answer.rrset[i:j]".

    Note that CNAMEs or DNAMEs in the response may mean that answer
    node's name might not be the query name.

    @ivar qname: The query name
    @type qname: dns.name.Name object
    @ivar rdtype: The query type
    @type rdtype: int
    @ivar rdclass: The query class
    @type rdclass: int
    @ivar response: The response message
    @type response: dns.message.Message object
    @ivar rrset: The answer
    @type rrset: dns.rrset.RRset object
    @ivar expiration: The time when the answer expires
    @type expiration: float (seconds since the epoch)
    @ivar canonical_name: The canonical name of the query name
    @type canonical_name: dns.name.Name object
    TcCs�||_||_||_||_d}d}x�tdd�D]�}y0|j|j|||�}|dksV|j|kr\|j}PWq,tk
�r|t	j
jkr�yJ|j|j||t	j
j�}	|dks�|	j|kr�|	j}x|	D]}
|
j}Pq�Ww,Wn"tk
r�|r�t
|d��YnX|�r�t
|d��Yq,Xq,W|dk�r |�r t
|d��||_||_|dk�r�x�yR|j|j||t	j
j�}|dk�sf|j|k�rl|j}|dj|k�r�|dj}PWn@tk
�r�y|j�}Wnt	jjk
�r�PYnXYnX�q8Wtj�||_dS)	Nrr�)r.rrrr)r-r%r&r.rZ
find_rrsetr$�ttl�KeyErrorrr"r#r(r<r/�rrsetZ	authority�SOAZminimum�parentr*�NoParent�time�
expiration)rr-r%r&r.�raise_on_no_answerZmin_ttlrM�countZcrrsetZrdZsrrsetrrr�__init__�sf






zAnswer.__init__cCs\|dkr|jjS|dkr |jjS|dkr0|jjS|dkr@|jjS|dkrP|jjSt|��dS)Nr*rK�coversr&r%)rMr*rKrVr&r%r
)r�attrrrr�__getattr__szAnswer.__getattr__cCs|jrt|j�pdS)Nr)rMr)rrrr�__len__szAnswer.__len__cCs|jrt|j�ptt��S)N)rM�iterr)rrrr�__iter__szAnswer.__iter__cCs
|j|S)N)rM)r�irrr�__getitem__szAnswer.__getitem__cCs|j|=dS)N)rM)rr\rrr�__delitem__szAnswer.__delitem__N)T)
r4r5r6rrUrXrYr[r]r^rrrrrI�s
7rIc@s<eZdZdZddd�Zdd�Zdd�Zd	d
�Zddd
�ZdS)�CacheaqSimple DNS answer cache.

    @ivar data: A dictionary of cached data
    @type data: dict
    @ivar cleaning_interval: The number of seconds between cleanings.  The
    default is 300 (5 minutes).
    @type cleaning_interval: float
    @ivar next_cleaning: The time the cache should next be cleaned (in seconds
    since the epoch.)
    @type next_cleaning: float
    ��r@cCs*i|_||_tj�|j|_tj�|_dS)z�Initialize a DNS cache.

        @param cleaning_interval: the number of seconds between periodic
        cleanings.  The default is 300.0
        @type cleaning_interval: float.
        N)�data�cleaning_intervalrQ�
next_cleaning�
_threading�Lock�lock)rrbrrrrU-szCache.__init__cCsptj�}|j|krlg}x*|jj�D]\}}|j|kr"|j|�q"Wx|D]}|j|=qHWtj�}||j|_dS)z&Clean the cache if it's time to do so.N)rQrcrar'rRr2rb)r�nowZkeys_to_delete�k�vrrr�_maybe_clean:s


zCache._maybe_cleanc
CsNz<|jj�|j�|jj|�}|dks6|jtj�kr:dS|S|jj�XdS)a)Get the answer associated with I{key}.  Returns None if
        no answer is cached for the key.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @rtype: dns.resolver.Answer object or None
        N)rf�acquirerjrar1rRrQ�release)r�keyrirrrr1Hs	
z	Cache.getc
Cs2z |jj�|j�||j|<Wd|jj�XdS)aAssociate key and value in the cache.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @param value: The answer being cached
        @type value: dns.resolver.Answer object
        N)rfrkrjrarl)rrm�valuerrr�put[s
	
z	Cache.putNc
CsRz@|jj�|dk	r(||jkr>|j|=ni|_tj�|j|_Wd|jj�XdS)z�Flush the cache.

        If I{key} is specified, only that item is flushed.  Otherwise
        the entire cache is flushed.

        @param key: the key to flush
        @type key: (dns.name.Name, int, int) tuple or None
        N)rfrkrarQrbrcrl)rrmrrr�flushks



zCache.flush)r`)N)	r4r5r6rrUrjr1rorprrrrr_s

r_c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�LRUCacheNodezLRUCache node.
    cCs||_||_||_||_dS)N)rmrn�prev�next)rrmrnrrrrU�szLRUCacheNode.__init__cCs |j|_||_||j_||_dS)N)rrrs)r�noderrr�link_before�szLRUCacheNode.link_beforecCs ||_|j|_||j_||_dS)N)rrrs)rrtrrr�
link_after�szLRUCacheNode.link_aftercCs|j|j_|j|j_dS)N)rrrs)rrrr�unlink�s
zLRUCacheNode.unlinkN)r4r5r6rrUrurvrwrrrrrq�s
rqc@s<eZdZdZddd�Zdd�Zdd�Zd	d
�Zddd
�ZdS)�LRUCacheaOBounded least-recently-used DNS answer cache.

    This cache is better than the simple cache (above) if you're
    running a web crawler or other process that does a lot of
    resolutions.  The LRUCache has a maximum number of nodes, and when
    it is full, the least-recently used node is removed to make space
    for a new one.

    @ivar data: A dictionary of cached data
    @type data: dict
    @ivar sentinel: sentinel node for circular doubly linked list of nodes
    @type sentinel: LRUCacheNode object
    @ivar max_size: The maximum number of nodes
    @type max_size: int
    順cCs*i|_|j|�tdd�|_tj�|_dS)z�Initialize a DNS cache.

        @param max_size: The maximum number of nodes to cache; the default is
        100,000. Must be greater than 1.
        @type max_size: int
        N)ra�set_max_sizerq�sentinelrdrerf)r�max_sizerrrrU�s
zLRUCache.__init__cCs|dkrd}||_dS)Nr)r|)rr|rrrrz�szLRUCache.set_max_sizec
CslzZ|jj�|jj|�}|dkr$dS|j�|jjtj�krJ|j|j=dS|j	|j
�|jS|jj�XdS)a)Get the answer associated with I{key}.  Returns None if
        no answer is cached for the key.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @rtype: dns.resolver.Answer object or None
        N)rfrkrar1rwrnrRrQrmrvr{rl)rrmrtrrrr1�s

zLRUCache.getc
Cs�z�|jj�|jj|�}|dk	r2|j�|j|j=x.t|j�|jkr`|jj	}|j�|j|j=q4Wt
||�}|j|j�||j|<Wd|jj�XdS)aAssociate key and value in the cache.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @param value: The answer being cached
        @type value: dns.resolver.Answer object
        N)
rfrkrar1rwrmrr|r{rrrqrvrl)rrmrnrtrrrro�s


zLRUCache.putNc
Cs�zr|jj�|dk	r<|jj|�}|dk	rp|j�|j|j=n4|jj}x$||jkrh|j}d|_d|_|}qFWi|_Wd|jj	�XdS)z�Flush the cache.

        If I{key} is specified, only that item is flushed.  Otherwise
        the entire cache is flushed.

        @param key: the key to flush
        @type key: (dns.name.Name, int, int) tuple or None
        N)
rfrkrar1rwrmr{rsrrrl)rrmrtrsrrrrp�s	

zLRUCache.flush)ry)N)	r4r5r6rrUrzr1rorprrrrrx�s
rxc@s�eZdZdZd%dd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zejjejjddddfdd�Zdejjfdd �Zd!d"�Zd#d$�ZdS)&�Resolvera-DNS stub resolver

    @ivar domain: The domain of this host
    @type domain: dns.name.Name object
    @ivar nameservers: A list of nameservers to query.  Each nameserver is
    a string which contains the IP address of a nameserver.
    @type nameservers: list of strings
    @ivar search: The search list.  If the query name is a relative name,
    the resolver will construct an absolute query name by appending the search
    names one by one to the query name.
    @type search: list of dns.name.Name objects
    @ivar port: The port to which to send queries.  The default is 53.
    @type port: int
    @ivar timeout: The number of seconds to wait for a response from a
    server, before timing out.
    @type timeout: float
    @ivar lifetime: The total number of seconds to spend trying to get an
    answer to the question.  If the lifetime expires, a Timeout exception
    will occur.
    @type lifetime: float
    @ivar keyring: The TSIG keyring to use.  The default is None.
    @type keyring: dict
    @ivar keyname: The TSIG keyname to use.  The default is None.
    @type keyname: dns.name.Name object
    @ivar keyalgorithm: The TSIG key algorithm to use.  The default is
    dns.tsig.default_algorithm.
    @type keyalgorithm: string
    @ivar edns: The EDNS level to use.  The default is -1, no Edns.
    @type edns: int
    @ivar ednsflags: The EDNS flags
    @type ednsflags: int
    @ivar payload: The EDNS payload size.  The default is 0.
    @type payload: int
    @ivar flags: The message flags to use.  The default is None (i.e. not
    overwritten)
    @type flags: int
    @ivar cache: The cache to use.  The default is None.
    @type cache: dns.resolver.Cache object
    @ivar retry_servfail: should we retry a nameserver if it says SERVFAIL?
    The default is 'false'.
    @type retry_servfail: bool
    �/etc/resolv.confTcCs�d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_	d|_
d|_d|_d|_
d|_d|_d|_|j�|r�tjdkr�|j�n|r�|j|�dS)aJInitialize a resolver instance.

        @param filename: The filename of a configuration file in
        standard /etc/resolv.conf format.  This parameter is meaningful
        only when I{configure} is true and the platform is POSIX.
        @type filename: string or file object
        @param configure: If True (the default), the resolver instance
        is configured in the normal fashion for the operating system
        the resolver is running on.  (I.e. a /etc/resolv.conf file on
        POSIX systems and from the registry on Windows systems.)
        @type configure: boolNFr)�domain�nameservers�nameserver_ports�port�search�timeout�lifetime�keyring�keyname�keyalgorithm�edns�	ednsflags�payload�cache�flags�retry_servfail�rotate�reset�sys�platform�
read_registry�read_resolv_conf)r�filenameZ	configurerrrrU9s.


zResolver.__init__cCs�tjjtjjtj��dd��|_t|j�dkr:tjj|_g|_	i|_
d|_g|_d|_
d|_d|_d|_tjj|_d|_d|_d|_d|_d|_d|_d|_dS)	z1Reset all resolver configuration to the defaults.rNr�5g@g>@Fr)rr*�Namer+�socket�gethostnamerr�rootr�r�r�r�r�r�r�r��tsig�default_algorithmr�r�r�r�r�r�r�r�)rrrrr�_s&"

zResolver.resetcCsZt|t�r<yt|d�}Wntk
r4dg|_dSXd}nd}z�x�|D]�}t|�dksH|ddksH|ddkrrqH|j�}t|�d	kr�qH|dd
kr�|jj|d�qH|ddkr�tj	j
|d�|_qH|dd
k�rxL|dd�D]}|jjtj	j
|��q�WqH|ddkrHd|dd�krHd|_
qHWWd|�r8|j�Xt|j�dk�rV|jjd�dS)z�Process f as a file in the /etc/resolv.conf format.  If f is
        a string, it is used as the name of the file to open; otherwise it
        is treated as the file itself.�rz	127.0.0.1NTFr�#�;rC�
nameserverrrr�Zoptionsr�)r	r�open�IOErrorr�r�splitr2rr*r+rr�r��close)r�fZ
want_close�l�tokens�suffixrrrr�vs:

$
zResolver.read_resolv_confcCs0|jd�dkrd}n|jd�dkr(d}nd}|S)N� r�,)�find)r�entry�
split_charrrr�_determine_split_char�szResolver._determine_split_charcCsDt|�}|j|�}|j|�}x"|D]}||jkr"|jj|�q"WdS)z&Configure a NameServer registry entry.N)rr�r�r�r2)rr�r�Zns_list�nsrrr�_config_win32_nameservers�s



z"Resolver._config_win32_nameserverscCstjjt|��|_dS)z"Configure a Domain registry entry.N)rr*r+rr)rrrrr�_config_win32_domain�szResolver._config_win32_domaincCsLt|�}|j|�}|j|�}x*|D]"}||jkr"|jjtjj|��q"WdS)z"Configure a Search registry entry.N)rr�r�r�r2rr*r+)rr�r�Zsearch_list�srrr�_config_win32_search�s



zResolver._config_win32_searchc#Cs.ytj|d�\}}Wntk
r,d}YnX|rv|j|�y"tj|d�\}}|r\|j|�Wq�tk
rrYq�Xntytj|d�\}}Wntk
r�d}YnX|r�|j|�y"tj|d�\}}|r�|j|�Wntk
r�YnXytj|d�\}}Wntk
�rd}YnX|�r*|j|�dS)z%Extract DNS info from a registry key.Z
NameServerNZDomainZDhcpNameServerZ
DhcpDomainZ
SearchList)�_winreg�QueryValueEx�WindowsErrorr�r�r�)rrmZserversZrtypeZdomr�rrr�_config_win32_fromkey�s<




zResolver._config_win32_fromkeyc,Cstjdtj�}d}z�ytj|d�}d}Wn tk
rHtj|d�}YnXz|j|�Wd|j�X|r�tj|d�}ztd}xjyNtj||�}|d7}tj||�}|j|||�s�w|z|j|�Wd|j�XWq|tk
r�PYq|Xq|WWd|j�XWd|j�XdS)	z9Extract resolver configuration from the Windows registry.NFz2SYSTEM\CurrentControlSet\Services\Tcpip\ParametersTz+SYSTEM\CurrentControlSet\Services\VxD\MSTCPz=SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfacesrr)	r�ZConnectRegistry�HKEY_LOCAL_MACHINE�OpenKey�EnvironmentErrorr��CloseZEnumKey�_win32_is_nic_enabled)r�lmZ	want_scanZ
tcp_paramsZ
interfacesr\�guidrmrrrr��s@
zResolver.read_registryc
Cs�y�tj|d|�}zftj|d�\}}|tjkr2t�tj|d|�}z(tj|d�\}}|tjkrbt�|d@S|j�XWd|j�XWnFttfk
r�ytj|d�\}	}|	dk	Stk
r�dSXYnXdS)Nz]SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\%s\ConnectionZ
PnpInstanceIDz SYSTEM\CurrentControlSet\Enum\%sZConfigFlagsrZNTEContextListF)	r�r�r�ZREG_SZ�
ValueErrorZ	REG_DWORDr�r�r�)
rr�r�Z
interface_keyZconnection_keyZpnp_idZttypeZ
device_keyr�Znterrrr�s6



zResolver._win32_is_nic_enabledcCsVtj�}||}|dkr0|dkr,t|d��n|}||jkrDt|d��t|j||j�S)Nrr)r�r)rQ�Timeoutr��minr�)r�startrgZdurationrrr�_compute_timeoutMs

zResolver._compute_timeoutFNrcCst|t�rtjj|d�}t|t�r.tjj|�}tjj|�r>t�t|t�rTtjj|�}tjj	|�rdt�g}|j
�r||j|�nZt|�dkr�|j|j
tjj��|jr�x2|jD]}	|j|j
|	��q�Wn|j|j
|j��d}
i}tj�}d}
�x�|D�]�}
|j�r@|jj|
||f�}|dk	�r@|jdk�r<|�r<t|jd��n|Stjj|
||�}|jdk	�rr|j|j|j|jd�|j|j|j|j �|j!dk	�r�|j!|_!d}|j"dd�}g}|j#�r�t$j%|�d}�x�|dk�r�t|�dk�r�t&||d���x`|dd�D�]N}|j'|�}|j(j||j)�}yx|}|�rDtj*j+||||||d	�}nNtj*j,||||||d	�}|j!tj!j-@�r�d}|j'|�}tj*j+||||||d	�}W�n t.j/tj0j1fk
�r�}z"|j|||||f�d}�w�WYdd}~Xn�tj*j2k
�r"}z"|j|||||f�d}�w�WYdd}~Xn�tj0j3k
�rn}z,|j4|�|j|||||f�d}�w�WYdd}~XnJt5k
�r�}z,|j4|�|j|||||f�d}�w�WYdd}~XnX|j6�}|tj6j7k�r�t7�}|j|||||f�|�|tj6j8k�s|tj6j9k�r
P|tj6j:k�s"|j;�r,|j4|�|j|||tj6j<|�|f�d}�q�W|dk	�r^Pt|�dk�r�|j'|�}t=||�}|d
9}tj>|��q�W|j6�tj6j9k�r�|||
<q�d}
Pq�W|
�r�t9||d��t?|
||||�}|j�r�|jj@|
||f|�|S)
aQuery nameservers to find the answer to the question.

        The I{qname}, I{rdtype}, and I{rdclass} parameters may be objects
        of the appropriate type, or strings that can be converted into objects
        of the appropriate type.  E.g. For I{rdtype} the integer 2 and the
        the string 'NS' both mean to query for records with DNS rdata type NS.

        @param qname: the query name
        @type qname: dns.name.Name object or string
        @param rdtype: the query type
        @type rdtype: int or string
        @param rdclass: the query class
        @type rdclass: int or string
        @param tcp: use TCP to make the query (default is False).
        @type tcp: bool
        @param source: bind to this IP address (defaults to machine default
        IP).
        @type source: IP address in dotted quad notation
        @param raise_on_no_answer: raise NoAnswer if there's no answer
        (defaults is True).
        @type raise_on_no_answer: bool
        @param source_port: The port from which to send the message.
        The default is 0.
        @type source_port: int
        @rtype: dns.resolver.Answer instance
        @raises Timeout: no answers could be found in the specified lifetime
        @raises NXDOMAIN: the query name does not exist
        @raises YXDOMAIN: the query name is too long after DNAME substitution
        @raises NoAnswer: the response did not contain an answer and
        raise_on_no_answer is True.
        @raises NoNameservers: no non-broken nameservers are available to
        answer the question.NrT)r.)�	algorithmg�������?r)rArB)�source�source_portrCF)rr)Ar	rrr*r+r"Zis_metatyperHr Zis_metaclass�is_absoluter2rZconcatenater�r�rrQr�r1rMr<r.�messageZ
make_queryr��use_tsigr�r��use_ednsr�r�r�r�r�r��randomZshuffler@r�r�r�r=�tcp�udpZTCr��error�	exceptionr�ZUnexpectedSourceZ	FormError�remove�EOFError�rcoder;ZNOERRORrZSERVFAILr�r)r�ZsleeprIro)rr-r%r&r�r�rSr�Z
qnames_to_tryr�Zall_nxdomainZnxdomain_responsesr�Z_qnamer$rAr.r�rBZbackoffr�r�r�Ztcp_attemptZexr�Z
sleep_timerrrr=]s�#




















zResolver.querycCs4||_|dkr$t|jj��d|_n||_||_dS)a�Add a TSIG signature to the query.

        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @param algorithm: The TSIG key algorithm to use.  The default
        is dns.tsig.default_algorithm.
        @type algorithm: stringNr)r�r
�keysr�r�)rr�r�r�rrrr�"s
zResolver.use_tsigcCs"|dkrd}||_||_||_dS)aConfigure Edns.

        @param edns: The EDNS level to use.  The default is -1, no Edns.
        @type edns: int
        @param ednsflags: The EDNS flags
        @type ednsflags: int
        @param payload: The EDNS payload size.  The default is 0.
        @type payload: intNrr)r�r�r�)rr�r�r�rrrr�8s

zResolver.use_ednscCs
||_dS)z�Overrides the default flags with your own

        @param flags: The flags to overwrite the default with
        @type flags: intN)r�)rr�rrr�	set_flagsHszResolver.set_flags)r~T)r4r5r6rrUr�r�r�r�r�r�r�r�r�r�rr"�Ar r!r=r�r�r�r�r�rrrrr}s&+
&)

"-7Er}cCstdkrt�tS)z7Get the default resolver, initializing it if necessary.N)�default_resolver�reset_default_resolverrrrr�get_default_resolverRsr�cCs
t�adS)zSRe-initialize default resolver.

    resolv.conf will be re-read immediatelly.
    N)r}r�rrrrr�Ysr�FTcCst�j|||||||�S)z�Query nameservers to find the answer to the question.

    This is a convenience function that uses the default resolver
    object to make the query.
    @see: L{dns.resolver.Resolver.query} for more information on the
    parameters.)r�r=)r-r%r&r�r�rSr�rrrr=bs	r=cCs�t|t�rtjj|tjj�}|dkr*t�}|j�s:t|��xxy(|j	|tj
j||�}|jj|krb|SWn tj
jtj
jfk
r�YnXy|j�}Wq<tjjk
r�t�Yq<Xq<WdS)a�Find the name of the zone which contains the specified name.

    @param name: the query name
    @type name: absolute dns.name.Name object or string
    @param rdclass: The query class
    @type rdclass: int
    @param tcp: use TCP to make the query (default is False).
    @type tcp: bool
    @param resolver: the resolver to use
    @type resolver: dns.resolver.Resolver object or None
    @rtype: dns.name.NameN)r	rrr*r+r�r�r�rFr=r"rNrM�resolverrr<rOrPrG)r*r&r�r�r$rrr�
zone_for_nameos"
r�c,Cs�|tjtjB@dkrt�|dkr4|dkr4tjtj��g}g}d}y�|dkr�d}|tj@dkrr|jd�|jd�q�|jd�|jd�n>|jd�}	t	|	�dkr�|	d}
n|}
t
jj|
�}|j|�|}W�npt
k
�r:y t
jj|�}|j|�|}W�n8t
k
�r4|tj@dk�r0y�|tjk�s8|tjk�r�tj|t
jjd	d
�}|j}|jjd�}|jdk	�r�x|jD]}
|j|
j��qrW|tjk�s�|tjk�r�tj|t
jjd	d
�}|j}|jjd�}|jdk	�r�x|jD]}
|j|
j��q�WWn<t
jjk
�rtjtj��Yntjtj��YnXYnXYnXd}y|dk�rRd}nt |�}WnLt
k
�r�|tj!@dk�r�ytj"|�}Wnt
k
�r�YnXYnX|dk�r�tjtj��g}|dk�r�tj#tj$g}n|g}|tj%@dk�r�|}nd}|tjk�s|tjk�rfxP|D]H}x@|D]8}x0t&|D]$}|jtj|||||ddff��q2W�q$W�qW|tjk�s~|tjk�r�xL|D]D}x<|D]4}x,t&|D] }|jtj|||||ff��q�W�q�W�q�Wt	|�dk�r�tjtj��|S)
NrZ	localhostz::z0.0.0.0z::1z	127.0.0.1�%rCF)rST�)'r�Z
AI_ADDRCONFIGZAI_V4MAPPED�NotImplementedError�gaierror�
EAI_NONAMEZ
AI_PASSIVEr2r�rr�ipv6�	inet_aton�	ExceptionZipv4ZAI_NUMERICHOST�AF_INET6�	AF_UNSPEC�	_resolverr=r"ZAAAAr-r/r)rMZaddress�AF_INETr�r�rZ
EAI_SYSTEM�intZAI_NUMERICSERVZ
getservbyname�
SOCK_DGRAM�SOCK_STREAM�AI_CANONNAME�_protocols_for_socktype)�host�service�familyZsocktype�protor�Zv6addrsZv4addrsr/�partsZahost�addrZv6ZrdataZv4r��tuplesZ	socktypesr,rrr�_getaddrinfo�s�












$

 r�c
Csf|d}|d}t|�dkr,|d}tj}n
d}tj}t|||tjtjd�}t|�dkrbtjd��|ddd}|tj@r�d}nd}t	j
j|�}	|tj@dk�ry"t
j|	d�}
|
jdjjd	�}WnVt	jjt	jjfk
�r|tj@r�tjtj��|}|dk	�r|d
t|�7}YnXn|}|dk	�r<|d
t|�7}|tj@�rRt|�}ntj||�}||fS)Nrr�rDz'sockaddr resolved to multiple addressesr�r�ZPTRTr�)rr�r�r�r�r��SOL_TCPr�ZNI_DGRAMrZreversenameZfrom_addressZNI_NUMERICHOSTr�r=rMr(r)r�rr<�NI_NAMEREQDr�r�rZNI_NUMERICSERVZ
getservbyport)
�sockaddrr�r�r�Zscoper�r�r�Zpnamer-r$Zhostnamer�rrr�_getnameinfosB






r�cCsD|dkrtj�}ytt|d�dd�dStk
r>|SXdS)N�Prr�)r�r�r�r�r�)r*rrr�_getfqdn.sr�cCst|�ddS)NrCr)�_gethostbyname_ex)r*rrr�_gethostbyname7sr�cCsXg}g}t|dtjtjtjtj�}|dd}x|D]}|j|dd�q4W|||fS)NrrDr�)r�r�r�r�r�r�r2)r*�aliases�	addressesr��	canonical�itemrrrr�;s
r�c
Cs�y"tjj|�|dddf}tj}Wn"tk
rD|df}tj}YnXt|tj�\}}g}g}t	|d|tj
tjtj�}|dd}x|D]}	|j
|	dd�q�W|||fS)Nr�rrDr�)rr�r�r�r�r�r�r�r�r�r�r�r�r2)
Zipr�r�r*r�r�r�r�r�rrrr�_gethostbyaddrGs 

rcCs:|dkrt�}|att_tt_tt_t	t_
tt_t
t_dS)a�Override the system resolver routines in the socket module with
    versions which use dnspython's resolver.

    This can be useful in testing situations where you want to control
    the resolution behavior of python code without having to change
    the system's resolver settings (e.g. /etc/resolv.conf).

    The resolver to use may be specified; if it's not, the default
    resolver will be used.

    @param resolver: the resolver to use
    @type resolver: dns.resolver.Resolver object or None
    N)r�r�r�r��getaddrinfor��getnameinfor��getfqdnr��
gethostbynamer��gethostbyname_exr�
gethostbyaddr)r�rrr�override_system_resolver[srcCs,datt_tt_tt_tt_	t
t_tt_
dS)z4Undo the effects of override_system_resolver().
    N)r��_original_getaddrinfor�r�_original_getnameinfor�_original_getfqdnr�_original_gethostbynamer�_original_gethostbyname_exr�_original_gethostbyaddrrrrrr�restore_system_resolverusr)r)N)N)Prr�r�rQr�Z	threadingrd�ImportErrorZdummy_threadingZ
dns.exceptionrZ	dns.flagsZdns.ipv4Zdns.ipv6Zdns.messageZdns.nameZ	dns.queryZ	dns.rcodeZdns.rdataclassZ
dns.rdatatypeZdns.reversenameZdns.tsigZ_compatrrr��winregr�r�ZDNSExceptionrr;r�r<r@rFrGrH�objectrIr_rqrxr}r�r�r�r"r�r r!r=r�r�ZSOL_UDPr�r�r�r�rr	rr
rrrrrr
rrr�r�r�r�r�r�rrrrrrr�<module>s�
<sboG	&

c
(
	
PKi�\��M�(($__pycache__/ttl.cpython-36.opt-1.pycnu�[���3

�b�W��@s8dZddlZddlmZGdd�dejj�Zdd�ZdS)	zDNS TTL conversion.�N�)�longc@seZdZdZdS)�BadTTLz!DNS TTL value is not well-formed.N)�__name__�
__module__�__qualname__�__doc__�r	r	�/usr/lib/python3.6/ttl.pyrsrcCs*|j�rt|�}n�|dj�s"t�td�}td�}x�|D]�}|j�rZ|d9}|t|�7}q8|j�}|dkr|||td�7}nl|dkr�||td�7}nR|dkr�||td�7}n8|d	kr�||td
�7}n|dkr�||7}ntd|��d}q8W|dk�std
��|td�k�s|td�k�r&td��|S)z�Convert the text form of a TTL to an integer.

    The BIND 8 units syntax for TTLs (e.g. '1w6d4h3m10s') is supported.

    @param text: the textual TTL
    @type text: string
    @raises dns.ttl.BadTTL: the TTL is not well-formed
    @rtype: int
    r�
�wi�:	�di�Q�hi�m�<�szunknown unit '%s'ztrailing integeri���z0TTL should be between 0 and 2^31 - 1 (inclusive))�isdigitrr�lower)�textZtotalZcurrent�cr	r	r
�	from_texts8



r)	rZ
dns.exceptionZdnsZ_compatrZ	exception�SyntaxErrorrrr	r	r	r
�<module>sPKi�\J,���*�*!__pycache__/dnssec.cpython-36.pycnu�[���3

�b�W�9�@sHdZddlmZddlZddlZddlZddlZddlZddl	Zddl
ZddlZddlZddl
ZddlmZGdd�dejj�ZGdd	�d	ejj�ZdZd
ZdZdZd
ZdZdZdZdZdZdZdZdZ dZ!eeeeeeeeeeeee e!d�Z"e#dd�e"j$�D��Z%dd�Z&dd�Z'dd�Z(dDd d!�Z)dEd"d#�Z*d$d%�Z+d&d'�Z,d(d)�Z-d*d+�Z.d,d-�Z/d.d/�Z0d0d1�Z1d2d3�Z2d4d5�Z3d6d7�Z4d8d9�Z5dFd:d;�Z6dGd<d=�Z7d>d?�Z8y(ddl9Z:ddl;Z:ddl<Z:e7Z=e6Z>d@Z?Wn"e@k
�r�e8Z=e8Z>dAZ?YnXy8ddlAZAddlBZAddlCZAddlDZAd@ZEGdBdC�dCeF�ZGWne@k
�rBdAZEYnXdS)Hz.Common DNSSEC-related functions and constants.�)�BytesION�)�string_typesc@seZdZdZdS)�UnsupportedAlgorithmz&The DNSSEC algorithm is not supported.N)�__name__�
__module__�__qualname__�__doc__�r
r
�/usr/lib/python3.6/dnssec.pyr!src@seZdZdZdS)�ValidationFailurez The DNSSEC signature is invalid.N)rrrr	r
r
r
rr&sr��������
�
����)�RSAMD5�DH�DSA�ECC�RSASHA1�DSANSEC3SHA1�RSASHA1NSEC3SHA1�	RSASHA256�	RSASHA512�INDIRECT�ECDSAP256SHA256�ECDSAP384SHA384�
PRIVATEDNS�
PRIVATEOIDccs|]\}}||fVqdS)Nr
)�.0�x�yr
r
r�	<genexpr>Nsr+cCs"tj|j��}|dkrt|�}|S)z:Convert text into a DNSSEC algorithm value
    @rtype: intN)�_algorithm_by_text�get�upper�int)�text�valuer
r
r�algorithm_from_textQsr2cCstj|�}|dkrt|�}|S)z;Convert a DNSSEC algorithm value to text
    @rtype: stringN)�_algorithm_by_valuer-�str)r1r0r
r
r�algorithm_to_text[s
r5cCst�}|j||d�|j�S)N)�origin)r�to_wire�getvalue)�recordr6�sr
r
r�	_to_rdataesr;cCs�t||�}t|�}|jtkr0|dd>|d	Sd}x<tt|�d�D](}||d|d>|d|d7}qFWt|�ddkr�||t|�dd>7}||d?d@7}|d@SdS)
Nrrr
rr�i��������)r;�	bytearray�	algorithmr�range�len)�keyr6�rdataZtotal�ir
r
r�key_idks

rFcCs�|j�dkr d}tjjd�}n,|j�dkr@d}tjjd�}ntd|��t|t�rdtjj||�}|j	|j
�j��|j	t||��|j
�}tjdt|�|j|�|}tjjtjjtjj|dt|��S)N�SHA1r�SHA256r
zunsupported algorithm "%s"z!HBBr)r.�dns�hash�hashesr�
isinstancer�name�	from_text�updateZcanonicalizer7r;�digest�struct�packrFr@rDZ	from_wire�
rdataclass�IN�	rdatatypeZDSrB)rMrCr@r6ZdsalgrJrPZdsrdatar
r
r�make_ds{s
rVcCs�g}|j|j�}|dkrdSt|tjj�rZy|jtjjtj	j
�}Wq^tk
rVdSXn|}x0|D](}|j|jkrdt
|�|jkrd|j|�qdW|S)N)r-�signerrLrIZnodeZNodeZ
find_rdatasetrSrTrUZDNSKEY�KeyErrorr@rFZkey_tag�append)�keys�rrsigZcandidate_keysr1�rdatasetrDr
r
r�_find_candidate_keys�s 

r]cCs|tttttfkS)N)rrr r!r")r@r
r
r�_is_rsa�sr^cCs|ttfkS)N)rr)r@r
r
r�_is_dsa�sr_cCsto|ttfkS)N)�_have_ecdsar$r%)r@r
r
r�	_is_ecdsa�sracCs|tkS)N)r)r@r
r
r�_is_md5�srbcCs|ttttfkS)N)rrrr )r@r
r
r�_is_sha1�srccCs|ttfkS)N)r!r$)r@r
r
r�
_is_sha256�srdcCs|tkS)N)r%)r@r
r
r�
_is_sha384�srecCs|tkS)N)r")r@r
r
r�
_is_sha512�srfcCs~t|�rtjjd�St|�r,tjjd�St|�rBtjjd�St|�rXtjjd�St|�rntjjd�Std|��dS)NZMD5rGrHZSHA384ZSHA512zunknown hash for algorithm %u)	rbrIrJrKrcrdrerfr)r@r
r
r�
_make_hash�srgc	Cs�t|�rddddddddg}ndt|�r6dd	d
ddg}nLt|�rVdddd
dd
ddd
g	}n,t|�rvdddd
dd
ddd
g	}ntd|��t|�}t|�j}dgd||gd|dgd|g|ddgd|g}tj	dt|�f|��S)N�*��H�rr
r�+rr��`r�erzunknown algorithm %u�0rrrz!%dB)
rbrcrdrfrrBrgZdigest_sizerQrR)r@ZoidZolenZdlenZidbytesr
r
r�_make_algorithm_id�s
<rqc)Cst|t�rtjj|tjj�}�x�t||�D�]�}|s<td��t|t�rX|d}|d}n
|j}|}|dkrrt	j	�}|j
|kr�td��|j|kr�td��t|j
�}t|j
��r`|j}	tjd|	dd��\}
|	dd�}	|
dk�rtjd|	dd	��\}
|	d	d�}	|	d|
�}|	|
d�}t|�d
}
tjjjtjjj|�tjjj|�f�}tjjj|j�f}�n t|j
��rl|j}	tjd|	dd��\}|	dd�}	d|d
}|	dd�}|	dd�}	|	d|�}|	|d�}	|	d|�}|	|d�}	|	d|�}tjjjtjjj|�tjjj|�tjjj|�tjjj|�f�}tjd
|jdd��\}}tjjj|�tjjj|�f}�nt|j
��rr|j
tk�r�tj j!}d}n"|j
t"k�r�tj j#}d}ntd��|j}	tjjj|	d|��}tjjj|	||d	��}tjj$|j%||��st&�tj'j(|j)|||j*�}tj+j,j-||�}t.||�}|jd|�}|j|d�}tjj/tjjj|�tjjj|��}ntd|j
��|j0t1||�dd��|j0|j2j3|��|j4t|�dk�r�|j5|j4d�d} tjjd| �}|j3|�}!tj6d|j7|j8|j9�}"t:|�}#xP|#D]H}$|j0|!�|j0|"�|$j3|�}%tj6dt|%��}&|j0|&�|j0|%��qW|j;�}'t|j
��r�t<|j
�|'}'|
d
t|'�d}(tj6dd	|(dfddgdg|(dg��|'}'n(t|j
��s�t|j
��r�ntd|j
��|j=|'|�r*dSq*Wtd��dS)a�Validate an RRset against a single signature rdata

    The owner name of the rrsig is assumed to be the same as the owner name
    of the rrset.

    @param rrset: The RRset to validate
    @type rrset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param rrsig: The signature rdata
    @type rrsig: dns.rrset.Rdata
    @param keys: The key dictionary.
    @type keys: a dictionary keyed by dns.name.Name with node or rdataset
    values
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name or None
    @param now: The time to use when validating the signatures.  The default
    is the current time.
    @type now: int
    zunknown keyrrNZexpiredz
not yet validz!Bz!Hr
r�@�z!20s20s� rpzunknown ECDSA curvezunknown algorithm %u��*z!HHIrz!%dB�zverify failure)>rLrrIrMrN�rootr]r�tuple�timeZ
expirationZ	inceptionrgr@r^rCrQ�unpackrB�CryptoZ	PublicKeyZRSAZ	construct�Util�number�
bytes_to_longZ	signaturer_rrar$�ecdsaZcurvesZNIST256pr%ZNIST384pZpoint_is_valid�	generator�AssertionErrorZ
ellipticcurveZPoint�curve�orderrZZVerifyingKeyZfrom_public_point�ECKeyWrapperZ	SignaturerOr;rWZ
to_digestableZlabels�splitrRZrdtypeZrdclassZoriginal_ttl�sortedrPrq�verify))�rrsetr[rZr6�nowZ
candidate_key�rrnamer\rJZkeyptrZbytes_Zrsa_eZrsa_nZkeylen�pubkey�sig�tZoctetsZdsa_qZdsa_pZdsa_gZdsa_yZdsa_rZdsa_sr��key_lenr)r*ZpointZ
verifying_key�rr:�suffixZ	rrnamebufZrrfixedZrrlistZrrZrrdataZrrlenrPZpadlenr
r
r�_validate_rrsig�s�














"r�c	
Cs�t|t�rtjj|tjj�}t|t�r0|d}n|j}t|t�rR|d}|d}n
|j}|}|j|�}|j|�}||kr�td��x6|D].}yt	|||||�dStk
r�Yq�Xq�Wtd��dS)ahValidate an RRset

    @param rrset: The RRset to validate
    @type rrset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param rrsigset: The signature RRset
    @type rrsigset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param keys: The key dictionary.
    @type keys: a dictionary keyed by dns.name.Name with node or rdataset
    values
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name or None
    @param now: The time to use when validating the signatures.  The default
    is the current time.
    @type now: int
    rrzowner names do not matchNzno RRSIGs validated)
rLrrIrMrNrxryZchoose_relativityrr�)	r�ZrrsigsetrZr6r�r�Z	rrsignameZ
rrsigrdatasetr[r
r
r�	_validatexs*








r�cOstd��dS)Nz#DNSSEC validation requires pycrypto)�NotImplementedError)�args�kwargsr
r
r�_need_pycrypto�sr�TFc@seZdZdd�Zdd�ZdS)r�cCs||_||_dS)N)rCr�)�selfrCr�r
r
r�__init__�szECKeyWrapper.__init__cCstjjj|�}|jjj||�S)N)r|r}r~rrCr�Zverifies)r�rPr�Zdiglongr
r
rr��szECKeyWrapper.verifyN)rrrr�r�r
r
r
rr��sr�)N)N)NN)NN)Hr	�iorrQrzZ
dns.exceptionrIZdns.hashZdns.nameZdns.nodeZdns.rdatasetZ	dns.rdataZ
dns.rdatatypeZdns.rdataclassZ_compatrZ	exceptionZDNSExceptionrrrrrrrrr r!r"r$r%r#r&r'r,�dict�itemsr3r2r5r;rFrVr]r^r_rarbrcrdrerfrgrqr�r�r�ZCrypto.PublicKey.RSAr|ZCrypto.PublicKey.DSAZCrypto.Util.numberZvalidateZvalidate_rrsigZ_have_pycrypto�ImportErrorr�Zecdsa.ecdsaZecdsa.ellipticcurveZ
ecdsa.keysr`�objectr�r
r
r
r�<module>s�





0

PKj�\]��)zz&__pycache__/flags.cpython-36.opt-1.pycnu�[���3

�b�Wh
�@s�dZdZdZdZdZdZdZdZdZeeeeeeed�Z	d	eiZ
ed
d�e	j�D��Z
edd�e
j�D��Zd
d�Zee
�Zee�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�ZdS)zDNS Message Flags.i�ii��� �)�QR�AA�TC�RD�RA�AD�CD�DOccs|]\}}||fVqdS)N�)�.0�x�yr
r
�/usr/lib/python3.6/flags.py�	<genexpr>3srccs|]\}}||fVqdS)Nr
)rrrr
r
rr5scCs t|j��}|j�|j�|S)N)�list�items�sort�reverse)�table�orderr
r
r�_order_flags8srcCs.d}|j�}x|D]}|||j�B}qW|S)N�)�split�upper)�textr�flags�tokens�tr
r
r�
_from_textCs

r!cCs6g}x&|D]\}}||@dkr
|j|�q
Wdj|�S)Nr� )�append�join)rrrZ
text_flags�k�vr
r
r�_to_textKs
r'cCs
t|t�S)zZConvert a space-separated list of flag text values into a flags
    value.
    @rtype: int)r!�_by_text)rr
r
r�	from_textSsr)cCst|tt�S)z]Convert a flags value into a space-separated list of flag text
    values.
    @rtype: string)r'�	_by_value�_flags_order)rr
r
r�to_text[sr,cCs
t|t�S)zdConvert a space-separated list of EDNS flag text values into a EDNS
    flags value.
    @rtype: int)r!�
_edns_by_text)rr
r
r�edns_from_textcsr.cCst|tt�S)zhConvert an EDNS flags value into a space-separated list of EDNS flag
    text values.
    @rtype: string)r'�_edns_by_value�_edns_flags_order)rr
r
r�edns_to_textksr1N)�__doc__rrrrr	r
rrr(r-�dictrr*r/rr+r0r!r'r)r,r.r1r
r
r
r�<module>s6PKj�\pJ�ն�!__pycache__/update.cpython-36.pycnu�[���3

�b�W'�@s`dZddlZddlZddlZddlZddlZddlZddlZddl	m
Z
Gdd�dejj�Z
dS)zDNS Dynamic Update Support�N�)�string_typescsxeZdZejjddejjf�fdd�	Zddd�Z	dd�Z
dd	�Zd
d�Zdd
�Z
dd�Zddd�Zd�fdd�	Z�ZS)�UpdateNcs�tt|�j�|jtjjtjj�O_t|t	�r>tj
j|�}||_t|t	�rZtj
j|�}||_|j|j|j|tjjddd�|dk	r�|j|||d�dS)a�Initialize a new DNS Update object.

        @param zone: The zone which is being updated.
        @type zone: A dns.name.Name or string
        @param rdclass: The class of the zone; defaults to dns.rdataclass.IN.
        @type rdclass: An int designating the class, or a string whose value
        is the name of a class.
        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @type keyname: dns.name.Name or string
        @param keyalgorithm: The TSIG algorithm to use; defaults to
        dns.tsig.default_algorithm.  Constants for TSIG algorithms are defined
        in dns.tsig, and the currently implemented algorithms are
        HMAC_MD5, HMAC_SHA1, HMAC_SHA224, HMAC_SHA256, HMAC_SHA384, and
        HMAC_SHA512.
        @type keyalgorithm: string
        T)ZcreateZforce_uniqueN)�	algorithm)�superr�__init__�flags�dnsZopcodeZto_flagsZUPDATE�
isinstancer�name�	from_text�origin�
rdataclass�zone_rdclass�
find_rrsetZquestion�	rdatatypeZSOAZuse_tsig)�selfZzoneZrdclassZkeyringZkeynameZkeyalgorithm)�	__class__��/usr/lib/python3.6/update.pyrs


zUpdate.__init__c	CsB|dkr|j}|j�}|j|||j|j||dd�}|j||�dS)z&Add a single RR to the update section.NT)�	authority�coversrr�rdtype�add)rr�ttl�rdZdeleting�sectionrZrrsetrrr�_add_rrEszUpdate._add_rrc
Gs:t|t�rtjj|d�}t|dtjj�rnx@|D]8}|rF|j||j�x |D]}|j	||j
||d�qLWq0Wn�t|�}t|j
d��}t|dtjj�r�|r�|j||dj�x�|D]}|j	||||d�q�Wnh|j
d�}t|t�r�tjj|�}|r�|j||�x6|D].}	tjj|j||	|j�}|j	||||d��qWdS)a�Add records.  The first argument is the replace mode.  If
        false, RRs are added to an existing RRset; if true, the RRset
        is replaced with the specified contents.  The second
        argument is the section to add to.  The third argument
        is always a name.  The other arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string...Nr)r)r
rr	rr�rdataset�Rdataset�deleterrr�list�int�pop�rdata�Rdatarrr
)
r�replacerr�args�rdsrrr�srrr�_addOs0






zUpdate._addcGs|jd|j|f|��dS)z�Add records.  The first argument is always a name.  The other
        arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string...FN)r*r)rrr'rrrrws	z
Update.addc	Gsft|t�rtjj|d�}t|�dkrR|j|j|tjj	tj
j	tj
jtj
j	dd��nt|dtjj
�r�x�|D]&}x |D]}|j|d|tjj�qtWqjWn�t|�}t|dtjj�r�x�|D]}|j|d|tjj�q�Wn�|jd�}t|t�r�tj
j|�}t|�dk�r(|j|j||j|tj
jtjj	dd�n:x8|D]0}tjj|j|||j�}|j|d|tjj��q.WdS)z�Delete records.  The first argument is always a name.  The other
        arguments can be:

                - I{nothing}

                - rdataset...

                - rdata...

                - rdtype, [string...]NrT)r
rr	rr�lenrrr�ANYr�NONErrrr!r$r%r#rr
)rrr'r(rrr)rrrr �s6








z
Update.deletecGs|jd|j|f|��dS)aQReplace records.  The first argument is always a name.  The other
        arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string...

        Note that if you want to replace the entire node, you should do
        a delete of the name followed by one or more calls to add.TN)r*r)rrr'rrrr&�s
zUpdate.replacec	Gs�t|t�rtjj|d�}t|�dkrL|j|j|tjj	tj
j	tj
jddd�n�t|dtjj
�s|t|dtjj�s|t|�dkr�t|dtjj
�s�t|�}|jdd�|jd|j|f|��n@|d}t|t�r�tj
j|�}|j|j|tjj	|tj
jddd�dS)aBRequire that an owner name (and optionally an rdata type,
        or specific rdataset) exists as a prerequisite to the
        execution of the update.  The first argument is always a name.
        The other arguments can be:

                - rdataset...

                - rdata...

                - rdtype, string...NrTrF)r
rr	rrr+r�answerrr,rr-rrr$r%r!�insertr*)rrr'rrrr�present�s*




zUpdate.presentc	Cs�t|t�rtjj|d�}|dkrH|j|j|tjjtj	j
tj	jddd�n8t|t�r^tj	j|�}|j|j|tjj|tj	jddd�dS)z�Require that an owner name (and optionally an rdata type) does
        not exist as a prerequisite to the execution of the update.NT)r
rr	rrrr.rr-rr,)rrrrrr�absent�s




z
Update.absent�cs |dkr|j}tt|�j||�S)zcReturn a string containing the update in DNS compressed wire
        format.
        @rtype: stringN)r
rr�to_wire)rr
Zmax_size)rrrr3�szUpdate.to_wire)NN)N)Nr2)�__name__�
__module__�__qualname__r	r�INZtsigZdefault_algorithmrrr*rr r&r0r1r3�
__classcell__rr)rrrs%

(+$
r)�__doc__Zdns.messager	Zdns.nameZ
dns.opcodeZ	dns.rdataZdns.rdataclassZdns.rdatasetZdns.tsigZ_compatr�messageZMessagerrrrr�<module>sPKj�\A��'__pycache__/opcode.cpython-36.opt-1.pycnu�[���3

�b�W�	�@s�dZddlZdZdZdZdZdZeeeeed�Ze	dd	�ej
�D��ZGd
d�dejj
�Zdd
�Zdd�Zdd�Zdd�Zdd�ZdS)zDNS Opcodes.�N����)�QUERY�IQUERY�STATUS�NOTIFY�UPDATEccs|]\}}||fVqdS)N�)�.0�x�yrr�/usr/lib/python3.6/opcode.py�	<genexpr>&src@seZdZdZdS)�
UnknownOpcodezAn DNS opcode is unknown.N)�__name__�
__module__�__qualname__�__doc__rrrrr)srcCsB|j�r$t|�}|dkr$|dkr$|Stj|j��}|dkr>t�|S)z�Convert text into an opcode.

    @param text: the textual opcode
    @type text: string
    @raises UnknownOpcode: the opcode is unknown
    @rtype: int
    r�N)�isdigit�int�_by_text�get�upperr)�text�valuerrr�	from_text.s	rcCs|d@d?S)zUExtract an opcode from DNS message flags.

    @param flags: int
    @rtype: int
    ix�r)�flagsrrr�
from_flagsAsr!cCs|d>d@S)z`Convert an opcode to a value suitable for ORing into DNS message
    flags.
    @rtype: int
    rixr)rrrr�to_flagsKsr"cCstj|�}|dkrt|�}|S)z�Convert an opcode to text.

    @param value: the opcdoe
    @type value: int
    @raises UnknownOpcode: the opcode is unknown
    @rtype: string
    N)�	_by_valuer�str)rrrrr�to_textTs	
r%cCst|�tkS)znTrue if the opcode in flags is UPDATE.

    @param flags: DNS flags
    @type flags: int
    @rtype: bool
    )r!r
)r rrr�	is_updatecsr&)rZ
dns.exceptionZdnsrrrr	r
r�dict�itemsr#Z	exceptionZDNSExceptionrrr!r"r%r&rrrr�<module>s$
	PKj�\�M�����)__pycache__/resolver.cpython-36.opt-1.pycnu�[���3

>D�W���@s�dZddlZddlZddlZddlZyddlZWnek
rLddlZYnXddl	Z
ddlZ
ddlZ
ddl
Z
ddlZ
ddlZ
ddlZ
ddlZ
ddlZ
ddlZ
ddlZ
ddlZ
ddlmZmZejdkr�yddlZWnek
r�ddlZYnXGdd�de
jj�ZGdd	�d	e
jj�Ze
jj Z Gd
d�de
jj�Z!Gdd
�d
e
jj�Z"Gdd�de
jj�Z#Gdd�de
jj�Z$Gdd�de
jj�Z%Gdd�de&�Z'Gdd�de&�Z(Gdd�de&�Z)Gdd�de&�Z*Gdd�de&�Z+da,dd�Z-d d!�Z.e
j/j0e
j1j2d"dd#dfd$d%�Z3e
j1j2d"dfd&d'�Z4ej5ej6gej7ej8giZ9da:ej;Z<ej=Z>ej?Z@ejAZBejCZDejEZFddejGdddfd(d)�ZHd8d*d+�ZId9d,d-�ZJd.d/�ZKd0d1�ZLd2d3�ZMd:d4d5�ZNd6d7�ZOdS);z{DNS stub resolver.

@var default_resolver: The default resolver object
@type default_resolver: dns.resolver.Resolver object�N�)�xrange�string_types�win32csVeZdZdZeddg�ZdZddd�Z�fdd�Zd	d
�Z	e
e	dd�Z	d
d�Z�ZS)�NXDOMAINz"The DNS query name does not exist.�qnames�	responsesNcCs\t|tttf�std��t|�dkr,td��|dkr:i}nt|t�sLtd��t||d�}|S)Nz#qnames must be a list, tuple or setrz(qnames must contain at least one elementz(responses must be a dict(qname=response))rr)�
isinstance�list�tuple�set�AttributeError�len�dict)�selfrr�kwargs�r�/usr/lib/python3.6/resolver.py�
_check_kwargs9s
zNXDOMAIN._check_kwargscs^d|jkrtt|�j�S|jd}t|�dkr4d}n|jdd�}djtt|��}d||fS)NrrzNone of DNS query names existz, z%s: %s���)	r�superr�__str__r�__doc__�join�map�str)rr�msg)�	__class__rrrEs

zNXDOMAIN.__str__cCs�d|jkrtd��tjj}tjj}d}xj|jdD]\}|jd|}x4|jD]*}|j|ksL|j	|krfqL|j
djj�}qLW|dk	r2tj
j|�Sq2W|jddS)Nrzparametrized exception requiredrr)r�	TypeError�dns�
rdataclass�IN�	rdatatype�CNAME�answer�rdtype�rdclass�items�target�to_text�name�	from_text)rr!r#�cname�qname�responser$rrr�canonical_namePs
zNXDOMAIN.canonical_namez%Return the unresolved canonical name.)�doccCs|t|jjdg��}t|jjdi��}|jjdi�}x<|jjdg�D]*}||krX|j|�||krB||||<qBWt||d�S)z3Augment by results from another NXDOMAIN exception.rr)rr)r
r�getr�appendr)rZe_nxZqnames0Z
responses0Z
responses1Zqname1rrr�__add__bs
zNXDOMAIN.__add__)N)
�__name__�
__module__�__qualname__rr�supp_kwargs�fmtrrr/�propertyr3�
__classcell__rr)rrr3s
rc@seZdZdZdS)�YXDOMAINz8The DNS query name is too long after DNAME substitution.N)r4r5r6rrrrrr;osr;cs.eZdZdZdZedg�Z�fdd�Z�ZS)�NoAnswerz<The DNS response does not contain an answer to the question.z,The DNS response does not contain an answer zto the question: {query}r.cstt|�j|djd�S)Nr.)�query)rr<�_fmt_kwargs�question)rr)rrrr>�s
zNoAnswer._fmt_kwargszDThe DNS response does not contain an answer to the question: {query})	r4r5r6rr8rr7r>r:rr)rrr<zs

r<cs@eZdZdZdZdedd
�Zeddg�Z�fdd	�Z�Z	S)�
NoNameserversz�All nameservers failed to answer the query.

    errors: list of servers and respective errors
    The type of errors is
    [(server ip address, any object convertible to string)].
    Non-empty errors list will add explanatory message ()
    z+All nameservers failed to answer the query.z%s {query}: {errors}Nr�request�errorscsdg}x>|dD]2}|jd|d|dr*dnd|d|df�qWtt|�j|d	jd
j|�d�S)NrBz Server %s %s port %s answered %srrZTCPZUDP��rAz; )r=rB)r2rr@r>r?r)rrZsrv_msgs�err)rrrr>�s&
zNoNameservers._fmt_kwargsr)
r4r5r6rrr8rr7r>r:rr)rrr@�s
r@c@seZdZdZdS)�NotAbsolutezEAn absolute domain name is required but a relative name was provided.N)r4r5r6rrrrrrF�srFc@seZdZdZdS)�	NoRootSOAzBThere is no SOA RR at the DNS root name. This should never happen!N)r4r5r6rrrrrrG�srGc@seZdZdZdS)�
NoMetaqueriesz DNS metaqueries are not allowed.N)r4r5r6rrrrrrH�srHc@sBeZdZdZddd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dS)�Answera9DNS stub resolver answer

    Instances of this class bundle up the result of a successful DNS
    resolution.

    For convenience, the answer object implements much of the sequence
    protocol, forwarding to its rrset.  E.g. "for a in answer" is
    equivalent to "for a in answer.rrset", "answer[i]" is equivalent
    to "answer.rrset[i]", and "answer[i:j]" is equivalent to
    "answer.rrset[i:j]".

    Note that CNAMEs or DNAMEs in the response may mean that answer
    node's name might not be the query name.

    @ivar qname: The query name
    @type qname: dns.name.Name object
    @ivar rdtype: The query type
    @type rdtype: int
    @ivar rdclass: The query class
    @type rdclass: int
    @ivar response: The response message
    @type response: dns.message.Message object
    @ivar rrset: The answer
    @type rrset: dns.rrset.RRset object
    @ivar expiration: The time when the answer expires
    @type expiration: float (seconds since the epoch)
    @ivar canonical_name: The canonical name of the query name
    @type canonical_name: dns.name.Name object
    TcCs�||_||_||_||_d}d}x�tdd�D]�}y0|j|j|||�}|dksV|j|kr\|j}PWq,tk
�r|t	j
jkr�yJ|j|j||t	j
j�}	|dks�|	j|kr�|	j}x|	D]}
|
j}Pq�Ww,Wn"tk
r�|r�t
|d��YnX|�r�t
|d��Yq,Xq,W|dk�r |�r t
|d��||_||_|dk�r�x�yR|j|j||t	j
j�}|dk�sf|j|k�rl|j}|dj|k�r�|dj}PWn@tk
�r�y|j�}Wnt	jjk
�r�PYnXYnX�q8Wtj�||_dS)	Nrr�)r.rrrr)r-r%r&r.rZ
find_rrsetr$�ttl�KeyErrorrr"r#r(r<r/�rrsetZ	authority�SOAZminimum�parentr*�NoParent�time�
expiration)rr-r%r&r.�raise_on_no_answerZmin_ttlrM�countZcrrsetZrdZsrrsetrrr�__init__�sf






zAnswer.__init__cCs\|dkr|jjS|dkr |jjS|dkr0|jjS|dkr@|jjS|dkrP|jjSt|��dS)Nr*rK�coversr&r%)rMr*rKrVr&r%r
)r�attrrrr�__getattr__szAnswer.__getattr__cCs|jrt|j�pdS)Nr)rMr)rrrr�__len__szAnswer.__len__cCs|jrt|j�ptt��S)N)rM�iterr)rrrr�__iter__szAnswer.__iter__cCs
|j|S)N)rM)r�irrr�__getitem__szAnswer.__getitem__cCs|j|=dS)N)rM)rr\rrr�__delitem__szAnswer.__delitem__N)T)
r4r5r6rrUrXrYr[r]r^rrrrrI�s
7rIc@s<eZdZdZddd�Zdd�Zdd�Zd	d
�Zddd
�ZdS)�CacheaqSimple DNS answer cache.

    @ivar data: A dictionary of cached data
    @type data: dict
    @ivar cleaning_interval: The number of seconds between cleanings.  The
    default is 300 (5 minutes).
    @type cleaning_interval: float
    @ivar next_cleaning: The time the cache should next be cleaned (in seconds
    since the epoch.)
    @type next_cleaning: float
    ��r@cCs*i|_||_tj�|j|_tj�|_dS)z�Initialize a DNS cache.

        @param cleaning_interval: the number of seconds between periodic
        cleanings.  The default is 300.0
        @type cleaning_interval: float.
        N)�data�cleaning_intervalrQ�
next_cleaning�
_threading�Lock�lock)rrbrrrrU-szCache.__init__cCsptj�}|j|krlg}x*|jj�D]\}}|j|kr"|j|�q"Wx|D]}|j|=qHWtj�}||j|_dS)z&Clean the cache if it's time to do so.N)rQrcrar'rRr2rb)r�nowZkeys_to_delete�k�vrrr�_maybe_clean:s


zCache._maybe_cleanc
CsNz<|jj�|j�|jj|�}|dks6|jtj�kr:dS|S|jj�XdS)a)Get the answer associated with I{key}.  Returns None if
        no answer is cached for the key.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @rtype: dns.resolver.Answer object or None
        N)rf�acquirerjrar1rRrQ�release)r�keyrirrrr1Hs	
z	Cache.getc
Cs2z |jj�|j�||j|<Wd|jj�XdS)aAssociate key and value in the cache.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @param value: The answer being cached
        @type value: dns.resolver.Answer object
        N)rfrkrjrarl)rrm�valuerrr�put[s
	
z	Cache.putNc
CsRz@|jj�|dk	r(||jkr>|j|=ni|_tj�|j|_Wd|jj�XdS)z�Flush the cache.

        If I{key} is specified, only that item is flushed.  Otherwise
        the entire cache is flushed.

        @param key: the key to flush
        @type key: (dns.name.Name, int, int) tuple or None
        N)rfrkrarQrbrcrl)rrmrrr�flushks



zCache.flush)r`)N)	r4r5r6rrUrjr1rorprrrrr_s

r_c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�LRUCacheNodezLRUCache node.
    cCs||_||_||_||_dS)N)rmrn�prev�next)rrmrnrrrrU�szLRUCacheNode.__init__cCs |j|_||_||j_||_dS)N)rrrs)r�noderrr�link_before�szLRUCacheNode.link_beforecCs ||_|j|_||j_||_dS)N)rrrs)rrtrrr�
link_after�szLRUCacheNode.link_aftercCs|j|j_|j|j_dS)N)rrrs)rrrr�unlink�s
zLRUCacheNode.unlinkN)r4r5r6rrUrurvrwrrrrrq�s
rqc@s<eZdZdZddd�Zdd�Zdd�Zd	d
�Zddd
�ZdS)�LRUCacheaOBounded least-recently-used DNS answer cache.

    This cache is better than the simple cache (above) if you're
    running a web crawler or other process that does a lot of
    resolutions.  The LRUCache has a maximum number of nodes, and when
    it is full, the least-recently used node is removed to make space
    for a new one.

    @ivar data: A dictionary of cached data
    @type data: dict
    @ivar sentinel: sentinel node for circular doubly linked list of nodes
    @type sentinel: LRUCacheNode object
    @ivar max_size: The maximum number of nodes
    @type max_size: int
    順cCs*i|_|j|�tdd�|_tj�|_dS)z�Initialize a DNS cache.

        @param max_size: The maximum number of nodes to cache; the default is
        100,000. Must be greater than 1.
        @type max_size: int
        N)ra�set_max_sizerq�sentinelrdrerf)r�max_sizerrrrU�s
zLRUCache.__init__cCs|dkrd}||_dS)Nr)r|)rr|rrrrz�szLRUCache.set_max_sizec
CslzZ|jj�|jj|�}|dkr$dS|j�|jjtj�krJ|j|j=dS|j	|j
�|jS|jj�XdS)a)Get the answer associated with I{key}.  Returns None if
        no answer is cached for the key.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @rtype: dns.resolver.Answer object or None
        N)rfrkrar1rwrnrRrQrmrvr{rl)rrmrtrrrr1�s

zLRUCache.getc
Cs�z�|jj�|jj|�}|dk	r2|j�|j|j=x.t|j�|jkr`|jj	}|j�|j|j=q4Wt
||�}|j|j�||j|<Wd|jj�XdS)aAssociate key and value in the cache.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @param value: The answer being cached
        @type value: dns.resolver.Answer object
        N)
rfrkrar1rwrmrr|r{rrrqrvrl)rrmrnrtrrrro�s


zLRUCache.putNc
Cs�zr|jj�|dk	r<|jj|�}|dk	rp|j�|j|j=n4|jj}x$||jkrh|j}d|_d|_|}qFWi|_Wd|jj	�XdS)z�Flush the cache.

        If I{key} is specified, only that item is flushed.  Otherwise
        the entire cache is flushed.

        @param key: the key to flush
        @type key: (dns.name.Name, int, int) tuple or None
        N)
rfrkrar1rwrmr{rsrrrl)rrmrtrsrrrrp�s	

zLRUCache.flush)ry)N)	r4r5r6rrUrzr1rorprrrrrx�s
rxc@s�eZdZdZd%dd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zejjejjddddfdd�Zdejjfdd �Zd!d"�Zd#d$�ZdS)&�Resolvera-DNS stub resolver

    @ivar domain: The domain of this host
    @type domain: dns.name.Name object
    @ivar nameservers: A list of nameservers to query.  Each nameserver is
    a string which contains the IP address of a nameserver.
    @type nameservers: list of strings
    @ivar search: The search list.  If the query name is a relative name,
    the resolver will construct an absolute query name by appending the search
    names one by one to the query name.
    @type search: list of dns.name.Name objects
    @ivar port: The port to which to send queries.  The default is 53.
    @type port: int
    @ivar timeout: The number of seconds to wait for a response from a
    server, before timing out.
    @type timeout: float
    @ivar lifetime: The total number of seconds to spend trying to get an
    answer to the question.  If the lifetime expires, a Timeout exception
    will occur.
    @type lifetime: float
    @ivar keyring: The TSIG keyring to use.  The default is None.
    @type keyring: dict
    @ivar keyname: The TSIG keyname to use.  The default is None.
    @type keyname: dns.name.Name object
    @ivar keyalgorithm: The TSIG key algorithm to use.  The default is
    dns.tsig.default_algorithm.
    @type keyalgorithm: string
    @ivar edns: The EDNS level to use.  The default is -1, no Edns.
    @type edns: int
    @ivar ednsflags: The EDNS flags
    @type ednsflags: int
    @ivar payload: The EDNS payload size.  The default is 0.
    @type payload: int
    @ivar flags: The message flags to use.  The default is None (i.e. not
    overwritten)
    @type flags: int
    @ivar cache: The cache to use.  The default is None.
    @type cache: dns.resolver.Cache object
    @ivar retry_servfail: should we retry a nameserver if it says SERVFAIL?
    The default is 'false'.
    @type retry_servfail: bool
    �/etc/resolv.confTcCs�d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_	d|_
d|_d|_d|_
d|_d|_d|_|j�|r�tjdkr�|j�n|r�|j|�dS)aJInitialize a resolver instance.

        @param filename: The filename of a configuration file in
        standard /etc/resolv.conf format.  This parameter is meaningful
        only when I{configure} is true and the platform is POSIX.
        @type filename: string or file object
        @param configure: If True (the default), the resolver instance
        is configured in the normal fashion for the operating system
        the resolver is running on.  (I.e. a /etc/resolv.conf file on
        POSIX systems and from the registry on Windows systems.)
        @type configure: boolNFr)�domain�nameservers�nameserver_ports�port�search�timeout�lifetime�keyring�keyname�keyalgorithm�edns�	ednsflags�payload�cache�flags�retry_servfail�rotate�reset�sys�platform�
read_registry�read_resolv_conf)r�filenameZ	configurerrrrU9s.


zResolver.__init__cCs�tjjtjjtj��dd��|_t|j�dkr:tjj|_g|_	i|_
d|_g|_d|_
d|_d|_d|_tjj|_d|_d|_d|_d|_d|_d|_d|_dS)	z1Reset all resolver configuration to the defaults.rNr�5g@g>@Fr)rr*�Namer+�socket�gethostnamerr�rootr�r�r�r�r�r�r�r��tsig�default_algorithmr�r�r�r�r�r�r�r�)rrrrr�_s&"

zResolver.resetcCsZt|t�r<yt|d�}Wntk
r4dg|_dSXd}nd}z�x�|D]�}t|�dksH|ddksH|ddkrrqH|j�}t|�d	kr�qH|dd
kr�|jj|d�qH|ddkr�tj	j
|d�|_qH|dd
k�rxL|dd�D]}|jjtj	j
|��q�WqH|ddkrHd|dd�krHd|_
qHWWd|�r8|j�Xt|j�dk�rV|jjd�dS)z�Process f as a file in the /etc/resolv.conf format.  If f is
        a string, it is used as the name of the file to open; otherwise it
        is treated as the file itself.�rz	127.0.0.1NTFr�#�;rC�
nameserverrrr�Zoptionsr�)r	r�open�IOErrorr�r�splitr2rr*r+rr�r��close)r�fZ
want_close�l�tokens�suffixrrrr�vs:

$
zResolver.read_resolv_confcCs0|jd�dkrd}n|jd�dkr(d}nd}|S)N� r�,)�find)r�entry�
split_charrrr�_determine_split_char�szResolver._determine_split_charcCsDt|�}|j|�}|j|�}x"|D]}||jkr"|jj|�q"WdS)z&Configure a NameServer registry entry.N)rr�r�r�r2)rr�r�Zns_list�nsrrr�_config_win32_nameservers�s



z"Resolver._config_win32_nameserverscCstjjt|��|_dS)z"Configure a Domain registry entry.N)rr*r+rr)rrrrr�_config_win32_domain�szResolver._config_win32_domaincCsLt|�}|j|�}|j|�}x*|D]"}||jkr"|jjtjj|��q"WdS)z"Configure a Search registry entry.N)rr�r�r�r2rr*r+)rr�r�Zsearch_list�srrr�_config_win32_search�s



zResolver._config_win32_searchc#Cs.ytj|d�\}}Wntk
r,d}YnX|rv|j|�y"tj|d�\}}|r\|j|�Wq�tk
rrYq�Xntytj|d�\}}Wntk
r�d}YnX|r�|j|�y"tj|d�\}}|r�|j|�Wntk
r�YnXytj|d�\}}Wntk
�rd}YnX|�r*|j|�dS)z%Extract DNS info from a registry key.Z
NameServerNZDomainZDhcpNameServerZ
DhcpDomainZ
SearchList)�_winreg�QueryValueEx�WindowsErrorr�r�r�)rrmZserversZrtypeZdomr�rrr�_config_win32_fromkey�s<




zResolver._config_win32_fromkeyc,Cstjdtj�}d}z�ytj|d�}d}Wn tk
rHtj|d�}YnXz|j|�Wd|j�X|r�tj|d�}ztd}xjyNtj||�}|d7}tj||�}|j|||�s�w|z|j|�Wd|j�XWq|tk
r�PYq|Xq|WWd|j�XWd|j�XdS)	z9Extract resolver configuration from the Windows registry.NFz2SYSTEM\CurrentControlSet\Services\Tcpip\ParametersTz+SYSTEM\CurrentControlSet\Services\VxD\MSTCPz=SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfacesrr)	r�ZConnectRegistry�HKEY_LOCAL_MACHINE�OpenKey�EnvironmentErrorr��CloseZEnumKey�_win32_is_nic_enabled)r�lmZ	want_scanZ
tcp_paramsZ
interfacesr\�guidrmrrrr��s@
zResolver.read_registryc
Cs�y�tj|d|�}zftj|d�\}}|tjkr2t�tj|d|�}z(tj|d�\}}|tjkrbt�|d@S|j�XWd|j�XWnFttfk
r�ytj|d�\}	}|	dk	Stk
r�dSXYnXdS)Nz]SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\%s\ConnectionZ
PnpInstanceIDz SYSTEM\CurrentControlSet\Enum\%sZConfigFlagsrZNTEContextListF)	r�r�r�ZREG_SZ�
ValueErrorZ	REG_DWORDr�r�r�)
rr�r�Z
interface_keyZconnection_keyZpnp_idZttypeZ
device_keyr�Znterrrr�s6



zResolver._win32_is_nic_enabledcCsVtj�}||}|dkr0|dkr,t|d��n|}||jkrDt|d��t|j||j�S)Nrr)r�r)rQ�Timeoutr��minr�)r�startrgZdurationrrr�_compute_timeoutMs

zResolver._compute_timeoutFNrcCst|t�rtjj|d�}t|t�r.tjj|�}tjj|�r>t�t|t�rTtjj|�}tjj	|�rdt�g}|j
�r||j|�nZt|�dkr�|j|j
tjj��|jr�x2|jD]}	|j|j
|	��q�Wn|j|j
|j��d}
i}tj�}d}
�x�|D�]�}
|j�r@|jj|
||f�}|dk	�r@|jdk�r<|�r<t|jd��n|Stjj|
||�}|jdk	�rr|j|j|j|jd�|j|j|j|j �|j!dk	�r�|j!|_!d}|j"dd�}g}|j#�r�t$j%|�d}�x�|dk�r�t|�dk�r�t&||d���x`|dd�D�]N}|j'|�}|j(j||j)�}yx|}|�rDtj*j+||||||d	�}nNtj*j,||||||d	�}|j!tj!j-@�r�d}|j'|�}tj*j+||||||d	�}W�n t.j/tj0j1fk
�r�}z"|j|||||f�d}�w�WYdd}~Xn�tj*j2k
�r"}z"|j|||||f�d}�w�WYdd}~Xn�tj0j3k
�rn}z,|j4|�|j|||||f�d}�w�WYdd}~XnJt5k
�r�}z,|j4|�|j|||||f�d}�w�WYdd}~XnX|j6�}|tj6j7k�r�t7�}|j|||||f�|�|tj6j8k�s|tj6j9k�r
P|tj6j:k�s"|j;�r,|j4|�|j|||tj6j<|�|f�d}�q�W|dk	�r^Pt|�dk�r�|j'|�}t=||�}|d
9}tj>|��q�W|j6�tj6j9k�r�|||
<q�d}
Pq�W|
�r�t9||d��t?|
||||�}|j�r�|jj@|
||f|�|S)
aQuery nameservers to find the answer to the question.

        The I{qname}, I{rdtype}, and I{rdclass} parameters may be objects
        of the appropriate type, or strings that can be converted into objects
        of the appropriate type.  E.g. For I{rdtype} the integer 2 and the
        the string 'NS' both mean to query for records with DNS rdata type NS.

        @param qname: the query name
        @type qname: dns.name.Name object or string
        @param rdtype: the query type
        @type rdtype: int or string
        @param rdclass: the query class
        @type rdclass: int or string
        @param tcp: use TCP to make the query (default is False).
        @type tcp: bool
        @param source: bind to this IP address (defaults to machine default
        IP).
        @type source: IP address in dotted quad notation
        @param raise_on_no_answer: raise NoAnswer if there's no answer
        (defaults is True).
        @type raise_on_no_answer: bool
        @param source_port: The port from which to send the message.
        The default is 0.
        @type source_port: int
        @rtype: dns.resolver.Answer instance
        @raises Timeout: no answers could be found in the specified lifetime
        @raises NXDOMAIN: the query name does not exist
        @raises YXDOMAIN: the query name is too long after DNAME substitution
        @raises NoAnswer: the response did not contain an answer and
        raise_on_no_answer is True.
        @raises NoNameservers: no non-broken nameservers are available to
        answer the question.NrT)r.)�	algorithmg�������?r)rArB)�source�source_portrCF)rr)Ar	rrr*r+r"Zis_metatyperHr Zis_metaclass�is_absoluter2rZconcatenater�r�rrQr�r1rMr<r.�messageZ
make_queryr��use_tsigr�r��use_ednsr�r�r�r�r�r��randomZshuffler@r�r�r�r=�tcp�udpZTCr��error�	exceptionr�ZUnexpectedSourceZ	FormError�remove�EOFError�rcoder;ZNOERRORrZSERVFAILr�r)r�ZsleeprIro)rr-r%r&r�r�rSr�Z
qnames_to_tryr�Zall_nxdomainZnxdomain_responsesr�Z_qnamer$rAr.r�rBZbackoffr�r�r�Ztcp_attemptZexr�Z
sleep_timerrrr=]s�#




















zResolver.querycCs4||_|dkr$t|jj��d|_n||_||_dS)a�Add a TSIG signature to the query.

        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @param algorithm: The TSIG key algorithm to use.  The default
        is dns.tsig.default_algorithm.
        @type algorithm: stringNr)r�r
�keysr�r�)rr�r�r�rrrr�"s
zResolver.use_tsigcCs"|dkrd}||_||_||_dS)aConfigure Edns.

        @param edns: The EDNS level to use.  The default is -1, no Edns.
        @type edns: int
        @param ednsflags: The EDNS flags
        @type ednsflags: int
        @param payload: The EDNS payload size.  The default is 0.
        @type payload: intNrr)r�r�r�)rr�r�r�rrrr�8s

zResolver.use_ednscCs
||_dS)z�Overrides the default flags with your own

        @param flags: The flags to overwrite the default with
        @type flags: intN)r�)rr�rrr�	set_flagsHszResolver.set_flags)r~T)r4r5r6rrUr�r�r�r�r�r�r�r�r�r�rr"�Ar r!r=r�r�r�r�r�rrrrr}s&+
&)

"-7Er}cCstdkrt�tS)z7Get the default resolver, initializing it if necessary.N)�default_resolver�reset_default_resolverrrrr�get_default_resolverRsr�cCs
t�adS)zSRe-initialize default resolver.

    resolv.conf will be re-read immediatelly.
    N)r}r�rrrrr�Ysr�FTcCst�j|||||||�S)z�Query nameservers to find the answer to the question.

    This is a convenience function that uses the default resolver
    object to make the query.
    @see: L{dns.resolver.Resolver.query} for more information on the
    parameters.)r�r=)r-r%r&r�r�rSr�rrrr=bs	r=cCs�t|t�rtjj|tjj�}|dkr*t�}|j�s:t|��xxy(|j	|tj
j||�}|jj|krb|SWn tj
jtj
jfk
r�YnXy|j�}Wq<tjjk
r�t�Yq<Xq<WdS)a�Find the name of the zone which contains the specified name.

    @param name: the query name
    @type name: absolute dns.name.Name object or string
    @param rdclass: The query class
    @type rdclass: int
    @param tcp: use TCP to make the query (default is False).
    @type tcp: bool
    @param resolver: the resolver to use
    @type resolver: dns.resolver.Resolver object or None
    @rtype: dns.name.NameN)r	rrr*r+r�r�r�rFr=r"rNrM�resolverrr<rOrPrG)r*r&r�r�r$rrr�
zone_for_nameos"
r�c,Cs�|tjtjB@dkrt�|dkr4|dkr4tjtj��g}g}d}y�|dkr�d}|tj@dkrr|jd�|jd�q�|jd�|jd�n>|jd�}	t	|	�dkr�|	d}
n|}
t
jj|
�}|j|�|}W�npt
k
�r:y t
jj|�}|j|�|}W�n8t
k
�r4|tj@dk�r0y�|tjk�s8|tjk�r�tj|t
jjd	d
�}|j}|jjd�}|jdk	�r�x|jD]}
|j|
j��qrW|tjk�s�|tjk�r�tj|t
jjd	d
�}|j}|jjd�}|jdk	�r�x|jD]}
|j|
j��q�WWn<t
jjk
�rtjtj��Yntjtj��YnXYnXYnXd}y|dk�rRd}nt |�}WnLt
k
�r�|tj!@dk�r�ytj"|�}Wnt
k
�r�YnXYnX|dk�r�tjtj��g}|dk�r�tj#tj$g}n|g}|tj%@dk�r�|}nd}|tjk�s|tjk�rfxP|D]H}x@|D]8}x0t&|D]$}|jtj|||||ddff��q2W�q$W�qW|tjk�s~|tjk�r�xL|D]D}x<|D]4}x,t&|D] }|jtj|||||ff��q�W�q�W�q�Wt	|�dk�r�tjtj��|S)
NrZ	localhostz::z0.0.0.0z::1z	127.0.0.1�%rCF)rST�)'r�Z
AI_ADDRCONFIGZAI_V4MAPPED�NotImplementedError�gaierror�
EAI_NONAMEZ
AI_PASSIVEr2r�rr�ipv6�	inet_aton�	ExceptionZipv4ZAI_NUMERICHOST�AF_INET6�	AF_UNSPEC�	_resolverr=r"ZAAAAr-r/r)rMZaddress�AF_INETr�r�rZ
EAI_SYSTEM�intZAI_NUMERICSERVZ
getservbyname�
SOCK_DGRAM�SOCK_STREAM�AI_CANONNAME�_protocols_for_socktype)�host�service�familyZsocktype�protor�Zv6addrsZv4addrsr/�partsZahost�addrZv6ZrdataZv4r��tuplesZ	socktypesr,rrr�_getaddrinfo�s�












$

 r�c
Csf|d}|d}t|�dkr,|d}tj}n
d}tj}t|||tjtjd�}t|�dkrbtjd��|ddd}|tj@r�d}nd}t	j
j|�}	|tj@dk�ry"t
j|	d�}
|
jdjjd	�}WnVt	jjt	jjfk
�r|tj@r�tjtj��|}|dk	�r|d
t|�7}YnXn|}|dk	�r<|d
t|�7}|tj@�rRt|�}ntj||�}||fS)Nrr�rDz'sockaddr resolved to multiple addressesr�r�ZPTRTr�)rr�r�r�r�r��SOL_TCPr�ZNI_DGRAMrZreversenameZfrom_addressZNI_NUMERICHOSTr�r=rMr(r)r�rr<�NI_NAMEREQDr�r�rZNI_NUMERICSERVZ
getservbyport)
�sockaddrr�r�r�Zscoper�r�r�Zpnamer-r$Zhostnamer�rrr�_getnameinfosB






r�cCsD|dkrtj�}ytt|d�dd�dStk
r>|SXdS)N�Prr�)r�r�r�r�r�)r*rrr�_getfqdn.sr�cCst|�ddS)NrCr)�_gethostbyname_ex)r*rrr�_gethostbyname7sr�cCsXg}g}t|dtjtjtjtj�}|dd}x|D]}|j|dd�q4W|||fS)NrrDr�)r�r�r�r�r�r�r2)r*�aliases�	addressesr��	canonical�itemrrrr�;s
r�c
Cs�y"tjj|�|dddf}tj}Wn"tk
rD|df}tj}YnXt|tj�\}}g}g}t	|d|tj
tjtj�}|dd}x|D]}	|j
|	dd�q�W|||fS)Nr�rrDr�)rr�r�r�r�r�r�r�r�r�r�r�r�r2)
Zipr�r�r*r�r�r�r�r�rrrr�_gethostbyaddrGs 

rcCs:|dkrt�}|att_tt_tt_t	t_
tt_t
t_dS)a�Override the system resolver routines in the socket module with
    versions which use dnspython's resolver.

    This can be useful in testing situations where you want to control
    the resolution behavior of python code without having to change
    the system's resolver settings (e.g. /etc/resolv.conf).

    The resolver to use may be specified; if it's not, the default
    resolver will be used.

    @param resolver: the resolver to use
    @type resolver: dns.resolver.Resolver object or None
    N)r�r�r�r��getaddrinfor��getnameinfor��getfqdnr��
gethostbynamer��gethostbyname_exr�
gethostbyaddr)r�rrr�override_system_resolver[srcCs,datt_tt_tt_tt_	t
t_tt_
dS)z4Undo the effects of override_system_resolver().
    N)r��_original_getaddrinfor�r�_original_getnameinfor�_original_getfqdnr�_original_gethostbynamer�_original_gethostbyname_exr�_original_gethostbyaddrrrrrr�restore_system_resolverusr)r)N)N)Prr�r�rQr�Z	threadingrd�ImportErrorZdummy_threadingZ
dns.exceptionrZ	dns.flagsZdns.ipv4Zdns.ipv6Zdns.messageZdns.nameZ	dns.queryZ	dns.rcodeZdns.rdataclassZ
dns.rdatatypeZdns.reversenameZdns.tsigZ_compatrrr��winregr�r�ZDNSExceptionrr;r�r<r@rFrGrH�objectrIr_rqrxr}r�r�r�r"r�r r!r=r�r�ZSOL_UDPr�r�r�r�rr	rr
rrrrrr
rrr�r�r�r�r�r�rrrrrrr�<module>s�
<sboG	&

c
(
	
PKj�\�_DBII#__pycache__/__init__.cpython-36.pycnu�[���3

�b�W/�#@sRdZddddddddd	d
ddd
ddddddddddddddddddd d!d"d#g#Zd$S)%zdnspython DNS toolkitZdnssecZe164ZednsZentropyZ	exception�flags�hashZinetZipv4Zipv6�message�nameZnamedictZnodeZopcodeZqueryZrcodeZrdataZ
rdataclassZrdatasetZ	rdatatypeZrendererZresolverZreversenameZrrset�setZ	tokenizerZtsigZtsigkeyringZttlZrdtypes�update�versionZwiredataZzoneN)�__doc__�__all__�r
r
�/usr/lib/python3.6/__init__.py�<module>sFPKj�\雅Xc&c&#__pycache__/renderer.cpython-36.pycnu�[���3

�b�W�.�@shdZddlmZddlZddlZddlZddlZddlZddl	m
Z
dZdZdZ
dZGdd	�d	e�ZdS)
z*Help for building DNS wire format messages�)�BytesION�)�long��c@steZdZdZddd�Zdd�Zd	d
�Zejj	fdd�Z
d
d�Zdd�Zddd�Z
ejjfdd�Zdd�Zdd�ZdS)�RendereraiHelper class for building DNS wire-format messages.

    Most applications can use the higher-level L{dns.message.Message}
    class and its to_wire() method to generate wire-format messages.
    This class is for those applications which need finer control
    over the generation of messages.

    Typical use::

        r = dns.renderer.Renderer(id=1, flags=0x80, max_size=512)
        r.add_question(qname, qtype, qclass)
        r.add_rrset(dns.renderer.ANSWER, rrset_1)
        r.add_rrset(dns.renderer.ANSWER, rrset_2)
        r.add_rrset(dns.renderer.AUTHORITY, ns_rrset)
        r.add_edns(0, 0, 4096)
        r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_1)
        r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_2)
        r.write_header()
        r.add_tsig(keyname, secret, 300, 1, 0, '', request_mac)
        wire = r.get_wire()

    @ivar output: where rendering is written
    @type output: BytesIO object
    @ivar id: the message id
    @type id: int
    @ivar flags: the message flags
    @type flags: int
    @ivar max_size: the maximum size of the message
    @type max_size: int
    @ivar origin: the origin to use when rendering relative names
    @type origin: dns.name.Name object
    @ivar compress: the compression table
    @type compress: dict
    @ivar section: the section currently being rendered
    @type section: int (dns.renderer.QUESTION, dns.renderer.ANSWER,
    dns.renderer.AUTHORITY, or dns.renderer.ADDITIONAL)
    @ivar counts: list of the number of RRs in each section
    @type counts: int list of length 4
    @ivar mac: the MAC of the rendered message (if TSIG was used)
    @type mac: string
    Nr�cCsht�|_|dkr tjdd�|_n||_||_||_||_i|_t	|_
ddddg|_|jjd�d|_
dS)a�Initialize a new renderer.

        @param id: the message id
        @type id: int
        @param flags: the DNS message flags
        @type flags: int
        @param max_size: the maximum message size; the default is 65535.
        If rendering results in a message greater than I{max_size},
        then L{dns.exception.TooBig} will be raised.
        @type max_size: int
        @param origin: the origin to use when rendering relative names
        @type origin: dns.name.Name or None.
        Nri�����s)r�output�randomZrandint�id�flags�max_size�origin�compress�QUESTION�section�counts�write�mac)�selfrrrr�r�/usr/lib/python3.6/renderer.py�__init__NszRenderer.__init__cCs^|jj|�|jj�g}x(|jj�D]\}}||kr&|j|�q&Wx|D]}|j|=qJWdS)z�Truncate the output buffer at offset I{where}, and remove any
        compression table entries that pointed beyond the truncation
        point.

        @param where: the offset
        @type where: int
        N)r�seek�truncater�items�append)r�whereZkeys_to_delete�k�vrrr�	_rollbackks	

zRenderer._rollbackcCs&|j|kr"|j|krtjj�||_dS)aZSet the renderer's current section.

        Sections must be rendered order: QUESTION, ANSWER, AUTHORITY,
        ADDITIONAL.  Sections may be empty.

        @param section: the section
        @type section: int
        @raises dns.exception.FormError: an attempt was made to set
        a section value less than the current section.
        N)r�dns�	exceptionZ	FormError)rrrrr�_set_section}s

zRenderer._set_sectioncCsz|jt�|jj�}|j|j|j|j�|jjtj	d||��|jj�}||j
krd|j|�tj
j�|jtd7<dS)aAdd a question to the message.

        @param qname: the question name
        @type qname: dns.name.Name
        @param rdtype: the question rdata type
        @type rdtype: int
        @param rdclass: the question rdata class
        @type rdclass: int
        z!HHrN)r&rr�tell�to_wirerrr�struct�packrr#r$r%�TooBigr)rZqnameZrdtypeZrdclass�before�afterrrr�add_question�s




zRenderer.add_questioncKsh|j|�|jj�}|j|j|j|jf|�}|jj�}||jkrR|j|�tj	j
�|j||7<dS)aAdd the rrset to the specified section.

        Any keyword arguments are passed on to the rdataset's to_wire()
        routine.

        @param section: the section
        @type section: int
        @param rrset: the rrset
        @type rrset: dns.rrset.RRset object
        N)r&rr'r(rrrr#r$r%r+r)rrZrrset�kwr,�nr-rrr�	add_rrset�s




zRenderer.add_rrsetcKsj|j|�|jj�}|j||j|j|jf|�}|jj�}||jkrT|j|�tj	j
�|j||7<dS)a�Add the rdataset to the specified section, using the specified
        name as the owner name.

        Any keyword arguments are passed on to the rdataset's to_wire()
        routine.

        @param section: the section
        @type section: int
        @param name: the owner name
        @type name: dns.name.Name object
        @param rdataset: the rdataset
        @type rdataset: dns.rdataset.Rdataset object
        N)r&rr'r(rrrr#r$r%r+r)rr�nameZrdatasetr/r,r0r-rrr�add_rdataset�s




zRenderer.add_rdatasetc
Cs�|td�M}||d>O}|jt�|jj�}|jjtjddtj	j
||d��|dk	�rJ|jj�}x�|D]�}tjd|jd�}|jj|�|jj�}	|j|j�|jj�}
|
|	dks�t
�|jj|	d�tjd	|
|	�}|jj|�|jjdd�qfW|jj�}||dk�st
�|jj|d�tjd	||�}|jj|�|jjdd�|jj�}||jk�rr|j|�tjj�|jtd
7<dS)a�Add an EDNS OPT record to the message.

        @param edns: The EDNS level to use.
        @type edns: int
        @param ednsflags: EDNS flag values.
        @type ednsflags: int
        @param payload: The EDNS sender's payload field, which is the maximum
        size of UDP datagram the sender can handle.
        @type payload: int
        @param options: The EDNS options list
        @type options: list of dns.edns.Option instances
        @see: RFC 2671
        l�~�z!BHHIHrNz!HHirz!Hr)rr&�
ADDITIONALrr'rr)r*r$�	rdatatype�OPTZotyper(�AssertionErrorrrr#r%r+r)
rZednsZ	ednsflagsZpayloadZoptionsr,Zlstart�optZstuff�start�endZlendr-rrr�add_edns�s<










zRenderer.add_ednsc	CsB|jt�|jj�}	|jj�}
tjj|
||tt	j	��||||||d�
\}|_
}|j|j|j|j
�|jjtjdtjjtjjdd��|jj�}
|jj|�|jj�}||
dks�t�||jkr�|j|	�tjj�|jj|
d�|jjtjd||
��|jtd7<|jjd�|jjtjd|jt��|jjdd�d	S)
a�Add a TSIG signature to the message.

        @param keyname: the TSIG key name
        @type keyname: dns.name.Name object
        @param secret: the secret to use
        @type secret: string
        @param fudge: TSIG time fudge
        @type fudge: int
        @param id: the message id to encode in the tsig signature
        @type id: int
        @param tsig_error: TSIG error code; default is 0.
        @type tsig_error: int
        @param other_data: TSIG other data.
        @type other_data: string
        @param request_mac: This message is a response to the request which
        had the specified MAC.
        @type request_mac: string
        @param algorithm: the TSIG algorithm to use
        @type algorithm: dns.name.Name object
        )�	algorithmz!HHIHrirz!Hr�
N)r&r5rr'�getvaluer$�tsigZsign�int�timerr(rrrr)r*r6ZTSIG�
rdataclass�ANYr8rr#r%r+rr)rZkeynameZsecretZfudgerZ
tsig_errorZ
other_dataZrequest_macr=r,�sZ
tsig_rdataZctxZrdata_startr-rrr�add_tsigs:







zRenderer.add_tsigc
CsX|jjd�|jjtjd|j|j|jd|jd|jd|jd��|jjdd�dS)z�Write the DNS message header.

        Writing the DNS message header is done after all sections
        have been rendered, but before the optional TSIG signature
        is added.
        rz!HHHHHHrrrN)rrrr)r*rrr)rrrr�write_header5s
zRenderer.write_headercCs
|jj�S)z@Return the wire format message.

        @rtype: string
        )rr?)rrrr�get_wireCszRenderer.get_wire)NrrN)N)�__name__�
__module__�__qualname__�__doc__rr#r&r$rC�INr.r1r3r<r@Zdefault_algorithmrFrGrHrrrrr"s*

04r)rL�iorr)r
rBZ
dns.exceptionr$Zdns.tsigZ_compatrrZANSWERZ	AUTHORITYr5�objectrrrrr�<module>sPKj�\`��	77%__pycache__/edns.cpython-36.opt-1.pycnu�[���3

�b�W �@s@dZdZGdd�de�ZGdd�de�ZiZdd�Zdd	�Zd
S)zEDNS Options�c@sdeZdZdZdd�Zdd�Zedd��Zdd	�Zd
d�Z	dd
�Z
dd�Zdd�Zdd�Z
dd�ZdS)�Optionz*Base class for all EDNS option types.
    cCs
||_dS)z\Initialize an option.
        @param otype: The rdata type
        @type otype: int
        N)�otype)�selfr�r�/usr/lib/python3.6/edns.py�__init__szOption.__init__cCst�dS)z*Convert an option to wire format.
        N)�NotImplementedError)r�filerrr�to_wire!szOption.to_wirecCst�dS)a�Build an EDNS option object from wire format

        @param otype: The option type
        @type otype: int
        @param wire: The wire-format message
        @type wire: string
        @param current: The offset in wire of the beginning of the rdata.
        @type current: int
        @param olen: The length of the wire-format option data
        @type olen: int
        @rtype: dns.edns.Option instanceN)r)�clsr�wire�current�olenrrr�	from_wire&s
zOption.from_wirecCst�dS)z�Compare an EDNS option with another option of the same type.
        Return < 0 if self < other, 0 if self == other,
        and > 0 if self > other.
        N)r)r�otherrrr�_cmp5szOption._cmpcCs,t|t�sdS|j|jkrdS|j|�dkS)NF�)�
isinstancerrr)rrrrr�__eq__<s

z
Option.__eq__cCs,t|t�sdS|j|jkrdS|j|�dkS)NFr)rrrr)rrrrr�__ne__Cs

z
Option.__ne__cCs*t|t�s|j|jkrtS|j|�dkS)Nr)rrr�NotImplementedr)rrrrr�__lt__Jsz
Option.__lt__cCs*t|t�s|j|jkrtS|j|�dkS)Nr)rrrrr)rrrrr�__le__Psz
Option.__le__cCs*t|t�s|j|jkrtS|j|�dkS)Nr)rrrrr)rrrrr�__ge__Vsz
Option.__ge__cCs*t|t�s|j|jkrtS|j|�dkS)Nr)rrrrr)rrrrr�__gt__\sz
Option.__gt__N)�__name__�
__module__�__qualname__�__doc__rr
�classmethodrrrrrrrrrrrrrsrcs<eZdZdZ�fdd�Zdd�Zedd��Zdd	�Z�Z	S)
�
GenericOptionzwGenerate Rdata Class

    This class is used for EDNS option types for which we have no better
    implementation.
    cstt|�j|�||_dS)N)�superr r�data)rrr")�	__class__rrrkszGenericOption.__init__cCs|j|j�dS)N)�writer")rr	rrrr
oszGenericOption.to_wirecCs||||||��S)Nr)rrrr
rrrrrrszGenericOption.from_wirecCs$|j|jkrdS|j|jkr dSdS)Nr����)r")rrrrrrvs
zGenericOption._cmp)
rrrrrr
rrr�
__classcell__rr)r#rr cs
r cCstj|�}|dkrt}|S)N)�_type_to_class�getr )rrrrr�get_option_class�s
r*cCst|�}|j||||�S)auBuild an EDNS option object from wire format

    @param otype: The option type
    @type otype: int
    @param wire: The wire-format message
    @type wire: string
    @param current: The offset in wire of the beginning of the rdata.
    @type current: int
    @param olen: The length of the wire-format option data
    @type olen: int
    @rtype: dns.edns.Option instance)r*r)rrr
rrrrr�option_from_wire�s
r+N)rZNSID�objectrr r(r*r+rrrr�<module>sNPKj�\�|��g
g
%__pycache__/e164.cpython-36.opt-1.pycnu�[���3

�b�WK�@s\dZddlZddlZddlZddlmZejjd�Z	e	fdd�Z
e	dfd	d
�Zd
dd�ZdS)z�DNS E.164 helpers

@var public_enum_domain: The DNS public ENUM domain, e164.arpa.
@type public_enum_domain: dns.name.Name object
�N�)�string_typesz
e164.arpa.cCs,dd�|D�}|j�tjjdj|�|d�S)auConvert an E.164 number in textual form into a Name object whose
    value is the ENUM domain name for that number.
    @param text: an E.164 number in textual form.
    @type text: str
    @param origin: The domain in which the number should be constructed.
    The default is e164.arpa.
    @type origin: dns.name.Name object or None
    @rtype: dns.name.Name object
    cSsg|]}|j�r|�qS�)�isdigit)�.0�drr�/usr/lib/python3.6/e164.py�
<listcomp>)szfrom_e164.<locals>.<listcomp>�.)�origin)�reverse�dns�name�	from_text�join)�textr�partsrrr�	from_e164s
rTcCsb|dk	r|j|�}dd�|jD�}t|�t|j�kr@tjjd��|j�dj|�}|r^d|}|S)a�Convert an ENUM domain name into an E.164 number.
    @param name: the ENUM domain name.
    @type name: dns.name.Name object.
    @param origin: A domain containing the ENUM domain name.  The
    name is relativized to this domain before being converted to text.
    @type origin: dns.name.Name object or None
    @param want_plus_prefix: if True, add a '+' to the beginning of the
    returned number.
    @rtype: str
    NcSs$g|]}|j�rt|�dkr|�qS)r)r�len)rrrrrr	;szto_e164.<locals>.<listcomp>z$non-digit labels in ENUM domain name��+)Z
relativizeZlabelsrr
Z	exception�SyntaxErrorrr)rrZwant_plus_prefixZdlabelsrrrr�to_e164.s

rcCs�|dkrtjj�}tjj�}xl|D]d}t|t�r<tjj|�}tjj	||�}y|j
|d�Stjjk
r�}z||7}WYdd}~Xq"Xq"W|�dS)z�Look for NAPTR RRs for the specified number in the specified domains.

    e.g. lookup('16505551212', ['e164.dnspython.org.', 'e164.arpa.'])
    NZNAPTR)r
�resolverZget_default_resolverZNXDOMAIN�
isinstancerrrZe164r�query)ZnumberZdomainsrZe_nxZdomainZqname�errrrEs



r)N)
�__doc__Z
dns.exceptionr
Zdns.nameZdns.resolverZ_compatrrrZpublic_enum_domainrrrrrrr�<module>sPKj�\�֙O'%'%)__pycache__/rdataset.cpython-36.opt-1.pycnu�[���3

�b�W$-�@s�dZddlZddlmZddlZddlZddlZddlZddl	Zddl
ZddlmZej
jZGdd�dejj�ZGdd	�d	ejj�ZGd
d�dej
j�Zdd
�Zdd�Zdd�Zdd�ZdS)zHDNS rdatasets (an rdataset is a set of rdatas of a given type and class)�N)�StringIO�)�string_typesc@seZdZdZdS)�DifferingCoversz~An attempt was made to add a DNS SIG/RRSIG whose covered type
    is not the same as that of the other rdatas in the rdataset.N)�__name__�
__module__�__qualname__�__doc__�r
r
�/usr/lib/python3.6/rdataset.pyr!src@seZdZdZdS)�IncompatibleTypesz?An attempt was made to add DNS RR data of an incompatible type.N)rrrr	r
r
r
rr'srcs�eZdZdZddddgZejjf�fdd�	Z�fdd	�Z	d
d�Z
d$�fd
d�	Z�fdd�Z�fdd�Z
�fdd�Zdd�Zdd�Z�fdd�Zdd�Zd%dd�Zd&d d!�Zd"d#�Z�ZS)'�Rdataseta�A DNS rdataset.

    @ivar rdclass: The class of the rdataset
    @type rdclass: int
    @ivar rdtype: The type of the rdataset
    @type rdtype: int
    @ivar covers: The covered type.  Usually this value is
    dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
    dns.rdatatype.RRSIG, then the covers value will be the rdata
    type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
    types as if they were a family of
    types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
    easier to work with than if RRSIGs covering different rdata
    types were aggregated into a single RRSIG rdataset.
    @type covers: int
    @ivar ttl: The DNS TTL (Time To Live) value
    @type ttl: int
    �rdclass�rdtype�covers�ttlcs*tt|�j�||_||_||_d|_dS)z�Create a new rdataset of the specified class and type.

        @see: the description of the class instance variables for the
        meaning of I{rdclass} and I{rdtype}rN)�superr
�__init__rrrr)�selfrrr)�	__class__r
rrCs
zRdataset.__init__cs2tt|�j�}|j|_|j|_|j|_|j|_|S)N)rr
�_clonerrrr)r�obj)rr
rrOszRdataset._clonecCs(t|�dkr||_n||jkr$||_dS)z�Set the TTL of the rdataset to be the lesser of the set's current
        TTL or the specified TTL.  If the set contains no rdatas, set the TTL
        to the specified TTL.
        @param ttl: The TTL
        @type ttl: intrN)�lenr)rrr
r
r�
update_ttlWs
zRdataset.update_ttlNcs�|j|jks|j|jkrt�|dk	r.|j|�|jtjjksJ|jtjjkr�|j�}t	|�dkrt|jtjj
krt||_n|j|kr�t�tjj|j�r�t	|�dkr�|j
�tt|�j|�dS)a%Add the specified rdata to the rdataset.

        If the optional I{ttl} parameter is supplied, then
        self.update_ttl(ttl) will be called prior to adding the rdata.

        @param rd: The rdata
        @type rd: dns.rdata.Rdata object
        @param ttl: The TTL
        @type ttl: intNr)rrrr�dns�	rdatatypeZRRSIGZSIGrr�NONErZis_singleton�clearrr
�add)r�rdrr)rr
rrcs

zRdataset.addcs |j|j�tt|�j|�dS)N)rrrr
�union_update)r�other)rr
rr �szRdataset.union_updatecs |j|j�tt|�j|�dS)N)rrrr
�intersection_update)rr!)rr
rr"�szRdataset.intersection_updatecs |j|j�tt|�j|�dS)z�Add all rdatas in other to self.

        @param other: The rdataset from which to update
        @type other: dns.rdataset.Rdataset objectN)rrrr
�update)rr!)rr
rr#�szRdataset.updatecCsR|jdkrd}ndtjj|j�d}dtjj|j�dtjj|j�|dS)Nr��(�)z<DNS � z
 rdataset>)rrr�to_text�
rdataclassrr)rZctextr
r
r�__repr__�s
zRdataset.__repr__cCs|j�S)N)r()rr
r
r�__str__�szRdataset.__str__csFt|t�sdS|j|jks2|j|jks2|j|jkr6dStt|�j|�S)zTwo rdatasets are equal if they have the same class, type, and
        covers, and contain the same rdata.
        @rtype: boolF)�
isinstancer
rrrr�__eq__)rr!)rr
rr-�s
zRdataset.__eq__cCs|j|�S)N)r-)rr!r
r
r�__ne__�szRdataset.__ne__Tc
Ks�|dk	r"|j||�}t|�}d}nd}d}t�}|dk	r>|}	n|j}	t|�dkrz|jd||tjj|	�tj	j|j
�f�nNxL|D]D}
|jd|||jtjj|	�tj	j|j
�|
jf||d�|��f�q�W|j�dd	�S)
a�Convert the rdataset into DNS master file format.

        @see: L{dns.name.Name.choose_relativity} for more information
        on how I{origin} and I{relativize} determine the way names
        are emitted.

        Any additional keyword arguments are passed on to the rdata
        to_text() method.

        @param name: If name is not None, emit a RRs with I{name} as
        the owner name.
        @type name: dns.name.Name object
        @param origin: The origin for relative names, or None.
        @type origin: dns.name.Name object
        @param relativize: True if names should names be relativized
        @type relativize: boolNr'r$rz
%s%s%s %s
z%s%s%d %s %s %s
)�origin�
relativizer���)
Zchoose_relativity�strrrr�writerr)r(rrr�getvalue)r�namer/r0�override_rdclass�kwZntextZpad�srrr
r
rr(�s*


zRdataset.to_textc
Cs|dk	r|}d}n|j}|jdd�t|�dkr`|j|||�tjd|j|dd�}|j|�dS|rxt|�}	t	j
|	�n|}	x�|	D]�}
|j|||�tjd|j||jd�}|j|�|j�}|
j|||�|j�}|j|d�tjd||�}|j|�|jdd�q�Wt|�SdS)a,Convert the rdataset to wire format.

        @param name: The owner name of the RRset that will be emitted
        @type name: dns.name.Name object
        @param file: The file to which the wire format data will be appended
        @type file: file
        @param compress: The compression table to use; the default is None.
        @type compress: dict
        @param origin: The origin to be appended to any relative names when
        they are emitted.  The default is None.
        @returns: the number of records emitted
        @rtype: int
        NFr�z!HHIHrz!H)
r�seekr�to_wire�struct�packrr3�list�randomZshuffler�tell)
rr5�file�compressr/r6Zwant_shufflerZstuff�lr�start�endr
r
rr;�s6




zRdataset.to_wirecCs&|j|kr"|j|kr"|j|kr"dSdS)zSReturns True if this rdataset matches the specified class, type,
        and coversTF)rrr)rrrrr
r
r�matchs



zRdataset.match)N)NNTN)NNNT)rrrr	�	__slots__rrrrrrrr r"r#r*r+r-r.r(r;rF�
__classcell__r
r
)rrr
,s$ 	

2
/r
cCspt|t�rtjj|�}t|t�r,tjj|�}t||�}|j|�x*|D]"}tjj|j	|j
|�}|j|�qFW|S)z�Create an rdataset with the specified class, type, and TTL, and with
    the specified list of rdatas in text format.

    @rtype: dns.rdataset.Rdataset object
    )r,rrr)�	from_textrr
rZrdatarrr)rrr�text_rdatas�r�trr
r
r�from_text_lists




rMcGst||||�S)z�Create an rdataset with the specified class, type, and TTL, and with
    the specified rdatas in text format.

    @rtype: dns.rdataset.Rdataset object
    )rM)rrrrJr
r
rrI/srIcCsTt|�dkrtd��d}x6|D].}|dkrBt|j|j�}|j|�|j|�qW|S)z�Create an rdataset with the specified TTL, and with
    the specified list of rdata objects.

    @rtype: dns.rdataset.Rdataset object
    rzrdata list must not be emptyN)r�
ValueErrorr
rrrr)r�rdatasrKrr
r
r�from_rdata_list9s

rPcGs
t||�S)z�Create an rdataset with the specified TTL, and with
    the specified rdata objects.

    @rtype: dns.rdataset.Rdataset object
    )rP)rrOr
r
r�
from_rdataKsrQ)r	r?�iorr<Z
dns.exceptionrZ
dns.rdatatypeZdns.rdataclassZ	dns.rdataZdns.setZ_compatr�set�SetZ	SimpleSetZ	exceptionZDNSExceptionrrr
rMrIrPrQr
r
r
r�<module>s$q
PKj�\:��	�	 __pycache__/rcode.cpython-36.pycnu�[���3

�b�W �
@s�dZddlZddlmZdZdZdZdZdZ	dZ
d	Zd
ZdZ
dZd
ZdZeeeee	e
eee
eeed�Zedd�ej�D��ZGdd�dejj�Zdd�Zdd�Zdd�Zdd�ZdS)zDNS Result Codes.�N�)�long��������	�
�)�NOERROR�FORMERR�SERVFAIL�NXDOMAIN�NOTIMP�REFUSED�YXDOMAIN�YXRRSET�NXRRSET�NOTAUTH�NOTZONE�BADVERSccs|]\}}||fVqdS)N�)�.0�x�yrr�/usr/lib/python3.6/rcode.py�	<genexpr>6src@seZdZdZdS)�UnknownRcodezA DNS rcode is unknown.N)�__name__�
__module__�__qualname__�__doc__rrrrr 9sr cCsB|j�r$t|�}|dkr$|dkr$|Stj|j��}|dkr>t�|S)z�Convert text into an rcode.

    @param text: the textual rcode
    @type text: string
    @raises UnknownRcode: the rcode is unknown
    @rtype: int
    ri�N)�isdigit�int�_by_text�get�upperr )�text�vrrr�	from_text>s	r,cCs0|d@|d?d@B}|dks$|dkr,td��|S)z�Return the rcode value encoded by flags and ednsflags.

    @param flags: the DNS flags
    @type flags: int
    @param ednsflags: the EDNS flags
    @type ednsflags: int
    @raises ValueError: rcode is < 0 or > 4095
    @rtype: int
    ��i�ri�zrcode must be >= 0 and <= 4095)�
ValueError)�flagsZ	ednsflags�valuerrr�
from_flagsQsr2cCs8|dks|dkrtd��|d@}t|d@�d>}||fS)z�Return a (flags, ednsflags) tuple which encodes the rcode.

    @param value: the rcode
    @type value: int
    @raises ValueError: rcode is < 0 or > 4095
    @rtype: (int, int) tuple
    ri�zrcode must be >= 0 and <= 4095r-i�r.)r/r)r1r+Zevrrr�to_flagsbs
	r3cCstj|�}|dkrt|�}|S)zbConvert rcode into text.

    @param value: the rcode
    @type value: int
    @rtype: string
    N)�	_by_valuer(�str)r1r*rrr�to_textrs
r6)r$Z
dns.exceptionZdnsZ_compatrrrrrrrrrrrrrr'�dict�itemsr4Z	exceptionZDNSExceptionr r,r2r3r6rrrr�<module>s@PKj�\�|��g
g
__pycache__/e164.cpython-36.pycnu�[���3

�b�WK�@s\dZddlZddlZddlZddlmZejjd�Z	e	fdd�Z
e	dfd	d
�Zd
dd�ZdS)z�DNS E.164 helpers

@var public_enum_domain: The DNS public ENUM domain, e164.arpa.
@type public_enum_domain: dns.name.Name object
�N�)�string_typesz
e164.arpa.cCs,dd�|D�}|j�tjjdj|�|d�S)auConvert an E.164 number in textual form into a Name object whose
    value is the ENUM domain name for that number.
    @param text: an E.164 number in textual form.
    @type text: str
    @param origin: The domain in which the number should be constructed.
    The default is e164.arpa.
    @type origin: dns.name.Name object or None
    @rtype: dns.name.Name object
    cSsg|]}|j�r|�qS�)�isdigit)�.0�drr�/usr/lib/python3.6/e164.py�
<listcomp>)szfrom_e164.<locals>.<listcomp>�.)�origin)�reverse�dns�name�	from_text�join)�textr�partsrrr�	from_e164s
rTcCsb|dk	r|j|�}dd�|jD�}t|�t|j�kr@tjjd��|j�dj|�}|r^d|}|S)a�Convert an ENUM domain name into an E.164 number.
    @param name: the ENUM domain name.
    @type name: dns.name.Name object.
    @param origin: A domain containing the ENUM domain name.  The
    name is relativized to this domain before being converted to text.
    @type origin: dns.name.Name object or None
    @param want_plus_prefix: if True, add a '+' to the beginning of the
    returned number.
    @rtype: str
    NcSs$g|]}|j�rt|�dkr|�qS)r)r�len)rrrrrr	;szto_e164.<locals>.<listcomp>z$non-digit labels in ENUM domain name��+)Z
relativizeZlabelsrr
Z	exception�SyntaxErrorrr)rrZwant_plus_prefixZdlabelsrrrr�to_e164.s

rcCs�|dkrtjj�}tjj�}xl|D]d}t|t�r<tjj|�}tjj	||�}y|j
|d�Stjjk
r�}z||7}WYdd}~Xq"Xq"W|�dS)z�Look for NAPTR RRs for the specified number in the specified domains.

    e.g. lookup('16505551212', ['e164.dnspython.org.', 'e164.arpa.'])
    NZNAPTR)r
�resolverZget_default_resolverZNXDOMAIN�
isinstancerrrZe164r�query)ZnumberZdomainsrZe_nxZdomainZqname�errrrEs



r)N)
�__doc__Z
dns.exceptionr
Zdns.nameZdns.resolverZ_compatrrrZpublic_enum_domainrrrrrrr�<module>sPKj�\o�o		)__pycache__/wiredata.cpython-36.opt-1.pycnu�[���3

�b�W��@s^dZddlZddlZddlmZmZGdd�de�Ze�dd�ZGdd�de�Z	d	d
�Z
dS)zDNS Wire Data Helper�N�)�binary_type�string_typesc@s&eZdZdd�Zejdkr"dd�ZdS)�_SliceUnspecifiedBoundcCs|jS)N)�stop)�self�key�r	�/usr/lib/python3.6/wiredata.py�__getitem__ sz"_SliceUnspecifiedBound.__getitem__�cCs|jt||��S)N)r�slice)r�i�jr	r	r
�__getslice__$sz#_SliceUnspecifiedBound.__getslice__N)r)�__name__�
__module__�__qualname__r�sys�version_inforr	r	r	r
rs
rcs>eZdZ�fdd�Zejd
kr&dd�Zdd�Zdd	�Z�Z	S)�WireDatacs�y�t|t�r�|j}|j}tjdkrx|tkr2t|�}|dksB|dkrJtj	j
�||kr�tt|�j
|�tt|�j
|d�n6x4||fD](}|dkr�q�q�t|�t|�kr�tj	j
�q�Wttt|�j
t||���St|j��|Stk
r�tj	j
�YnXdS)Nrrr)r)�
isinstancer
�startrrr�_unspecified_bound�len�dns�	exception�	FormError�superrr�abs�	bytearray�unwrap�
IndexError)rrrr�index)�	__class__r	r
r-s,

zWireData.__getitem__rcCs|jt||��S)N)rr
)rrrr	r	r
rPszWireData.__getslice__ccsBd}x8y||V|d7}Wqtjjk
r8t�YqXqWdS)Nrr)rrr�
StopIteration)rrr	r	r
�__iter__Ss
zWireData.__iter__cCst|�S)N)r)rr	r	r
r!\szWireData.unwrap)r)
rrrrrrrr&r!�
__classcell__r	r	)r$r
r*s
"
	rcCsJt|t�r|St|t�r t|�St|t�r6t|j��Stdt|���dS)Nzunhandled type %s)rrrr�encode�
ValueError�type)Zwirer	r	r
�
maybe_wrap`s


r+)�__doc__rZ
dns.exceptionrZ_compatrrrrrr+r	r	r	r
�<module>s		6PKj�\�drNN__pycache__/ipv4.cpython-36.pycnu�[���3

�b�W��@s4dZddlZddlZddlmZdd�Zdd�ZdS)	zIPv4 helper functions.�N�)�binary_typecCsJt|�dkrtjj�t|t�s&t|�}d|d|d|d|dfj�S)z�Convert an IPv4 address in network form to text form.

    @param address: The IPv4 address
    @type address: string
    @returns: string
    �z%u.%u.%u.%urr��)�len�dns�	exception�SyntaxError�
isinstance�	bytearray�encode)Zaddress�r�/usr/lib/python3.6/ipv4.py�	inet_ntoas
rc	Cs�t|t�s|j�}|jd�}t|�dkr0tjj�x<|D]4}|j�sJtjj�t|�dkr6|ddkr6tjj�q6Wydd�|D�}t	j
d
|��Stjj�YnXd	S)z�Convert an IPv4 address in text form to network form.

    @param text: The IPv4 address
    @type text: string
    @returns: string
    �.rrr�0cSsg|]}t|��qSr)�int)�.0�partrrr�
<listcomp>8szinet_aton.<locals>.<listcomp>�BBBBN)r)rrr
�splitrrr	r
�isdigit�struct�pack)�text�partsr�bytesrrr�	inet_aton%s


r)�__doc__rZ
dns.exceptionrZ_compatrrrrrrr�<module>s
PKj�\�f5���"__pycache__/entropy.cpython-36.pycnu�[���3

�b�Wq�@s�ddlZddlZddlZddlmZmZyddlZWnek
rPddl	ZYnXGdd�de
�Ze�Zyej
�ZWnek
r�dZYnXdd�Zdd	�ZdS)
�N�)�long�binary_typec@sHeZdZddd�Zddd�Zdd�Zd	d
�Zdd�Zd
d�Zdd�Z	dS)�EntropyPoolNcCs�d|_d|_d|_tj�|_yddl}|j�|_d|_	Wn^t
k
r�yddl}|j�|_d|_	Wn,t
k
r�ddl
}|j�|_d|_	YnXYnXtd|j	�|_|dk	r�|jt|��d|_tj�|_nd|_d|_dS)Nr���TF)�
pool_index�digest�	next_byte�
_threadingZLock�lock�hashlibZsha1�hash�hash_len�ImportError�sha�new�md5�	bytearray�pool�stir�seeded�os�getpid�seed_pid)�self�seedrrr�r�/usr/lib/python3.6/entropy.py�__init__s0





zEntropyPool.__init__FcCsr|s|jj�zNxH|D]@}|j|jkr,d|_|d@}|j|j|N<|jd7_qWWd|sl|jj�XdS)Nr�r)r
�acquirer	rr�release)rZentropyZalready_locked�c�brrrr7s

zEntropyPool.stircCs�|js|jtj�kr�ytjd�}Wn`tk
r�y*tddd�}z|jd�}Wd|j�XWn tk
r~t	t
j
��}YnXYnXd|_tj�|_d|_t|�}|j
|d�dS)Nrz/dev/urandom�rbrT)rrrr�urandom�	Exception�open�read�close�str�timer
rr)rr�rrrr�_maybe_seedEs 
zEntropyPool._maybe_seedc
Cs�|jj�zr|j�|jdks*|j|jkr`|jjt|j	��t
|jj��|_|j|jd�d|_|j|j}|jd7_Wd|jj�X|S)NTrr)
r
r"r/r
rrr�updaterrrrr#)r�valuerrr�random_8Xs
zEntropyPool.random_8cCs|j�d|j�S)N�)r2)rrrr�	random_16gszEntropyPool.random_16cCs|j�d|j�S)Ni)r4)rrrr�	random_32jszEntropyPool.random_32cCsl||d}|td�kr td��|dkr8|j}td�}n|dkrL|j}d}n
|j}d}|||�|dS)	Nrlztoo bigil��r3i��r!)r�
ValueErrorr5r4r2)r�first�last�sizeZrand�maxrrr�random_betweenms
zEntropyPool.random_between)N)F)
�__name__�
__module__�__qualname__r rr/r2r4r5r;rrrrrs

rcCs tdk	rtjdd�Stj�SdS)Nri)�
system_random�	randrangerr4rrrrr4�sr4cCs(tdk	rtj||d�Stj||�SdS)Nr)r?r@rr;)r7r8rrr�between�srA)rZrandomr-Z_compatrrZ	threadingrrZdummy_threading�objectrrZSystemRandomr?r(r4rArrrr�<module>sb
PKj�\b�CI"__pycache__/_compat.cpython-36.pycnu�[���3

�b�W!�@s�ddlZddlZddlmZejdkr0eZeZneZeZejd
krfeZ	e
ZefZe
Zdd�Zdd�Zn"eZ	eZefZeZdd�Zd	d�Zd
d�ZdS)�N)�Context�cCs|j�S)N)�decode)�x�r�/usr/lib/python3.6/_compat.py�maybe_decodesrcCs|j�S)N)�encode)rrrr�maybe_encodesr
cCs|S)Nr)rrrrrscCs|S)Nr)rrrrr
scCs,tttt|���tjd�jt|��}t|�S)z�
    Python 2 and Python 3 use different rounding strategies in round(). This
    function ensures that results are python2/3 compatible and backward
    compatible with previous py2 releases
    :param what: float
    :return: rounded long
    )ZprecZrounding)r�len�str�long�decimalZ
ROUND_HALF_UPZcreate_decimal)Zwhat�drrr�round_py2_compat#s


r)r)r)�sysrr�version_info�intr
�rangeZxrangerZ	text_type�bytesZbinary_typeZstring_types�chrZunichrrr
ZunicodeZ
basestringrrrrr�<module>s*


PKj�\pJ�ն�'__pycache__/update.cpython-36.opt-1.pycnu�[���3

�b�W'�@s`dZddlZddlZddlZddlZddlZddlZddlZddl	m
Z
Gdd�dejj�Z
dS)zDNS Dynamic Update Support�N�)�string_typescsxeZdZejjddejjf�fdd�	Zddd�Z	dd�Z
dd	�Zd
d�Zdd
�Z
dd�Zddd�Zd�fdd�	Z�ZS)�UpdateNcs�tt|�j�|jtjjtjj�O_t|t	�r>tj
j|�}||_t|t	�rZtj
j|�}||_|j|j|j|tjjddd�|dk	r�|j|||d�dS)a�Initialize a new DNS Update object.

        @param zone: The zone which is being updated.
        @type zone: A dns.name.Name or string
        @param rdclass: The class of the zone; defaults to dns.rdataclass.IN.
        @type rdclass: An int designating the class, or a string whose value
        is the name of a class.
        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @type keyname: dns.name.Name or string
        @param keyalgorithm: The TSIG algorithm to use; defaults to
        dns.tsig.default_algorithm.  Constants for TSIG algorithms are defined
        in dns.tsig, and the currently implemented algorithms are
        HMAC_MD5, HMAC_SHA1, HMAC_SHA224, HMAC_SHA256, HMAC_SHA384, and
        HMAC_SHA512.
        @type keyalgorithm: string
        T)ZcreateZforce_uniqueN)�	algorithm)�superr�__init__�flags�dnsZopcodeZto_flagsZUPDATE�
isinstancer�name�	from_text�origin�
rdataclass�zone_rdclass�
find_rrsetZquestion�	rdatatypeZSOAZuse_tsig)�selfZzoneZrdclassZkeyringZkeynameZkeyalgorithm)�	__class__��/usr/lib/python3.6/update.pyrs


zUpdate.__init__c	CsB|dkr|j}|j�}|j|||j|j||dd�}|j||�dS)z&Add a single RR to the update section.NT)�	authority�coversrr�rdtype�add)rr�ttl�rdZdeleting�sectionrZrrsetrrr�_add_rrEszUpdate._add_rrc
Gs:t|t�rtjj|d�}t|dtjj�rnx@|D]8}|rF|j||j�x |D]}|j	||j
||d�qLWq0Wn�t|�}t|j
d��}t|dtjj�r�|r�|j||dj�x�|D]}|j	||||d�q�Wnh|j
d�}t|t�r�tjj|�}|r�|j||�x6|D].}	tjj|j||	|j�}|j	||||d��qWdS)a�Add records.  The first argument is the replace mode.  If
        false, RRs are added to an existing RRset; if true, the RRset
        is replaced with the specified contents.  The second
        argument is the section to add to.  The third argument
        is always a name.  The other arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string...Nr)r)r
rr	rr�rdataset�Rdataset�deleterrr�list�int�pop�rdata�Rdatarrr
)
r�replacerr�args�rdsrrr�srrr�_addOs0






zUpdate._addcGs|jd|j|f|��dS)z�Add records.  The first argument is always a name.  The other
        arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string...FN)r*r)rrr'rrrrws	z
Update.addc	Gsft|t�rtjj|d�}t|�dkrR|j|j|tjj	tj
j	tj
jtj
j	dd��nt|dtjj
�r�x�|D]&}x |D]}|j|d|tjj�qtWqjWn�t|�}t|dtjj�r�x�|D]}|j|d|tjj�q�Wn�|jd�}t|t�r�tj
j|�}t|�dk�r(|j|j||j|tj
jtjj	dd�n:x8|D]0}tjj|j|||j�}|j|d|tjj��q.WdS)z�Delete records.  The first argument is always a name.  The other
        arguments can be:

                - I{nothing}

                - rdataset...

                - rdata...

                - rdtype, [string...]NrT)r
rr	rr�lenrrr�ANYr�NONErrrr!r$r%r#rr
)rrr'r(rrr)rrrr �s6








z
Update.deletecGs|jd|j|f|��dS)aQReplace records.  The first argument is always a name.  The other
        arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string...

        Note that if you want to replace the entire node, you should do
        a delete of the name followed by one or more calls to add.TN)r*r)rrr'rrrr&�s
zUpdate.replacec	Gs�t|t�rtjj|d�}t|�dkrL|j|j|tjj	tj
j	tj
jddd�n�t|dtjj
�s|t|dtjj�s|t|�dkr�t|dtjj
�s�t|�}|jdd�|jd|j|f|��n@|d}t|t�r�tj
j|�}|j|j|tjj	|tj
jddd�dS)aBRequire that an owner name (and optionally an rdata type,
        or specific rdataset) exists as a prerequisite to the
        execution of the update.  The first argument is always a name.
        The other arguments can be:

                - rdataset...

                - rdata...

                - rdtype, string...NrTrF)r
rr	rrr+r�answerrr,rr-rrr$r%r!�insertr*)rrr'rrrr�present�s*




zUpdate.presentc	Cs�t|t�rtjj|d�}|dkrH|j|j|tjjtj	j
tj	jddd�n8t|t�r^tj	j|�}|j|j|tjj|tj	jddd�dS)z�Require that an owner name (and optionally an rdata type) does
        not exist as a prerequisite to the execution of the update.NT)r
rr	rrrr.rr-rr,)rrrrrr�absent�s




z
Update.absent�cs |dkr|j}tt|�j||�S)zcReturn a string containing the update in DNS compressed wire
        format.
        @rtype: stringN)r
rr�to_wire)rr
Zmax_size)rrrr3�szUpdate.to_wire)NN)N)Nr2)�__name__�
__module__�__qualname__r	r�INZtsigZdefault_algorithmrrr*rr r&r0r1r3�
__classcell__rr)rrrs%

(+$
r)�__doc__Zdns.messager	Zdns.nameZ
dns.opcodeZ	dns.rdataZdns.rdataclassZdns.rdatasetZdns.tsigZ_compatr�messageZMessagerrrrr�<module>sPKj�\A��!__pycache__/opcode.cpython-36.pycnu�[���3

�b�W�	�@s�dZddlZdZdZdZdZdZeeeeed�Ze	dd	�ej
�D��ZGd
d�dejj
�Zdd
�Zdd�Zdd�Zdd�Zdd�ZdS)zDNS Opcodes.�N����)�QUERY�IQUERY�STATUS�NOTIFY�UPDATEccs|]\}}||fVqdS)N�)�.0�x�yrr�/usr/lib/python3.6/opcode.py�	<genexpr>&src@seZdZdZdS)�
UnknownOpcodezAn DNS opcode is unknown.N)�__name__�
__module__�__qualname__�__doc__rrrrr)srcCsB|j�r$t|�}|dkr$|dkr$|Stj|j��}|dkr>t�|S)z�Convert text into an opcode.

    @param text: the textual opcode
    @type text: string
    @raises UnknownOpcode: the opcode is unknown
    @rtype: int
    r�N)�isdigit�int�_by_text�get�upperr)�text�valuerrr�	from_text.s	rcCs|d@d?S)zUExtract an opcode from DNS message flags.

    @param flags: int
    @rtype: int
    ix�r)�flagsrrr�
from_flagsAsr!cCs|d>d@S)z`Convert an opcode to a value suitable for ORing into DNS message
    flags.
    @rtype: int
    rixr)rrrr�to_flagsKsr"cCstj|�}|dkrt|�}|S)z�Convert an opcode to text.

    @param value: the opcdoe
    @type value: int
    @raises UnknownOpcode: the opcode is unknown
    @rtype: string
    N)�	_by_valuer�str)rrrrr�to_textTs	
r%cCst|�tkS)znTrue if the opcode in flags is UPDATE.

    @param flags: DNS flags
    @type flags: int
    @rtype: bool
    )r!r
)r rrr�	is_updatecsr&)rZ
dns.exceptionZdnsrrrr	r
r�dict�itemsr#Z	exceptionZDNSExceptionrrr!r"r%r&rrrr�<module>s$
	PKj�\k���''#__pycache__/namedict.cpython-36.pycnu�[���3

�b�W]�@s6dZddlZddlZddlmZGdd�dej�ZdS)zDNS name dictionary�N�)�xrangec@sbeZdZdZdddgZdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dS)�NameDictaA dictionary whose keys are dns.name.Name objects.
    @ivar max_depth: the maximum depth of the keys that have ever been
    added to the dictionary.
    @type max_depth: int
    @ivar max_depth_items: the number of items of maximum depth
    @type max_depth_items: int
    �	max_depth�max_depth_itemsZ__storecOs(t�|_d|_d|_|jt||��dS)Nr)�dict�_NameDict__storerr�update)�self�args�kwargs�r
�/usr/lib/python3.6/namedict.py�__init__-szNameDict.__init__cCs>t|�|jkr|jd|_nt|�|jkr:t|�|_d|_dS)Nr)�lenrr)r
�keyr
r
rZ__update_max_depth3s

zNameDict.__update_max_depthcCs
|j|S)N)r)r
rr
r
r�__getitem__:szNameDict.__getitem__cCs.t|tjj�std��||j|<|j|�dS)NzNameDict key must be a name)�
isinstance�dns�name�Name�
ValueErrorr�_NameDict__update_max_depth)r
r�valuer
r
r�__setitem__=s
zNameDict.__setitem__cCsT|jj|�}t|�|jkr&|jd|_|jdkrPd|_x|jD]}|j|�q>WdS)Nrr)r�poprrrr)r
rr�kr
r
r�__delitem__Cs
zNameDict.__delitem__cCs
t|j�S)N)�iterr)r
r
r
r�__iter__LszNameDict.__iter__cCs
t|j�S)N)rr)r
r
r
r�__len__OszNameDict.__len__cCs
||jkS)N)r)r
rr
r
r�has_keyRszNameDict.has_keycCsnt|�}||jkr|j}x<t|d�D],}tjj||d��}||kr&|||fSq&W|tjj}tjj|fS)aFind the deepest match to I{name} in the dictionary.

        The deepest match is the longest name in the dictionary which is
        a superdomain of I{name}.

        @param name: the name
        @type name: dns.name.Name object
        @rtype: (key, value) tuple
        rN)rrrrrr�empty)r
r�depth�i�n�vr
r
r�get_deepest_matchUs
zNameDict.get_deepest_matchN)�__name__�
__module__�__qualname__�__doc__�	__slots__rrrrrrr r!r'r
r
r
rr!s
	r)r+�collectionsZdns.namerZ_compatr�MutableMappingrr
r
r
r�<module>sPKj�\0
�	��__pycache__/node.cpython-36.pycnu�[���3

�b�W��@s<dZddlmZddlZddlZddlZGdd�de�ZdS)z)DNS nodes.  A node is a set of rdatasets.�)�StringIONc@s�eZdZdZdgZdd�Zdd�Zdd�Zd	d
�Zdd�Z	d
d�Z
dd�Zej
jdfdd�Zej
jdfdd�Zej
jfdd�Zdd�ZdS)�Nodez�A DNS node.

    A node is a set of rdatasets

    @ivar rdatasets: the node's rdatasets
    @type rdatasets: list of dns.rdataset.Rdataset objects�	rdatasetscCs
g|_dS)zInitialize a DNS node.
        N)r)�self�r�/usr/lib/python3.6/node.py�__init__$sz
Node.__init__cKsPt�}x8|jD].}t|�dkr|j|j|f|��|jd�qW|j�dd�S)a+Convert a node to text format.

        Each rdataset at the node is printed.  Any keyword arguments
        to this method are passed on to the rdataset's to_text() method.
        @param name: the owner name of the rdatasets
        @type name: dns.name.Name object
        @rtype: string
        r�
N����)rr�len�write�to_text�getvalue)r�name�kw�s�rdsrrrr*s
zNode.to_textcCsdtt|��dS)Nz
<DNS node �>)�str�id)rrrr�__repr__;sz
Node.__repr__cCs@x|jD]}||jkrdSqWx|jD]}||jkr&dSq&WdS)zSTwo nodes are equal if they have the same rdatasets.

        @rtype: bool
        FT)r)r�otherZrdrrr�__eq__>s

zNode.__eq__cCs|j|�S)N)r)rrrrr�__ne__NszNode.__ne__cCs
t|j�S)N)rr)rrrr�__len__QszNode.__len__cCs
t|j�S)N)�iterr)rrrr�__iter__Tsz
Node.__iter__FcCsHx |jD]}|j|||�r|SqW|s*t�tjj||�}|jj|�|S)aFind an rdataset matching the specified properties in the
        current node.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.  Usually this value is
        dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
        dns.rdatatype.RRSIG, then the covers value will be the rdata
        type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
        types as if they were a family of
        types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
        easier to work with than if RRSIGs covering different rdata
        types were aggregated into a single RRSIG rdataset.
        @type covers: int
        @param create: If True, create the rdataset if it is not found.
        @type create: bool
        @raises KeyError: An rdataset of the desired type and class does
        not exist and I{create} is not True.
        @rtype: dns.rdataset.Rdataset object
        )r�match�KeyError�dns�rdataset�Rdataset�append)r�rdclass�rdtype�covers�createrrrr�
find_rdatasetWszNode.find_rdatasetcCs2y|j||||�}Wntk
r,d}YnX|S)aEGet an rdataset matching the specified properties in the
        current node.

        None is returned if an rdataset of the specified type and
        class does not exist and I{create} is not True.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.
        @type covers: int
        @param create: If True, create the rdataset if it is not found.
        @type create: bool
        @rtype: dns.rdataset.Rdataset object or None
        N)r(r)rr$r%r&r'rrrr�get_rdatasetys

zNode.get_rdatasetcCs&|j|||�}|dk	r"|jj|�dS)azDelete the rdataset matching the specified properties in the
        current node.

        If a matching rdataset does not exist, it is not an error.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.
        @type covers: int
        N)r)r�remove)rr$r%r&rrrr�delete_rdataset�szNode.delete_rdatasetcCs:t|tjj�std��|j|j|j|j�|j	j
|�dS)a8Replace an rdataset.

        It is not an error if there is no rdataset matching I{replacement}.

        Ownership of the I{replacement} object is transferred to the node;
        in other words, this method does not store a copy of I{replacement}
        at the node, it stores I{replacement} itself.
        zreplacement is not an rdatasetN)�
isinstancer r!r"�
ValueErrorr+r$r%r&rr#)rZreplacementrrr�replace_rdataset�s

zNode.replace_rdatasetN)�__name__�
__module__�__qualname__�__doc__�	__slots__rrrrrrrr Z	rdatatypeZNONEr(r)r+r.rrrrrs!r)	r2�iorZdns.rdatasetr Z
dns.rdatatypeZdns.renderer�objectrrrrr�<module>s
PKj�\�_DBII)__pycache__/__init__.cpython-36.opt-1.pycnu�[���3

�b�W/�#@sRdZddddddddd	d
ddd
ddddddddddddddddddd d!d"d#g#Zd$S)%zdnspython DNS toolkitZdnssecZe164ZednsZentropyZ	exception�flags�hashZinetZipv4Zipv6�message�nameZnamedictZnodeZopcodeZqueryZrcodeZrdataZ
rdataclassZrdatasetZ	rdatatypeZrendererZresolverZreversenameZrrset�setZ	tokenizerZtsigZtsigkeyringZttlZrdtypes�update�versionZwiredataZzoneN)�__doc__�__all__�r
r
�/usr/lib/python3.6/__init__.py�<module>sFPKj�\���	�	%__pycache__/rdataclass.cpython-36.pycnu�[���3

�b�W��@s�dZddlZddlZdZdZdZdZdZdZ	eeeeee	d�Z
ed	d
�e
j�D��Z
e
jeeed��ede	diZejd
ej�ZGdd�dejj�Zdd�Zdd�Zdd�ZdS)akDNS Rdata Classes.

@var _by_text: The rdata class textual name to value mapping
@type _by_text: dict
@var _by_value: The rdata class value to textual name mapping
@type _by_value: dict
@var _metaclasses: If an rdataclass is a metaclass, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _metaclasses: dict�N�����)�	RESERVED0�IN�CH�HS�NONE�ANYccs|]\}}||fVqdS)N�)�.0�x�yr
r
� /usr/lib/python3.6/rdataclass.py�	<genexpr>2sr)ZINTERNETZCHAOSZHESIODTzCLASS([0-9]+)$c@seZdZdZdS)�UnknownRdataclasszA DNS class is unknown.N)�__name__�
__module__�__qualname__�__doc__r
r
r
rrEsrcCsVtj|j��}|dkrRtj|�}|dkr,t�t|jd��}|dksJ|dkrRtd��|S)z�Convert text into a DNS rdata class value.
    @param text: the text
    @type text: string
    @rtype: int
    @raises dns.rdataclass.UnknownRdataclass: the class is unknown
    @raises ValueError: the rdata class value is not >= 0 and <= 65535
    Nrri��z'class must be between >= 0 and <= 65535)	�_by_text�get�upper�_unknown_class_pattern�matchr�int�group�
ValueError)�text�valuerr
r
r�	from_textJs	
r"cCs:|dks|dkrtd��tj|�}|dkr6dt|�}|S)z�Convert a DNS rdata class to text.
    @param value: the rdata class value
    @type value: int
    @rtype: string
    @raises ValueError: the rdata class value is not >= 0 and <= 65535
    ri��z'class must be between >= 0 and <= 65535NZCLASS)r�	_by_valuer�repr)r!r r
r
r�to_text^s
r%cCs|tkrdSdS)zmTrue if the class is a metaclass.
    @param rdclass: the rdata class
    @type rdclass: int
    @rtype: boolTF)�_metaclasses)Zrdclassr
r
r�is_metaclassnsr')r�reZ
dns.exceptionZdnsrrr	r
rrr�dict�itemsr#�updater&�compile�IrZ	exceptionZDNSExceptionrr"r%r'r
r
r
r�<module>s4
PKj�\�ȟ��%__pycache__/ipv6.cpython-36.opt-1.pycnu�[���3

�b�W��@s�dZddlZddlZddlZddlZddlmZmZm	Z	ej
d�Zdd�Zej
d�Z
ej
d	�Zej
d
�Zdd�ZdZdd�ZdS)zIPv6 helper functions.�N�)�xrange�binary_type�maybe_decodes
0+([0-9a-f]+)cCs�t|�dkrtd��tj|�}g}d}t|�}xJ||krx|||d�}tj|�}|dk	rd|jd�}|j|�|d7}q0Wd}d}d}	d}
xNtd�D]B}||d	kr�|
r�|}||	}||kr�|	}|}d}
q�|
s�|}	d
}
q�W|
�r�d}||	}||k�r�|	}|}|dk�r�|dk�rb|dk�s4|dk�rb|dd
k�rb|dk�rDd}
nd}
|
t	j
j|dd��}n,dj|d|��ddj|||d��}n
dj|�}t
|�S)z�Convert a network format IPv6 address into text.

    @param address: the binary address
    @type address: string
    @rtype: string
    @raises ValueError: the address isn't 16 bytes long
    �z IPv6 addresses are 16 bytes longr�NrF��0T��sffffs::s::ffff:��:���)�len�
ValueError�binasciiZhexlify�
_leading_zero�match�group�appendr�dns�ipv4�	inet_ntoa�joinr)�address�hex�chunks�i�l�chunk�mZ
best_startZbest_len�startZ
last_was_zero�endZcurrent_len�prefix�r$�/usr/lib/python3.6/ipv6.pyrs^	










rs(.*):(\d+\.\d+\.\d+\.\d+)$s::.*s.*::$c
Cs�t|t�s|j�}|dkrd}tj|�}|dk	rvttjj|j	d���}d|j	d�j
�|d|d|d|dfj�}tj|�}|dk	r�|dd�}ntj|�}|dk	r�|dd�}|j
d	�}t|�}|d
kr�tjj�d}g}x�|D]�}|dk�r.|�rtjj�d
}xftdd
|d�D]}|jd��qWq�t|�}	|	dk�rHtjj�|	dk�rbdd|	|}|j|�q�W|d
k�r�|�r�tjj�dj|�}y
tj|�Stjtfk
�r�tjj�YnXdS)z�Convert a text format IPv6 address into network format.

    @param text: the textual address
    @type text: string
    @rtype: string
    @raises dns.exception.SyntaxError: the text was not properly formatted
    s::s0::N�z%s:%02x%02x:%02x%02xrr�r
rF�Ts0000rr	r)�
isinstancer�encode�
_v4_endingr�	bytearrayrr�	inet_atonr�decode�_colon_colon_start�_colon_colon_end�splitrZ	exception�SyntaxErrorrrrrZ	unhexlify�Error�	TypeError)
�textr �brrZ
seen_emptyZ	canonical�crZlcr$r$r%r-bsR










r-��
s��cCs
|jt�S)N)�
startswith�_mapped_prefix)rr$r$r%�	is_mapped�sr<s
s��)�__doc__�rerZ
dns.exceptionrZdns.ipv4Z_compatrrr�compilerrr+r/r0r-r;r<r$r$r$r%�<module>s
C


GPKj�\�VJ��8�8*__pycache__/tokenizer.cpython-36.opt-1.pycnu�[���3

�b�W�G�@s�dZddlmZddlZddlZddlZddlZddlm	Z	m
Z
mZdddddddd�ZddiZ
dZdZd	Zd
ZdZdZd
ZGdd�dejj�ZGdd�de�ZGdd�de�ZdS)zTokenize DNS master file format�)�StringION�)�long�	text_type�binary_typeT)� �	�
�;�(�)�"r
�����c@seZdZdZdS)�UngetBufferFullzDAn attempt was made to unget a token when the unget buffer was full.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/tokenizer.pyr.src@s�eZdZdZd%dd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$S)&�Tokenz�A DNS master file format token.

    @ivar ttype: The token type
    @type ttype: int
    @ivar value: The token value
    @type value: string
    @ivar has_escape: Does the token value contain escapes?
    @type has_escape: bool
    �FcCs||_||_||_dS)aInitialize a token instance.

        @param ttype: The token type
        @type ttype: int
        @param value: The token value
        @type value: string
        @param has_escape: Does the token value contain escapes?
        @type has_escape: bool
        N)�ttype�value�
has_escape)�selfrrrrrr�__init__?s
zToken.__init__cCs
|jtkS)N)r�EOF)rrrr�is_eofMszToken.is_eofcCs
|jtkS)N)r�EOL)rrrr�is_eolPszToken.is_eolcCs
|jtkS)N)r�
WHITESPACE)rrrr�
is_whitespaceSszToken.is_whitespacecCs
|jtkS)N)r�
IDENTIFIER)rrrr�
is_identifierVszToken.is_identifiercCs
|jtkS)N)r�
QUOTED_STRING)rrrr�is_quoted_stringYszToken.is_quoted_stringcCs
|jtkS)N)r�COMMENT)rrrr�
is_comment\szToken.is_commentcCs
|jtkS)N)r�	DELIMITER)rrrr�is_delimiter_szToken.is_delimitercCs|jtkp|jtkS)N)rr#r!)rrrr�
is_eol_or_eofbszToken.is_eol_or_eofcCs&t|t�sdS|j|jko$|j|jkS)NF)�
isinstancerrr)r�otherrrr�__eq__es
zToken.__eq__cCs&t|t�sdS|j|jkp$|j|jkS)NT)r0rrr)rr1rrr�__ne__ks
zToken.__ne__cCsd|j|jfS)Nz%d "%s")rr)rrrr�__str__qsz
Token.__str__cCs|js
|Sd}t|j�}d}x�||kr�|j|}|d7}|dkr�||krPtjj�|j|}|d7}|j�r�||krztjj�|j|}|d7}||kr�tjj�|j|}|d7}|j�o�|j�s�tjj�tt	|�dt	|�dt	|��}||7}qWt
|j|�S)Nrrr�\�d�
)r�lenr�dns�	exception�
UnexpectedEnd�isdigit�SyntaxError�chr�intrr)rZ	unescaped�l�i�c�c2�c3rrr�unescapets6





$zToken.unescapecCsdS)Nrr)rrrr�__len__�sz
Token.__len__cCst|j|jf�S)N)�iterrr)rrrr�__iter__�szToken.__iter__cCs$|dkr|jS|dkr|jSt�dS)Nrr)rr�
IndexError)rrArrr�__getitem__�s
zToken.__getitem__N)rF)rrrrr r"r$r&r(r*r,r.r/r2r3r4rErFrHrJrrrrr3s"

rc@s�eZdZdZejdfdd�Zdd�Zdd�Zd	d
�Z	dd�Z
d(dd�Zdd�Zdd�Z
e
Zdd�Zdd�Zdd�Zdd�Zdd�Zd)dd�Zd*d d!�Zd+d"d#�Zd$d%�Zd&d'�ZdS),�	Tokenizera�A DNS master file format tokenizer.

    A token is a (type, value) tuple, where I{type} is an int, and
    I{value} is a string.  The valid types are EOF, EOL, WHITESPACE,
    IDENTIFIER, QUOTED_STRING, COMMENT, and DELIMITER.

    @ivar file: The file to tokenize
    @type file: file
    @ivar ungotten_char: The most recently ungotten character, or None.
    @type ungotten_char: string
    @ivar ungotten_token: The most recently ungotten token, or None.
    @type ungotten_token: (int, string) token tuple
    @ivar multiline: The current multiline level.  This value is increased
    by one every time a '(' delimiter is read, and decreased by one every time
    a ')' delimiter is read.
    @type multiline: int
    @ivar quoting: This variable is true if the tokenizer is currently
    reading a quoted string.
    @type quoting: bool
    @ivar eof: This variable is true if the tokenizer has encountered EOF.
    @type eof: bool
    @ivar delimiters: The current delimiter dictionary.
    @type delimiters: dict
    @ivar line_number: The current line number
    @type line_number: int
    @ivar filename: A filename that will be returned by the L{where} method.
    @type filename: string
    NcCs�t|t�r t|�}|dkr`d}n@t|t�rDt|j��}|dkr`d}n|dkr`|tjkr\d}nd}||_d|_d|_	d|_
d|_d|_t
|_d|_||_dS)a�Initialize a tokenizer instance.

        @param f: The file to tokenize.  The default is sys.stdin.
        This parameter may also be a string, in which case the tokenizer
        will take its input from the contents of the string.
        @type f: file or string
        @param filename: the name of the filename that the L{where} method
        will return.
        @type filename: string
        Nz<string>z<stdin>z<file>rFr)r0rrr�decode�sys�stdin�file�
ungotten_char�ungotten_token�	multiline�quoting�eof�_DELIMITERS�
delimiters�line_number�filename)r�frXrrrr �s*


zTokenizer.__init__cCsZ|jdkrJ|jrd}qV|jjd�}|dkr2d|_qV|dkrV|jd7_n|j}d|_|S)z<Read a character from input.
        @rtype: string
        NrrTr	)rPrTrO�readrW)rrBrrr�	_get_char�s
zTokenizer._get_charcCs|j|jfS)z�Return the current location in the input.

        @rtype: (string, int) tuple.  The first item is the filename of
        the input, the second is the current line number.
        )rXrW)rrrr�where�szTokenizer.wherecCs|jdk	rt�||_dS)aEUnget a character.

        The unget buffer for characters is only one character large; it is
        an error to try to unget a character when the unget buffer is not
        empty.

        @param c: the character to unget
        @type c: string
        @raises UngetBufferFull: there is already an ungotten char
        N)rPr)rrBrrr�_unget_chars
zTokenizer._unget_charcCsLd}xB|j�}|dkr<|dkr<|dks.|jr<|j|�|S|d7}qWdS)a(Consume input until a non-whitespace character is encountered.

        The non-whitespace character is then ungotten, and the number of
        whitespace characters consumed is returned.

        If the tokenizer is in multiline mode, then newlines are whitespace.

        @rtype: int
        rrrr	rN)r[rRr])r�skippedrBrrr�skip_whitespaces
zTokenizer.skip_whitespaceFc
CsT|jdk	r>|j}d|_|j�r(|r>|Sn|j�r:|r>|Sn|S|j�}|r\|dkr\ttd�Sd}t}d}�x�|j�}|dks�||jk�r|dkr�|j	r�t
jj�|dko�|t
k�r|dkr�|jd7_|j�ql�q|dk�r
|jdkr�t
jj�|jd8_|j�qln�|d	k�rH|j	�s0d
|_	t|_t
}qlnd|_	t|_|j�qln�|dk�r\ttd�S|dk�r�x,|j�}|dk�s�|dk�r�P||7}�qhW|�r�|j|�tt|�S|dk�r�|j�r�t
jjd
��tt�S|j�r�|j�d}qln
ttd�Sn|}t}n
|j|�P�n�|j	�r�|dk�r�|j�}|dk�r>t
jj�|j��r�|j�}|dk�rbt
jj�|j�}	|dk�r|t
jj�|j��o�|	j��s�t
jj�tt|�dt|�dt|	��}n|dk�rt
jjd��n:|dk�r||7}d
}|j�}|dk�s|dk�rt
jj�||7}qlW|dk�rH|t
k�rH|j�rDt
jjd
��t}t|||�S)aGet the next token.

        @param want_leading: If True, return a WHITESPACE token if the
        first character read is whitespace.  The default is False.
        @type want_leading: bool
        @param want_comment: If True, return a COMMENT token if the
        first token read is a comment.  The default is False.
        @type want_comment: bool
        @rtype: Token object
        @raises dns.exception.UnexpectedEnd: input ended prematurely
        @raises dns.exception.SyntaxError: input was badly formed
        NrrrFrrrr
Tr	r
zunbalanced parenthesesr5r6r7znewline in quoted string)rQr&r,r_rr%r'r[rVrSr9r:r;r)rRr=�_QUOTING_DELIMITERSrUr#r]r+r!r-r<r>r?)
rZwant_leadingZwant_comment�tokenr^rrrBrCrDrrr�get%s�
















&

z
Tokenizer.getcCs|jdk	rt�||_dS)a@Unget a token.

        The unget buffer for tokens is only one token large; it is
        an error to try to unget a token when the unget buffer is not
        empty.

        @param token: the token to unget
        @type token: Token object
        @raises UngetBufferFull: there is already an ungotten token
        N)rQr)rrarrr�unget�s
zTokenizer.ungetcCs|j�}|j�rt�|S)zLReturn the next item in an iteration.
        @rtype: (int, string)
        )rbr"�
StopIteration)rrarrr�next�szTokenizer.nextcCs|S)Nr)rrrrrH�szTokenizer.__iter__cCs@|j�j�}|j�s tjjd��|jj�s6tjjd��t|j�S)z|Read the next token and interpret it as an integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        zexpecting an identifierzexpecting an integer)	rbrEr(r9r:r=rr<r?)rrarrr�get_int�s
zTokenizer.get_intcCs,|j�}|dks|dkr(tjjd|��|S)z�Read the next token and interpret it as an 8-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        r�z#%d is not an unsigned 8-bit integer)rfr9r:r=)rrrrr�	get_uint8�s

zTokenizer.get_uint8cCs,|j�}|dks|dkr(tjjd|��|S)z�Read the next token and interpret it as a 16-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        ri��z$%d is not an unsigned 16-bit integer)rfr9r:r=)rrrrr�
get_uint16�s

zTokenizer.get_uint16cCsh|j�j�}|j�s tjjd��|jj�s6tjjd��t|j�}|dksT|td�krdtjjd|��|S)z�Read the next token and interpret it as a 32-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        zexpecting an identifierzexpecting an integerrlz$%d is not an unsigned 32-bit integer)	rbrEr(r9r:r=rr<r)rrarrrr�
get_uint32�s


zTokenizer.get_uint32cCs.|j�j�}|j�p|j�s(tjjd��|jS)z}Read the next token and interpret it as a string.

        @raises dns.exception.SyntaxError:
        @rtype: string
        zexpecting a string)rbrEr(r*r9r:r=r)r�originrarrr�
get_string�szTokenizer.get_stringcCs&|j�j�}|j�s tjjd��|jS)z�Read the next token and raise an exception if it is not an identifier.

        @raises dns.exception.SyntaxError:
        @rtype: string
        zexpecting an identifier)rbrEr(r9r:r=r)rrkrarrr�get_identifier
szTokenizer.get_identifiercCs,|j�}|j�stjjd��tjj|j|�S)z�Read the next token and interpret it as a DNS name.

        @raises dns.exception.SyntaxError:
        @rtype: dns.name.Name objectzexpecting an identifier)rbr(r9r:r=�name�	from_textr)rrkrarrr�get_nameszTokenizer.get_namecCs.|j�}|j�s(tjjd|j|jf��|jS)z�Read the next token and raise an exception if it isn't EOL or
        EOF.

        @raises dns.exception.SyntaxError:
        @rtype: string
        z expected EOL or EOF, got %d "%s")rbr/r9r:r=rr)rrarrr�get_eol!szTokenizer.get_eolcCs.|j�j�}|j�s tjjd��tjj|j�S)Nzexpecting an identifier)	rbrEr(r9r:r=Zttlror)rrarrr�get_ttl0szTokenizer.get_ttl)FF)N)N)N)rrrrrMrNr r[r\r]r_rbrcre�__next__rHrfrhrirjrlrmrprqrrrrrrrK�s($	
{



rK)r�iorrMZ
dns.exceptionr9Zdns.nameZdns.ttlZ_compatrrrrUr`r!r#r%r'r)r+r-r:ZDNSExceptionr�objectrrKrrrr�<module>s0oPKj�\k���'')__pycache__/namedict.cpython-36.opt-1.pycnu�[���3

�b�W]�@s6dZddlZddlZddlmZGdd�dej�ZdS)zDNS name dictionary�N�)�xrangec@sbeZdZdZdddgZdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dS)�NameDictaA dictionary whose keys are dns.name.Name objects.
    @ivar max_depth: the maximum depth of the keys that have ever been
    added to the dictionary.
    @type max_depth: int
    @ivar max_depth_items: the number of items of maximum depth
    @type max_depth_items: int
    �	max_depth�max_depth_itemsZ__storecOs(t�|_d|_d|_|jt||��dS)Nr)�dict�_NameDict__storerr�update)�self�args�kwargs�r
�/usr/lib/python3.6/namedict.py�__init__-szNameDict.__init__cCs>t|�|jkr|jd|_nt|�|jkr:t|�|_d|_dS)Nr)�lenrr)r
�keyr
r
rZ__update_max_depth3s

zNameDict.__update_max_depthcCs
|j|S)N)r)r
rr
r
r�__getitem__:szNameDict.__getitem__cCs.t|tjj�std��||j|<|j|�dS)NzNameDict key must be a name)�
isinstance�dns�name�Name�
ValueErrorr�_NameDict__update_max_depth)r
r�valuer
r
r�__setitem__=s
zNameDict.__setitem__cCsT|jj|�}t|�|jkr&|jd|_|jdkrPd|_x|jD]}|j|�q>WdS)Nrr)r�poprrrr)r
rr�kr
r
r�__delitem__Cs
zNameDict.__delitem__cCs
t|j�S)N)�iterr)r
r
r
r�__iter__LszNameDict.__iter__cCs
t|j�S)N)rr)r
r
r
r�__len__OszNameDict.__len__cCs
||jkS)N)r)r
rr
r
r�has_keyRszNameDict.has_keycCsnt|�}||jkr|j}x<t|d�D],}tjj||d��}||kr&|||fSq&W|tjj}tjj|fS)aFind the deepest match to I{name} in the dictionary.

        The deepest match is the longest name in the dictionary which is
        a superdomain of I{name}.

        @param name: the name
        @type name: dns.name.Name object
        @rtype: (key, value) tuple
        rN)rrrrrr�empty)r
r�depth�i�n�vr
r
r�get_deepest_matchUs
zNameDict.get_deepest_matchN)�__name__�
__module__�__qualname__�__doc__�	__slots__rrrrrrr r!r'r
r
r
rr!s
	r)r+�collectionsZdns.namerZ_compatr�MutableMappingrr
r
r
r�<module>sPKj�\����i�i%__pycache__/name.cpython-36.opt-1.pycnu�[���3

�Of�r�@s�dZddlmZddlZddlZddlZddlZyddlZdZ	Wne
k
rXdZ	YnXddlZddl
ZddlmZmZmZmZmZy
ejZWn.ek
r�ddejd	�>d
dZYnXdZdZd
ZdZdZGd
d�dejj�ZGdd�dejj�ZGdd�dejj �Z!Gdd�dejj �Z"Gdd�dejj#�Z$Gdd�dejj �Z%Gdd�dejj�Z&Gdd�dejj#�Z'Gdd�dejj#�Z(Gdd �d ejj#�Z)Gd!d"�d"ejj#�Z*Gd#d$�d$e+�Z,Gd%d&�d&e,�Z-Gd'd(�d(e,�Z.e/d)�Z0d*Z1e-d�Z2e-d�Z3e2Z4e.dddd�Z5e.dddd�Z6e.dddd�Z7e.dddd�Z8e5Z9d+d,�Z:d-d.�Z;d/d0�Z<Gd1d2�d2e+�Z=e=d3g�Z>e=g�Z?e>dfd4d5�Z@e>dfd6d7�ZAd8d9�ZBdS):z�DNS Names.

@var root: The DNS root name.
@type root: dns.name.Name object
@var empty: The empty DNS name.
@type empty: dns.name.Name object
�)�BytesIONTF�)�long�binary_type�	text_type�unichr�maybe_decode��P���c@seZdZdZdS)�
EmptyLabelzA DNS label is empty.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/name.pyr4src@seZdZdZdS)�	BadEscapez8An escaped code in a text format of DNS name is invalid.N)rrrrrrrrr9src@seZdZdZdS)�
BadPointerz=A DNS compression pointer points forward instead of backward.N)rrrrrrrrr>src@seZdZdZdS)�BadLabelTypez2The label type in DNS name wire format is unknown.N)rrrrrrrrrCsrc@seZdZdZdS)�NeedAbsoluteNameOrOriginzvAn attempt was made to convert a non-absolute name to
    wire when there was also a non-absolute (or missing) origin.N)rrrrrrrrrHsrc@seZdZdZdS)�NameTooLongz A DNS name is > 255 octets long.N)rrrrrrrrrNsrc@seZdZdZdS)�LabelTooLongz A DNS label is > 63 octets long.N)rrrrrrrrrSsrc@seZdZdZdS)�AbsoluteConcatenationz]An attempt was made to append anything other than the
    empty name to an absolute DNS name.N)rrrrrrrrrXsrc@seZdZdZdS)�NoParentzMAn attempt was made to get the parent of the root name
    or the empty name.N)rrrrrrrrr^src@seZdZdZdS)�
NoIDNA2008zLIDNA 2008 processing was requested but the idna module is not
    available.N)rrrrrrrrrcsrc@seZdZdZedg�ZdZdS)�
IDNAExceptionz$IDNA processing raised an exception.�idna_exceptionz+IDNA processing exception: {idna_exception}N)rrrr�setZsupp_kwargsZfmtrrrrris
rc@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�	IDNACodecz.Abstract base class for IDNA encoder/decoders.cCsdS)Nr)�selfrrr�__init__tszIDNACodec.__init__cCs|j�jd�S)Nsxn--)�lower�
startswith)r"�labelrrr�is_idnawszIDNACodec.is_idnacCs"x|D]}t|�dkrdSqWdS)N�FT)�ord)r"r&�crrr�is_all_asciizs
zIDNACodec.is_all_asciicCst�dS)N)�NotImplementedError)r"r&rrr�encode�szIDNACodec.encodecCs`|j|�rPy|dd�jd�}WqXtk
rL}zt|d��WYdd}~XqXXnt|�}t|�S)Nr
Zpunycode)r)r'�decode�	Exceptionrr�	_escapify)r"r&�errrr.�s
zIDNACodec.decodeN)	rrrrr#r'r+r-r.rrrrr!psr!cs6eZdZdZd	�fdd�	Zdd�Z�fdd�Z�ZS)
�
IDNA2003CodeczIDNA 2003 encoder/decoder.Fcstt|�j�||_dS)aInitialize the IDNA 2003 encoder/decoder.
        @param strict_decode: If True, then IDNA2003 checking is done when
        decoding.  This can cause failures if the name was encoded with
        IDNA2008.  The default is False.
        @type strict_decode: bool
        N)�superr2r#�
strict_decode)r"r4)�	__class__rrr#�szIDNA2003Codec.__init__cCs6|dkrdSytjj|�Stk
r0t�YnXdS)N��)�	encodings�idnaZToASCII�UnicodeErrorr)r"r&rrrr-�szIDNA2003Codec.encodecsd|jstt|�j|�S|dkr"dSyttjj|��Stk
r^}zt	|d��WYdd}~XnXdS)Nr7r6)r)
r4r3r2r.r0r8r9Z	ToUnicoder/r)r"r&r1)r5rrr.�szIDNA2003Codec.decode)F)rrrrr#r-r.�
__classcell__rr)r5rr2�s
r2cs6eZdZdZd	�fdd�	Zdd�Z�fdd�Z�ZS)
�
IDNA2008CodeczIDNA 2008 encoder/decoder.Fcs*tt|�j�||_||_||_||_dS)a�Initialize the IDNA 2008 encoder/decoder.
        @param uts_46: If True, apply Unicode IDNA compatibility processing
        as described in Unicode Technical Standard #46
        (U{http://unicode.org/reports/tr46/}).  This parameter is only
        meaningful if IDNA 2008 is in use.  If False, do not apply
        the mapping.  The default is False
        @type uts_46: bool
        @param transitional: If True, use the "transitional" mode described
        in Unicode Technical Standard #46.  This parameter is only
        meaningful if IDNA 2008 is in use.  The default is False.
        @type transitional: bool
        @param allow_pure_ascii: If True, then a label which
        consists of only ASCII characters is allowed.  This is less strict
        than regular IDNA 2008, but is also necessary for mixed names,
        e.g. a name with starting with "_sip._tcp." and ending in an IDN
        suffixm which would otherwise be disallowed.  The default is False
        @type allow_pure_ascii: bool
        @param strict_decode: If True, then IDNA2008 checking is done when
        decoding.  This can cause failures if the name was encoded with
        IDNA2003.  The default is False.
        @type strict_decode: bool
        N)r3r<r#�uts_46�transitional�allow_pure_asciir4)r"r=r>r?r4)r5rrr#�s
zIDNA2008Codec.__init__cCs�|dkrdS|jr&|j|�r&|jd�Sts.t�y |jrFtj|d|j�}tj	|�Stj
k
r|}zt|d��WYdd}~XnXdS)Nr6r7�asciiF)r)r?r+r-�have_idna_2008rr=r9�uts46_remapr>Zalabel�	IDNAErrorr)r"r&r1rrrr-�s

zIDNA2008Codec.encodecs�|jstt|�j|�S|dkr"dSts*t�y"|jr@tj|dd�}t	tj
|��Stjk
rz}zt|d��WYdd}~XnXdS)Nr7r6F)r)
r4r3r<r.rArr=r9rBr0ZulabelrCr)r"r&r1)r5rrr.�szIDNA2008Codec.decode)FFFF)rrrrr#r-r.r;rr)r5rr<�s
r<s"().;\@$z"().;\@$cCs�t|t�rzd}t|t�r |j�}xTt|�D]H}|tkrH|dt|�7}q*|dkrf|dkrf|t|�7}q*|d|7}q*W|Sd}xD|D]<}|tkr�|d|7}q�|dkr�|dt|�7}q�||7}q�W|S)zaEscape the characters in label which need it.
    @returns: the escaped string
    @rtype: stringr6�\� r(z\%03d� )	�
isinstance�bytesrr-�	bytearray�_escaped�chr�
_escaped_textr))r&�textr*rrrr0�s&


r0cCs�t|�}d}d}d}xH|D]@}t|�}||d7}|dkr>t�|dkrR|dkrR|}|d7}qW|dkrjt�|dkr�||dkr�t�dS)a/Check for empty labels in the middle of a label sequence,
    labels that are too long, and for too many labels.
    @raises NameTooLong: the name as a whole is too long
    @raises EmptyLabel: a label is empty (i.e. the root label) and appears
    in a position other than the end of the label sequencerr�?r7�N���)�lenrrr)�labels�l�total�i�jr&Zllrrr�_validate_labelss 
rWcCs(t|t�r|St|t�r |j�St�dS)N)rGrrr-�
ValueError)r&rrr�
_ensure_bytes/s


rYcsDeZdZdZdgZ�fdd�Zdd�Zdd�Zd	d
�Zdd�Z	�fd
d�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�ZdLd.d/�ZdMd1d2�ZdNd3d4�ZdOd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d?d@�Z"dAdB�Z#dCdD�Z$dEdF�Z%dPdHdI�Z&dJdK�Z'�Z(S)Q�Namez�A DNS name.

    The dns.name.Name class represents a DNS name as a tuple of labels.
    Instances of the class are immutable.

    @ivar labels: The tuple of labels in the name. Each label is a string of
    up to 63 octets.rRcs2dd�|D�}tt|�jdt|��t|j�dS)z�Initialize a domain name from a list of labels.
        @param labels: the labels
        @type labels: any iterable whose values are strings
        cSsg|]}t|��qSr)rY)�.0�xrrr�
<listcomp>Hsz!Name.__init__.<locals>.<listcomp>rRN)r3rZ�__setattr__�tuplerWrR)r"rR)r5rrr#Csz
Name.__init__cCstd��dS)Nz+object doesn't support attribute assignment)�	TypeError)r"�name�valuerrrr^LszName.__setattr__cCs
t|j�S)N)rZrR)r"rrr�__copy__Osz
Name.__copy__cCsttj|j|��S)N)rZ�copy�deepcopyrR)r"�memorrr�__deepcopy__RszName.__deepcopy__cCs
d|jiS)NrR)rR)r"rrr�__getstate__UszName.__getstate__cs$tt|�jd|d�t|j�dS)NrR)r3rZr^rWrR)r"�state)r5rr�__setstate__XszName.__setstate__cCst|j�dko|jddkS)zXIs the most significant label of this name the root label?
        @rtype: bool
        rrr7rP)rQrR)r"rrr�is_absolute\szName.is_absolutecCst|j�dko|jddkS)z\Is this name wild?  (I.e. Is the least significant label '*'?)
        @rtype: bool
        r�*)rQrR)r"rrr�is_wildcszName.is_wildcCsJtd�}x4|jD]*}x$t|j��D]}||d>|7}q"WqWt|t�S)zHReturn a case-insensitive hash of the name.
        @rtype: int
        rr)rrRrIr$�int�maxint)r"�hr&r*rrr�__hash__js
z
Name.__hash__c
Cs*|j�}|j�}||kr0|r&tddfStddfSt|j�}t|j�}||}|dkrZ|}n|}d}d}	t}
x�|dkr�|d8}|d8}|d8}|j|j�}|j|j�}||kr�d}|	dkr�t}
|
||	fS||kr�d}|	dkr�t}
|
||	fS|	d7}	qlW|}|dk�rt}
n|dk�rt}
nt}
|
||	fS)a�Compare two names, returning a 3-tuple (relation, order, nlabels).

        I{relation} describes the relation ship between the names,
        and is one of: dns.name.NAMERELN_NONE,
        dns.name.NAMERELN_SUPERDOMAIN, dns.name.NAMERELN_SUBDOMAIN,
        dns.name.NAMERELN_EQUAL, or dns.name.NAMERELN_COMMONANCESTOR

        I{order} is < 0 if self < other, > 0 if self > other, and ==
        0 if self == other.  A relative name is always less than an
        absolute name.  If both names have the same relativity, then
        the DNSSEC order relation is used to order them.

        I{nlabels} is the number of significant labels that the two names
        have in common.
        rrrPrP)	rk�
NAMERELN_NONErQrRr$�NAMERELN_COMMONANCESTOR�NAMERELN_SUPERDOMAIN�NAMERELN_SUBDOMAIN�NAMERELN_EQUAL)
r"�otherZsabsZoabs�l1�l2ZldiffrS�orderZnlabelsZnamerelnZlabel1Zlabel2rrr�fullcompareusN








zName.fullcomparecCs(|j|�\}}}|tks |tkr$dSdS)zoIs self a subdomain of other?

        The notion of subdomain includes equality.
        @rtype: bool
        TF)r{rurv)r"rw�nr�o�nlrrr�is_subdomain�szName.is_subdomaincCs(|j|�\}}}|tks |tkr$dSdS)zqIs self a superdomain of other?

        The notion of subdomain includes equality.
        @rtype: bool
        TF)r{rtrv)r"rwr|r}r~rrr�is_superdomain�szName.is_superdomaincCstdd�|jD��S)z�Return a name which is equal to the current name, but is in
        DNSSEC canonical form.
        @rtype: dns.name.Name object
        cSsg|]}|j��qSr)r$)r[r\rrrr]�sz%Name.canonicalize.<locals>.<listcomp>)rZrR)r"rrr�canonicalize�szName.canonicalizecCs$t|t�r|j|�ddkSdSdS)NrrF)rGrZr{)r"rwrrr�__eq__�s
zName.__eq__cCs$t|t�r|j|�ddkSdSdS)NrrT)rGrZr{)r"rwrrr�__ne__�s
zName.__ne__cCs$t|t�r|j|�ddkStSdS)Nrr)rGrZr{�NotImplemented)r"rwrrr�__lt__�s
zName.__lt__cCs$t|t�r|j|�ddkStSdS)Nrr)rGrZr{r�)r"rwrrr�__le__�s
zName.__le__cCs$t|t�r|j|�ddkStSdS)Nrr)rGrZr{r�)r"rwrrr�__ge__�s
zName.__ge__cCs$t|t�r|j|�ddkStSdS)Nrr)rGrZr{r�)r"rwrrr�__gt__�s
zName.__gt__cCsd|j�dS)Nz
<DNS name �>)�__str__)r"rrr�__repr__�sz
Name.__repr__cCs
|jd�S)NF)�to_text)r"rrrr��szName.__str__FcCspt|j�dkrtd�St|j�dkr:|jddkr:td�S|rV|j�rV|jdd�}n|j}djtt|��}|S)	z�Convert name to text format.
        @param omit_final_dot: If True, don't emit the final dot (denoting the
        root label) for absolute names.  The default is False.
        @rtype: string
        r�@rr7�.N�.rP)rQrRrrk�join�mapr0)r"�omit_final_dotrS�srrrr��szName.to_textNcsxt|j�dkrdSt|j�dkr2|jddkr2dS|rN|j�rN|jdd	�}n|j}�dkr`t�dj�fdd�|D��S)
a�Convert name to Unicode text format.

        IDN ACE labels are converted to Unicode.

        @param omit_final_dot: If True, don't emit the final dot (denoting the
        root label) for absolute names.  The default is False.
        @type omit_final_dot: bool
        @param idna_codec: IDNA encoder/decoder.  If None, the
        IDNA_2003_Practical encoder/decoder is used.  The IDNA_2003_Practical
        decoder does not impose any policy, it just decodes punycode, so if
        you don't want checking for compliance, you can use this decoder for
        IDNA2008 as well.
        @type idna_codec: dns.name.IDNA
        @rtype: string
        r�@rr7r�Ncsg|]}�j|��qSr)r.)r[r\)�
idna_codecrrr])sz#Name.to_unicode.<locals>.<listcomp>rP)rQrRrk�IDNA_2003_Practicalr�)r"r�r�rSr)r�r�
to_unicodeszName.to_unicodecCsX|j�s:|dks|j�rt�t|j�}|jt|j��n|j}dd�|D�}dj|�S)aConvert name to a format suitable for digesting in hashes.

        The name is canonicalized and converted to uncompressed wire format.

        @param origin: If the name is relative and origin is not None, then
        origin will be appended to it.
        @type origin: dns.name.Name object
        @raises NeedAbsoluteNameOrOrigin: All names in wire format are
        absolute.  If self is a relative name, then an origin must be supplied;
        if it is missing, then this exception is raised
        @rtype: string
        NcSs*g|]"}tjdt|�t|�|j���qS)z!B%ds)�struct�packrQr$)r[r\rrrr]@sz&Name.to_digestable.<locals>.<listcomp>r7)rkr�listrR�extendr�)r"�originrRZdlabelsrrr�
to_digestable+s
zName.to_digestablec
Cs.|dkrt�}d}nd}|j�sR|dks2|j�r6t�t|j�}|jt|j��n|j}d}x�|D]�}t||d��}|d7}|dk	r�|j|�}	nd}	|	dk	r�d|	}
tj	d|
�}|j
|�Pqb|dk	r�t|�dkr�|j�}	|	dkr�|	||<t|�}|j
tj	d	|��|dkrb|j
|�qbW|�r*|j
�SdS)
a�Convert name to wire format, possibly compressing it.

        @param file: the file where the name is emitted (typically
        a BytesIO file).  If None, a string containing the wire name
        will be returned.
        @type file: file or None
        @param compress: The compression table.  If None (the default) names
        will not be compressed.
        @type compress: dict
        @param origin: If the name is relative and origin is not None, then
        origin will be appended to it.
        @type origin: dns.name.Name object
        @raises NeedAbsoluteNameOrOrigin: All names in wire format are
        absolute.  If self is a relative name, then an origin must be supplied;
        if it is missing, then this exception is raised
        NTFrri�z!Hi�?z!B)rrkrr�rRr�rZ�getr�r��writerQ�tell�getvalue)
r"�file�compressr�Zwant_returnrRrUr&�n�posrbr�rSrrr�to_wireDs@


zName.to_wirecCs
t|j�S)z@The length of the name (in labels).
        @rtype: int
        )rQrR)r"rrr�__len__|szName.__len__cCs
|j|S)N)rR)r"�indexrrr�__getitem__�szName.__getitem__cCs
|j|�S)N)�concatenate)r"rwrrr�__add__�szName.__add__cCs
|j|�S)N)�
relativize)r"rwrrr�__sub__�szName.__sub__cCsnt|j�}|dkr|tjjfS||kr2tjj|fS|dksB||krJtd��t|d|��t||d��fS)a(Split a name into a prefix and suffix at depth.

        @param depth: the number of labels in the suffix
        @type depth: int
        @raises ValueError: the depth was not >= 0 and <= the length of the
        name.
        @returns: the tuple (prefix, suffix)
        @rtype: tuple
        rz0depth must be >= 0 and <= the length of the nameN)rQrR�dnsra�emptyrXrZ)r"�depthrSrrr�split�s
z
Name.splitcCs:|j�rt|�dkrt�t|j�}|jt|j��t|�S)z�Return a new name which is the concatenation of self and other.
        @rtype: dns.name.Name object
        @raises AbsoluteConcatenation: self is absolute and other is
        not the empty name
        r)rkrQrr�rRr�rZ)r"rwrRrrrr��s

zName.concatenatecCs0|dk	r(|j|�r(t|dt|���S|SdS)z�If self is a subdomain of origin, return a new name which is self
        relative to origin.  Otherwise return self.
        @rtype: dns.name.Name object
        N)rrZrQ)r"r�rrrr��szName.relativizecCs|j�s|j|�S|SdS)z�If self is a relative name, return a new name which is the
        concatenation of self and origin.  Otherwise return self.
        @rtype: dns.name.Name object
        N)rkr�)r"r�rrr�derelativize�s
zName.derelativizeTcCs&|r|r|j|�S|j|�Sn|SdS)aReturn a name with the relativity desired by the caller.  If
        origin is None, then self is returned.  Otherwise, if
        relativize is true the name is relativized, and if relativize is
        false the name is derelativized.
        @rtype: dns.name.Name object
        N)r�r�)r"r�r�rrr�choose_relativity�s

zName.choose_relativitycCs&|tks|tkrt�t|jdd��S)z�Return the parent of the name.
        @rtype: dns.name.Name object
        @raises NoParent: the name is either the root name or the empty name,
        and thus has no parent.
        rN)�rootr�rrZrR)r"rrr�parent�szName.parent)F)FN)N)NNN)NT))rrrr�	__slots__r#r^rcrgrhrjrkrmrqr{rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r;rr)r5rrZ7sJ	=



8

rZr7c	Cs�t|t�std��|dkp"t|t�s,td��g}d}d}d}d}|dkrLt}|dkrXd}|�rz|dkrptd	g�Sx�|D]�}|r�|dkr�|j�r�t|�}|d
7}q�||7}d}n@|j�s�t�|d9}|t|�7}|d
7}|dkr�d}|t|�7}qv|dk�r"t	|�dk�rt
�|j|j|��d}qv|dk�r:d}d}d}qv||7}qvW|�rPt�t	|�dk�rp|j|j|��n
|jd	�t	|�dk�s�|dd	k�r�|dk	�r�|j
t|j��t|�S)a�Convert unicode text into a Name object.

    Labels are encoded in IDN ACE form.

    @param text: The text to convert into a name.
    @type text: Unicode string
    @param origin: The origin to append to non-absolute names.
    @type origin: dns.name.Name
    @param idna_codec: IDNA encoder/decoder.  If None, the default IDNA 2003
    encoder/decoder is used.
    @type idna_codec: dns.name.IDNA
    @rtype: dns.name.Name object
    z0input to from_unicode() must be a unicode stringNzorigin must be a Name or Noner6Frr�r�r7r�
r�。�.�。rDT)r�r�r�r�rP)rGrrXrZ�	IDNA_2003�isdigitrnrrrQr�appendr-r�r�rR)	rMr�r�rRr&�escaping�edigitsrTr*rrr�from_unicode�sd






&r�c
Cs�t|t�rt|||�St|t�s(td��|dkp8t|t�sBtd��g}d}d}d}d}|dkrbd}|�r�|dkrztdg�Sx�t|�D]�}tjd	|�}	|�r|dkr�|	j	�r�t
|	�}|d
7}n||	7}d}nF|	j	�s�t�|d9}|t
|	�7}|d
7}|dk�r^d}|tjd	|�7}q�|	dk�r>t|�dk�r.t
�|j|�d}q�|	d
k�rVd}d}d}q�||	7}q�W|�rlt�t|�dk�r�|j|�n
|jd�t|�dk�s�|ddk�r�|dk	�r�|jt|j��t|�S)a}Convert text into a Name object.

    @param text: The text to convert into a name.
    @type text: string
    @param origin: The origin to append to non-absolute names.
    @type origin: dns.name.Name
    @param idna_codec: IDNA encoder/decoder.  If None, the default IDNA 2003
    encoder/decoder is used.
    @type idna_codec: dns.name.IDNA
    @rtype: dns.name.Name object
    z%input to from_text() must be a stringNzorigin must be a Name or Noner7Frr�r�z!Brr�r�\TrP)rGrr�rrXrZrIr�r�r�rnrrQrr�r�r�rR)
rMr�r�rRr&r�r�rTr*Zbyte_rrr�	from_text*sf








&r�cCst|t�std��tjj|�}g}|}d}||}|d7}d}x�|dkr�|dkr�|j||||�j��||7}|dkr�||7}nJ|dkr�|d@d||}|dkr�|d7}||kr�t�|}|d7}nt	�||}|d7}|dkr@|d7}q@W|jd�t
|�|fS)	a^Convert possibly compressed wire format into a Name.
    @param message: the entire DNS message
    @type message: string
    @param current: the offset of the beginning of the name from the start
    of the message
    @type current: int
    @raises dns.name.BadPointer: a compression pointer did not point backwards
    in the message
    @raises dns.name.BadLabelType: an invalid label type was encountered.
    @returns: a tuple consisting of the name that was read and the number
    of bytes of the wire format message which were consumed reading it
    @rtype: (dns.name.Name object, int) tuple
    z*input to from_wire() must be a byte stringrr�@�rN�r6)rGrrXr�ZwiredataZ
maybe_wrapr�ZunwraprrrZ)�messageZcurrentrRZbiggest_pointerZhops�countZcusedrrr�	from_wireps<




r�)Cr�iorr��sysrdZencodings.idnar8r9rA�ImportErrorZ
dns.exceptionr�Zdns.wiredataZ_compatrrrrrro�AttributeError�calcsizerrrtrurvrsZ	exception�SyntaxErrorrrZ	FormErrorrrZDNSExceptionrrrrrrr�objectr!r2r<rIrJrLr�ZIDNA_2003_Strictr�ZIDNA_2008_PracticalZIDNA_2008_UTS_46ZIDNA_2008_StrictZIDNA_2008_TransitionalZ	IDNA_2008r0rWrYrZr�r�r�r�r�rrrr�<module>st

  >*
HFPKj�\���"		%__pycache__/inet.cpython-36.opt-1.pycnu�[���3

�b�W��@sjdZddlZddlZddlZejZy
ejZWnek
rDdZYnXdd�Zdd�Z	dd	�Z
d
d�ZdS)z*Generic Internet address helper functions.�Ni'cCs0|tkrtjj|�S|tkr(tjj|�St�dS)a*Convert the textual form of a network address into its binary form.

    @param family: the address family
    @type family: int
    @param text: the textual address
    @type text: string
    @raises NotImplementedError: the address family specified is not
    implemented.
    @rtype: string
    N)�AF_INET�dns�ipv4�	inet_aton�AF_INET6�ipv6�NotImplementedError)�family�text�r�/usr/lib/python3.6/inet.py�	inet_pton&s
r
cCs0|tkrtjj|�S|tkr(tjj|�St�dS)a/Convert the binary form of a network address into its textual form.

    @param family: the address family
    @type family: int
    @param address: the binary address
    @type address: string
    @raises NotImplementedError: the address family specified is not
    implemented.
    @rtype: string
    N)rrrZ	inet_ntoarrr)r	Zaddressrrr�	inet_ntop:s
rcCsLytjj|�tStk
rFytjj|�tSt�YnXYnXdS)z�Determine the address family of a textual-form network address.

    @param text: the textual address
    @type text: string
    @raises ValueError: the address family cannot be determined from the input.
    @rtype: int
    N)rrrr�	Exceptionrr�
ValueError)r
rrr�af_for_addressMsrcCsty$ttjj|�d�}|dko$|dkStk
rnyttjj|�d�}|dkStk
rht�YnXYnXdS)z�Is the textual-form network address a multicast address?

    @param text: the textual address
    @raises ValueError: the address family cannot be determined from the input.
    @rtype: bool
    r�����N)�ordrrrrrr)r
�firstrrr�is_multicast`sr)�__doc__ZsocketZdns.ipv4rZdns.ipv6rr�AttributeErrorr
rrrrrrr�<module>s

PKj�\��şDD$__pycache__/exception.cpython-36.pycnu�[���3

d��W�@shdZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZGd	d
�d
e�ZGdd�de�Zd
S)zCommon DNS Exceptions.csReZdZdZdZe�ZdZ�fdd�Zdd�Z	dd�Z
d	d
�Z�fdd�Z�Z
S)
�DNSExceptiona�Abstract base class shared by all dnspython exceptions.

    It supports two basic modes of operation:

    a) Old/compatible mode is used if __init__ was called with
    empty **kwargs.
    In compatible mode all *args are passed to standard Python Exception class
    as before and all *args are printed by standard __str__ implementation.
    Class variable msg (or doc string if msg is None) is returned from str()
    if *args is empty.

    b) New/parametrized mode is used if __init__ was called with
    non-empty **kwargs.
    In the new mode *args has to be empty and all kwargs has to exactly match
    set in class variable self.supp_kwargs. All kwargs are stored inside
    self.kwargs and used in new __str__ implementation to construct
    formatted message based on self.fmt string.

    In the simplest case it is enough to override supp_kwargs and fmt
    class variables to get nice parametrized messages.
    Ncsp|j||�|r*|jf|�|_t|�|_nt�|_|jdkrD|j|_|rZtt|�j	|�ntt|�j	|j�dS)N)
�
_check_params�
_check_kwargs�kwargs�str�msg�dict�__doc__�superr�__init__)�self�argsr)�	__class__��/usr/lib/python3.6/exception.pyr
.s
zDNSException.__init__cOs$|s|r t|�t|�ks td��dS)zsOld exceptions supported only args and not kwargs.

        For sanity we do not allow to mix old and new behavior.z=keyword arguments are mutually exclusive with positional argsN)�bool�AssertionError)rrrrrrr=szDNSException._check_paramscKs(|r$t|j��|jks$td|j��|S)Nz-following set of keyword args is required: %s)�set�keys�supp_kwargsr)rrrrrrEs

zDNSException._check_kwargscKshi}x^|j�D]R\}}t|ttf�rXttt|��||<t||�dkr`||j�||<q|||<qW|S)z�Format kwargs before printing them.

        Resulting dictionary has to have keys necessary for str.format call
        on fmt class variable.
        �)�items�
isinstance�listr�mapr�len�pop)rr�fmtargs�kw�datarrr�_fmt_kwargsLszDNSException._fmt_kwargscs:|jr(|jr(|jf|j�}|jjf|�Stt|�j�SdS)N)r�fmtr�formatr	r�__str__)rr)r
rrr"^szDNSException.__str__)�__name__�
__module__�__qualname__rrrrr r
rrrr"�
__classcell__rr)r
rrsrc@seZdZdZdS)�	FormErrorzDNS message is malformed.N)r#r$r%rrrrrr'hsr'c@seZdZdZdS)�SyntaxErrorzText input is malformed.N)r#r$r%rrrrrr(msr(c@seZdZdZdS)�
UnexpectedEndzText input ended unexpectedly.N)r#r$r%rrrrrr)rsr)c@seZdZdZdS)�TooBigzThe DNS message is too big.N)r#r$r%rrrrrr*wsr*c@seZdZdZedg�ZdZdS)�TimeoutzThe DNS operation timed out.Ztimeoutz3The DNS operation timed out after {timeout} secondsN)r#r$r%rrrr rrrrr+|s
r+N)r�	Exceptionrr'r(r)r*r+rrrr�<module>sUPKj�\{��_��__pycache__/set.cpython-36.pycnu�[���3

�b�W#�@sdZGdd�de�ZdS)zA simple Set class.c@seZdZdZdgZdDdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Z d<d=�Z!d>d?�Z"d@dA�Z#dBdC�Z$dS)E�Seta'A simple set class.

    Sets are not in Python until 2.3, and rdata are not immutable so
    we cannot use sets.Set anyway.  This class implements subset of
    the 2.3 Set interface using a list as the container.

    @ivar items: A list of the items which are in the set
    @type items: list�itemsNcCs*g|_|dk	r&x|D]}|j|�qWdS)zvInitialize the set.

        @param items: the initial set of items
        @type items: any iterable or None
        N)r�add)�selfr�item�r�/usr/lib/python3.6/set.py�__init__ s
zSet.__init__cCsdt|j�S)Nzdns.simpleset.Set(%s))�reprr)rrrr�__repr__,szSet.__repr__cCs||jkr|jj|�dS)zAdd an item to the set.N)r�append)rrrrrr/s
zSet.addcCs|jj|�dS)zRemove an item from the set.N)r�remove)rrrrrr4sz
Set.removecCs*y|jj|�Wntk
r$YnXdS)z'Remove an item from the set if present.N)rr�
ValueError)rrrrr�discard8szSet.discardcCs |j}|j|�}t|j�|_|S)a�Make a (shallow) copy of the set.

        There is a 'clone protocol' that subclasses of this class
        should use.  To make a copy, first call your super's _clone()
        method, and use the object returned as the new instance.  Then
        make shallow copies of the attributes defined in the subclass.

        This protocol allows us to write the set algorithms that
        return new instances (e.g. union) once, and keep using them in
        subclasses.
        )�	__class__�__new__�listr)r�cls�objrrr�_clone?s

z
Set._clonecCs|j�S)z!Make a (shallow) copy of the set.)r)rrrr�__copy__QszSet.__copy__cCs|j�S)z!Make a (shallow) copy of the set.)r)rrrr�copyUszSet.copycCs<t|t�std��||krdSx|jD]}|j|�q&WdS)z�Update the set, adding any elements from other which are not
        already in the set.
        @param other: the collection of items with which to update the set
        @type other: Set object
        zother must be a Set instanceN)�
isinstancerr
rr)r�otherrrrr�union_updateYs
zSet.union_updatecCsLt|t�std��||krdSx(t|j�D]}||jkr*|jj|�q*WdS)z�Update the set, removing any elements from other which are not
        in both sets.
        @param other: the collection of items with which to update the set
        @type other: Set object
        zother must be a Set instanceN)rrr
rrr)rrrrrr�intersection_updatefs

zSet.intersection_updatecCs@t|t�std��||kr"g|_nx|jD]}|j|�q*WdS)z�Update the set, removing any elements from other which are in
        the set.
        @param other: the collection of items with which to update the set
        @type other: Set object
        zother must be a Set instanceN)rrr
rr)rrrrrr�difference_updatevs
zSet.difference_updatecCs|j�}|j|�|S)z�Return a new set which is the union of I{self} and I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        )rr)rrrrrr�union�s
z	Set.unioncCs|j�}|j|�|S)z�Return a new set which is the intersection of I{self} and I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        )rr)rrrrrr�intersection�s
zSet.intersectioncCs|j�}|j|�|S)z�Return a new set which I{self} - I{other}, i.e. the items
        in I{self} which are not also in I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        )rr)rrrrrr�
difference�s	
zSet.differencecCs
|j|�S)N)r)rrrrr�__or__�sz
Set.__or__cCs
|j|�S)N)r)rrrrr�__and__�szSet.__and__cCs
|j|�S)N)r)rrrrr�__add__�szSet.__add__cCs
|j|�S)N)r)rrrrr�__sub__�szSet.__sub__cCs|j|�|S)N)r)rrrrr�__ior__�s
zSet.__ior__cCs|j|�|S)N)r)rrrrr�__iand__�s
zSet.__iand__cCs|j|�|S)N)r)rrrrr�__iadd__�s
zSet.__iadd__cCs|j|�|S)N)r)rrrrr�__isub__�s
zSet.__isub__cCsx|D]}|j|�qWdS)z�Update the set, adding any elements from other which are not
        already in the set.
        @param other: the collection of items with which to update the set
        @type other: any iterable typeN)r)rrrrrr�update�s
z
Set.updatecCs
g|_dS)zMake the set empty.N)r)rrrr�clear�sz	Set.clearcCs@x|jD]}||jkrdSqWx|jD]}||jkr&dSq&WdS)NFT)r)rrrrrr�__eq__�s

z
Set.__eq__cCs|j|�S)N)r))rrrrr�__ne__�sz
Set.__ne__cCs
t|j�S)N)�lenr)rrrr�__len__�szSet.__len__cCs
t|j�S)N)�iterr)rrrr�__iter__�szSet.__iter__cCs
|j|S)N)r)r�irrr�__getitem__�szSet.__getitem__cCs|j|=dS)N)r)rr/rrr�__delitem__�szSet.__delitem__cCs4t|t�std��x|jD]}||jkrdSqWdS)z?Is I{self} a subset of I{other}?

        @rtype: bool
        zother must be a Set instanceFT)rrr
r)rrrrrr�issubset�s

zSet.issubsetcCs4t|t�std��x|jD]}||jkrdSqWdS)zAIs I{self} a superset of I{other}?

        @rtype: bool
        zother must be a Set instanceFT)rrr
r)rrrrrr�
issuperset�s

zSet.issuperset)N)%�__name__�
__module__�__qualname__�__doc__�	__slots__rr
rrrrrrrrrrrrrr r!r"r#r$r%r&r'r(r)r*r,r.r0r1r2r3rrrrrsD	



rN)r7�objectrrrrr�<module>sPKj�\]���5�5&__pycache__/query.cpython-36.opt-1.pycnu�[���3

�Of�L�@s�dZddlmZddlZddlZddlZddlZddlZddlZddl	Z
ddlZ
ddlZ
ddl
Z
ddlZ
ddlZ
ddlmZmZejd/kr�eZnejZejZGdd�de
jj�ZGd	d
�d
e
jj�Zdd�Zd
d�Zdd�Zdd�Z dd�Z!e"ed�r�ea#nea#dd�Z$dd�Z%dd�Z&dd�Z'dd�Z(d0d"d#�Z)d$d%�Z*d&d'�Z+d(d)�Z,d1d*d+�Z-e
j.j/e
j0j1dd ddd,dddddd!e
j2j3fd-d.�Z4dS)2zTalk to a DNS server.�)�
generatorsN�)�long�string_types�c@seZdZdZdS)�UnexpectedSourcez=A DNS query response came from an unexpected address or port.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/query.pyr,src@seZdZdZdS)�BadResponsez<A DNS query response does not respond to the question asked.N)rr	r
rrrrr
r1srcCs|dkrdStj�|SdS)N)�time)�timeoutrrr
�_compute_expiration6srcCsjd}|r|tjO}|r |tjO}|r.|tjO}tj�}|j||�|rZ|jt|d��}n|j�}t|�S)aqPoll polling backend.
    @param fd: File descriptor
    @type fd: int
    @param readable: Whether to wait for readability
    @type readable: bool
    @param writable: Whether to wait for writability
    @type writable: bool
    @param timeout: Deadline timeout (expiration time, in seconds)
    @type timeout: float
    @return True on success, False on timeout
    ri�)�selectZPOLLINZPOLLOUTZPOLLERR�poll�registerr�bool)�fd�readable�writable�errorrZ
event_maskZpollableZ
event_listrrr
�	_poll_for=s


rcCsrggg}}}|r|g}|r$|g}|r.|g}|dkrLtj|||�\}}	}
ntj||||�\}}	}
t|pn|	pn|
�S)asSelect polling backend.
    @param fd: File descriptor
    @type fd: int
    @param readable: Whether to wait for readability
    @type readable: bool
    @param writable: Whether to wait for writability
    @type writable: bool
    @param timeout: Deadline timeout (expiration time, in seconds)
    @type timeout: float
    @return True on success, False on timeout
    N)rr)rrrrrZrsetZwsetZxsetZrcountZwcountZxcountrrr
�_select_for\srcCs�d}x�|s�|dkrd}n|tj�}|dkr4tjj�yt|||||�sNtjj�Wn6tk
r�}z|jdtjkrv|�WYdd}~XnXd}qWdS)NFgrT)	r�dns�	exceptionZTimeout�_polling_backend�select_error�args�errnoZEINTR)rrrr�
expiration�doner�errr
�	_wait_forysr%cCs|adS)z#
    Internal API. Do not use.
    N)r)�fnrrr
�_set_polling_backend�sr'rcCst|ddd|�dS)NTF)r%)�sr"rrr
�_wait_for_readable�sr)cCst|ddd|�dS)NFT)r%)r(r"rrr
�_wait_for_writable�sr*cCsDtjj||d�}tjj||d�}||koB|dd�|dd�kS)Nrr)r�inetZ	inet_pton)�afZa1Za2Zn1Zn2rrr
�_addresses_equal�sr-cCs`|sdSt|||�s<tjj|d�r@|dd�|dd�kr@dS|rHdStd|�d|����dS)NTrrFzgot a response from z instead of )r-rr+Zis_multicastr)r,�from_address�destination�ignore_unexpectedrrr
�_matches_destination�s(r1cCs�|dkr6ytjj|�}Wntk
r4tjj}YnX|tjjkrp||f}|dk	sZ|dkr�|dkrfd}||f}n@|tjjkr�||ddf}|dk	s�|dkr�|dkr�d}||ddf}|||fS)Nrz0.0.0.0z::)rr+Zaf_for_address�	ExceptionZAF_INETZAF_INET6)r,�where�port�source�source_portr/rrr
�_destination_and_source�s$
r7�5Fc
Cs"|j�}
t|||||�\}}}t|tjd�}d}
z�t|�}|jd�|dk	rV|j|�t||�t	j	�}
|j
|
|�x�t||�|jd�\}
}t
|j|||�s�qvt	j	�|
}y"tjj|
|j|j|d�}||_	Wntk
r�|	r�wvn�YnX|j|��r�|S|	�rqvqvt�qvWWd|j�XdS)a�Return the response obtained after sending a query via UDP.

    @param q: the query
    @type q: dns.message.Message
    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param timeout: The number of seconds to wait before the query times out.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @rtype: dns.message.Message object
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param ignore_unexpected: If True, ignore responses from unexpected
    sources.  The default is False.
    @type ignore_unexpected: bool
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    rNi��)�keyring�request_mac�one_rr_per_rrset)�to_wirer7�socket_factory�socket�
SOCK_DGRAMr�setblocking�bindr*rZsendtor)�recvfromr1Zfamilyr�message�	from_wirer9�macr2�is_responser�close)�qr3rr4r,r5r6r0r;�
ignore_errors�wirer/r(�
begin_timer"r.�
response_time�rrrr
�udp�sD




rNcCsJd}x@|dkrDt||�|j|�}|dkr.t�|t|�}||}qW|S)z�Read the specified number of bytes from sock.  Keep trying until we
    either get the desired amount, or we hit EOF.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    �r)r)Zrecv�EOFError�len)�sock�countr"r(�nrrr
�	_net_reads


rUcCs>d}t|�}x,||kr8t||�||j||d��7}qWdS)z�Write the specified data to the socket.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    rN)rQr*�send)rR�datar"Zcurrent�lrrr
�
_net_write/s


rYcCspy|j|�Wn\tjk
rjtj�dd�\}}t|d�rF|j}n|d}|tjtjtj	gkrf|�YnXdS)N�r!r)
Zconnectr>r�sys�exc_info�hasattrr!ZEINPROGRESSZEWOULDBLOCKZEALREADY)r(ZaddressZty�vZv_errrrr
�_connect;s
r_cCs|j�}t|||||�\}}	}t|tjd�}
d}z�t|�}|
jd�tj�}|dk	r^|
j|�t	|
|	�t
|�}
tjd|
�|}t
|
||�t|
d|�}tjd|�\}
t|
|
|�}Wd|dkr�d}ntj�|}|
j�Xtjj||j|j|d�}||_|j|��st�|S)aReturn the response obtained after sending a query via TCP.

    @param q: the query
    @type q: dns.message.Message object
    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param timeout: The number of seconds to wait before the query times out.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @rtype: dns.message.Message object
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    rNz!HrZ)r9r:r;)r<r7r=r>�SOCK_STREAMrr@rrAr_rQ�struct�packrYrU�unpackrGrrCrDr9rErFr)rHr3rr4r,r5r6r;rJr/r(rKr"rX�tcpmsg�ldatarLrMrrr
�tcpIs8



rfTc&cs�t|t�rtjj|�}t|t�r,tjj|�}tjj|||�}|tjjkrltj	j|dddd|
�}|j
j|�|dk	r�|j|||d�|j
�}t|	||||�\}	}}|r�|tjjkr�td��t|	tjd�}nt|	tjd�}|jd�|dk	r�|j|�t|
�}t||�t|�}|�r*t||�|j|�ntjd|�|}t|||�d	}d
}d	}d}|�rj|}tjj}nd}|}d}d
}�x6|�s�t|�} | dk�s�|dk	�r�| |k�r�|} |�r�t||�|j d�\}}!n&t!|d| �}"tj"d|"�\}t!||| �}|tjjk}#tjj#||j$|j%d
||d
||#d
�	}$|$j&}d	}d}%|dk�r�|$j'�sV|$j'dj|k�rbtj(j)d��|$j'd}|j*tjj+k�r�tj(j)d��d}%|j,�}|tjjk�r�|dj-|
k�r�d
}nd
}x�|$j'|%d�D]�}|�r�tj(j)d��|j*tjj+k�rl|j|k�rl|�r&|dj-|
k�r tj(j)d��d	}n|tjjk�r:|}||k�r~|tjj.k�sf|tjjk�r~|�r~d
}n|�r�tjj.}d	}�q�W|�r�|j$�r�|$j/�r�tj(j)d��|$V�q~W|j0�dS)a�Return a generator for the responses to a zone transfer.

    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param zone: The name of the zone to transfer
    @type zone: dns.name.Name object or string
    @param rdtype: The type of zone transfer.  The default is
    dns.rdatatype.AXFR.
    @type rdtype: int or string
    @param rdclass: The class of the zone transfer.  The default is
    dns.rdataclass.IN.
    @type rdclass: int or string
    @param timeout: The number of seconds to wait for each response message.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param keyring: The TSIG keyring to use
    @type keyring: dict
    @param keyname: The name of the TSIG key to use
    @type keyname: dns.name.Name object or string
    @param relativize: If True, all names in the zone will be relativized to
    the zone origin.  It is essential that the relativize setting matches
    the one specified to dns.zone.from_xfr().
    @type relativize: bool
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @param lifetime: The total number of seconds to spend doing the transfer.
    If None, the default, then there is no limit on the time the transfer may
    take.
    @type lifetime: float
    @rtype: generator of dns.message.Message objects.
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param serial: The SOA serial number to use as the base for an IXFR diff
    sequence (only meaningful if rdtype == dns.rdatatype.IXFR).
    @type serial: int
    @param use_udp: Use UDP (only meaningful for IXFR)
    @type use_udp: bool
    @param keyalgorithm: The TSIG algorithm to use; defaults to
    dns.tsig.default_algorithm
    @type keyalgorithm: string
    r�IN�SOAz. . %u 0 0 0 0N)�	algorithmzcannot do a UDP AXFRz!HFTi��rZ)r9r:�xfr�origin�tsig_ctxZmulti�firstr;z No answer or RRset not for qnamezfirst RRset is not an SOArzanswers after final SOAzIXFR base serial mismatchzmissing TSIG)1�
isinstancerr�nameZ	from_text�	rdatatyperCZ
make_queryZIXFR�rrsetZ	authority�appendZuse_tsigr<r7�
ValueErrorr=r>r?r`r@rArr_rQr*rVrarbrY�emptyr)rBrUrcrDr9rErlZanswerr�	FormError�rdtyperh�copy�serial�AXFRZhad_tsigrG)&r3ZzonervZrdclassrr4r9ZkeynameZ
relativizer,Zlifetimer5r6rxZuse_udpZkeyalgorithmrHrqrJr/r(r"rXrdr#Zdelete_modeZ
expecting_SOAZ	soa_rrsetrkZonamerlrmZmexpirationr.reZis_ixfrrMZanswer_indexrrr
rj�s�5














rj)r)Nr8NNrFFF)Nr8NNrF)5rZ
__future__rr!rr>rar[rZ
dns.exceptionrZdns.inetZdns.nameZdns.messageZdns.rdataclassZ
dns.rdatatypeZ_compatrr�version_info�OSErrorrrr=rZDNSExceptionrrurrrrr%r'r]rr)r*r-r1r7rNrUrYr_rfrpryZ
rdataclassrgZtsigZdefault_algorithmrjrrrr
�<module>sX

	
I
?

PKj�\��M�((__pycache__/ttl.cpython-36.pycnu�[���3

�b�W��@s8dZddlZddlmZGdd�dejj�Zdd�ZdS)	zDNS TTL conversion.�N�)�longc@seZdZdZdS)�BadTTLz!DNS TTL value is not well-formed.N)�__name__�
__module__�__qualname__�__doc__�r	r	�/usr/lib/python3.6/ttl.pyrsrcCs*|j�rt|�}n�|dj�s"t�td�}td�}x�|D]�}|j�rZ|d9}|t|�7}q8|j�}|dkr|||td�7}nl|dkr�||td�7}nR|dkr�||td�7}n8|d	kr�||td
�7}n|dkr�||7}ntd|��d}q8W|dk�std
��|td�k�s|td�k�r&td��|S)z�Convert the text form of a TTL to an integer.

    The BIND 8 units syntax for TTLs (e.g. '1w6d4h3m10s') is supported.

    @param text: the textual TTL
    @type text: string
    @raises dns.ttl.BadTTL: the TTL is not well-formed
    @rtype: int
    r�
�wi�:	�di�Q�hi�m�<�szunknown unit '%s'ztrailing integeri���z0TTL should be between 0 and 2^31 - 1 (inclusive))�isdigitrr�lower)�textZtotalZcurrent�cr	r	r
�	from_texts8



r)	rZ
dns.exceptionZdnsZ_compatrZ	exception�SyntaxErrorrrr	r	r	r
�<module>sPKj�\�8�Yww&__pycache__/rrset.cpython-36.opt-1.pycnu�[���3

�$�Wk�@sldZddlZddlZddlZddlZddlmZGdd�dejj	�Z
ddd�Zd	d
�Zddd�Z
d
d�ZdS)z)DNS RRsets (an RRset is a named rdataset)�N�)�string_typescs�eZdZdZddgZejjdf�fdd�	Z�fdd�Z	d	d
�Z
dd�Z�fd
d�Zd�fdd�	Z
d�fdd�	Zd�fdd�	Zdd�Z�ZS)�RRseta6A DNS RRset (named rdataset).

    RRset inherits from Rdataset, and RRsets can be treated as
    Rdatasets in most cases.  There are, however, a few notable
    exceptions.  RRsets have different to_wire() and to_text() method
    arguments, reflecting the fact that RRsets always have an owner
    name.
    �name�deletingNcs$tt|�j|||�||_||_dS)zCreate a new RRset.N)�superr�__init__rr)�selfr�rdclass�rdtype�coversr)�	__class__��/usr/lib/python3.6/rrset.pyr'szRRset.__init__cs"tt|�j�}|j|_|j|_|S)N)rr�_clonerr)r	�obj)r
rrr/szRRset._clonecCs�|jdkrd}ndtjj|j�d}|jdk	rDdtjj|j�}nd}dt|j�dtjj|j�dtjj|j	�||dS)	Nr��(�)z delete=z<DNS � z RRset>)
r�dns�	rdatatype�to_textr�
rdataclass�strrr
r)r	ZctextZdtextrrr�__repr__5s

zRRset.__repr__cCs|j�S)N)r)r	rrr�__str__Bsz
RRset.__str__cs.t|t�sdS|j|jkrdStt|�j|�S)zcTwo RRsets are equal if they have the same name and the same
        rdataset

        @rtype: boolF)�
isinstancerrr�__eq__)r	�other)r
rrrEs

zRRset.__eq__cs4tt|�j|||�sdS|j|ks,|j|kr0dSdS)zaReturns True if this rrset matches the specified class, type,
        covers, and deletion state.FT)rr�matchrr)r	rr
rrr)r
rrr Ps
zRRset.matchTcstt|�j|j|||jf|�S)a�Convert the RRset into DNS master file format.

        @see: L{dns.name.Name.choose_relativity} for more information
        on how I{origin} and I{relativize} determine the way names
        are emitted.

        Any additional keyword arguments are passed on to the rdata
        to_text() method.

        @param origin: The origin for relative names, or None.
        @type origin: dns.name.Name object
        @param relativize: True if names should names be relativized
        @type relativize: bool)rrrrr)r	�originZ
relativize�kw)r
rrrZsz
RRset.to_textcs tt|�j|j||||jf|�S)z!Convert the RRset to wire format.)rr�to_wirerr)r	�file�compressr!r")r
rrr#lsz
RRset.to_wirecCstjj|jt|��S)zYConvert an RRset into an Rdataset.

        @rtype: dns.rdataset.Rdataset object
        )r�rdataset�from_rdata_list�ttl�list)r	rrr�to_rdatasetrszRRset.to_rdataset)N)NT)NN)�__name__�
__module__�__qualname__�__doc__�	__slots__rrZNONErrrrrr rr#r*�
__classcell__rr)r
rrs	

rc	Cs�t|t�rtjj|d|d�}t|t�r2tjj|�}t|t�rHtjj|�}t|||�}|j|�x*|D]"}tj	j|j
|j|�}|j|�qdW|S)z�Create an RRset with the specified name, TTL, class, and type, and with
    the specified list of rdatas in text format.

    @rtype: dns.rrset.RRset object
    N)�
idna_codec)
rrrr�	from_textrrr�
update_ttlZrdatar
r�add)	rr(r
r�text_rdatasr1�r�t�rdrrr�from_text_listzs




r9cGst|||||�S)z�Create an RRset with the specified name, TTL, class, and type and with
    the specified rdatas in text format.

    @rtype: dns.rrset.RRset object
    )r9)rr(r
rr5rrrr2�sr2cCsrt|t�rtjj|d|d�}t|�dkr0td��d}x8|D]0}|dkr`t||j|j	�}|j
|�|j|�q:W|S)z�Create an RRset with the specified name and TTL, and with
    the specified list of rdata objects.

    @rtype: dns.rrset.RRset object
    N)r1rzrdata list must not be empty)rrrrr2�len�
ValueErrorrr
rr3r4)rr(�rdatasr1r6r8rrrr'�s


r'cGst|||�S)z�Create an RRset with the specified name and TTL, and with
    the specified rdata objects.

    @rtype: dns.rrset.RRset object
    )r')rr(r<rrr�
from_rdata�sr=)N)N)r.Zdns.namerZdns.rdatasetZdns.rdataclassZdns.rendererZ_compatrr&ZRdatasetrr9r2r'r=rrrr�<module>sa


PKj�\�pp���$__pycache__/rdatatype.cpython-36.pycnu�[���3

��W��F@s0dZddlZddlZdZdZdZdZdZdZ	dZ
d	Zd
ZdZ
dZd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/d.Z0d/Z1d0Z2d1Z3d2Z4d3Z5d4Z6d5Z7d6Z8d7Z9d8Z:d9Z;d:Z<d;Z=d<Z>d=Z?d>Z@d?ZAd@ZBdAZCdBZDdCZEdDZFdEZGdFZHeeeeee	e
eee
eeeeeeeeeeeeeeeeeee e!e"e#e$e%e&e'e(e)e*e+e,e-e.e/e0e1e2e3e4e5e6e7e8e9e:e;e<e=e>e?e@eAeBeCeDeEeFeGeHdG�EZIeJdHdI�eIjK�D��ZLe)dJiZMe
dJe"dJe(dJe/dJiZNejOdKejP�ZQGdLdM�dMejRjS�ZTdNdO�ZUdPdQ�ZVdRdS�ZWdTdU�ZXdS)VaDNS Rdata Types.

@var _by_text: The rdata type textual name to value mapping
@type _by_text: dict
@var _by_value: The rdata type value to textual name mapping
@type _by_value: dict
@var _metatypes: If an rdatatype is a metatype, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _metatypes: dict
@var _singletons: If an rdatatype is a singleton, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _singletons: dict�N���������	�
���
������������������!�#�$�%�&�'�)�*�+�,�-�.�/�0�1�2�3�4�7�;�<�>�c�g�l�m��������iii�i�)E�NONE�A�NS�MD�MF�CNAME�SOA�MB�MG�MR�NULL�WKS�PTR�HINFO�MINFO�MX�TXT�RP�AFSDB�X25�ISDN�RT�NSAPzNSAP-PTR�SIG�KEY�PX�GPOS�AAAA�LOC�NXT�SRV�NAPTR�KX�CERT�A6�DNAME�OPT�APL�DS�SSHFP�IPSECKEY�RRSIG�NSEC�DNSKEY�DHCID�NSEC3�
NSEC3PARAM�TLSA�HIP�CDS�CDNSKEY�CSYNC�SPF�UNSPEC�EUI48�EUI64�TKEY�TSIG�IXFR�AXFR�MAILB�MAILA�ANY�URI�CAA�AVC�TA�DLVccs|]\}}||fVqdS)N�)�.0�x�yr�r��/usr/lib/python3.6/rdatatype.py�	<genexpr>�sr�Tz
TYPE([0-9]+)$c@seZdZdZdS)�UnknownRdatatypez$DNS resource record type is unknown.N)�__name__�
__module__�__qualname__�__doc__r�r�r�r�r��sr�cCsVtj|j��}|dkrRtj|�}|dkr,t�t|jd��}|dksJ|dkrRtd��|S)z�Convert text into a DNS rdata type value.
    @param text: the text
    @type text: string
    @raises dns.rdatatype.UnknownRdatatype: the type is unknown
    @raises ValueError: the rdata type value is not >= 0 and <= 65535
    @rtype: intNrri��z&type must be between >= 0 and <= 65535)	�_by_text�get�upper�_unknown_type_pattern�matchr��int�group�
ValueError)�text�valuer�r�r�r��	from_text�s
r�cCs:|dks|dkrtd��tj|�}|dkr6dt|�}|S)z�Convert a DNS rdata type to text.
    @param value: the rdata type value
    @type value: int
    @raises ValueError: the rdata type value is not >= 0 and <= 65535
    @rtype: stringri��z&type must be between >= 0 and <= 65535NZTYPE)r��	_by_valuer��repr)r�r�r�r�r��to_text�s
r�cCs |tkr|tks|tkrdSdS)zbTrue if the type is a metatype.
    @param rdtype: the type
    @type rdtype: int
    @rtype: boolTF)rzr��
_metatypes)�rdtyper�r�r��is_metatype�sr�cCs|tkrdSdS)zcTrue if the type is a singleton.
    @param rdtype: the type
    @type rdtype: int
    @rtype: boolTF)�_singletons)r�r�r�r��is_singleton�sr�)Yr��reZ
dns.exceptionZdnsrBrCrDrErFrGrHrIrJrKrLrMrNrOrPrQrRrSrTrUrVrWrXZNSAP_PTRrYrZr[r\r]r^r_r`rarbrcrdrerfrgrhrirjrkrlrmrnrorprqrrrsrtrurvrwrxryrzr{r|r}r~rr�r�r�r�r�r�r��dict�itemsr�r�r��compile�Ir�Z	exceptionZDNSExceptionr�r�r�r�r�r�r�r�r��<module>s0PKj�\�pp���*__pycache__/rdatatype.cpython-36.opt-1.pycnu�[���3

��W��F@s0dZddlZddlZdZdZdZdZdZdZ	dZ
d	Zd
ZdZ
dZd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/d.Z0d/Z1d0Z2d1Z3d2Z4d3Z5d4Z6d5Z7d6Z8d7Z9d8Z:d9Z;d:Z<d;Z=d<Z>d=Z?d>Z@d?ZAd@ZBdAZCdBZDdCZEdDZFdEZGdFZHeeeeee	e
eee
eeeeeeeeeeeeeeeeeee e!e"e#e$e%e&e'e(e)e*e+e,e-e.e/e0e1e2e3e4e5e6e7e8e9e:e;e<e=e>e?e@eAeBeCeDeEeFeGeHdG�EZIeJdHdI�eIjK�D��ZLe)dJiZMe
dJe"dJe(dJe/dJiZNejOdKejP�ZQGdLdM�dMejRjS�ZTdNdO�ZUdPdQ�ZVdRdS�ZWdTdU�ZXdS)VaDNS Rdata Types.

@var _by_text: The rdata type textual name to value mapping
@type _by_text: dict
@var _by_value: The rdata type value to textual name mapping
@type _by_value: dict
@var _metatypes: If an rdatatype is a metatype, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _metatypes: dict
@var _singletons: If an rdatatype is a singleton, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _singletons: dict�N���������	�
���
������������������!�#�$�%�&�'�)�*�+�,�-�.�/�0�1�2�3�4�7�;�<�>�c�g�l�m��������iii�i�)E�NONE�A�NS�MD�MF�CNAME�SOA�MB�MG�MR�NULL�WKS�PTR�HINFO�MINFO�MX�TXT�RP�AFSDB�X25�ISDN�RT�NSAPzNSAP-PTR�SIG�KEY�PX�GPOS�AAAA�LOC�NXT�SRV�NAPTR�KX�CERT�A6�DNAME�OPT�APL�DS�SSHFP�IPSECKEY�RRSIG�NSEC�DNSKEY�DHCID�NSEC3�
NSEC3PARAM�TLSA�HIP�CDS�CDNSKEY�CSYNC�SPF�UNSPEC�EUI48�EUI64�TKEY�TSIG�IXFR�AXFR�MAILB�MAILA�ANY�URI�CAA�AVC�TA�DLVccs|]\}}||fVqdS)N�)�.0�x�yr�r��/usr/lib/python3.6/rdatatype.py�	<genexpr>�sr�Tz
TYPE([0-9]+)$c@seZdZdZdS)�UnknownRdatatypez$DNS resource record type is unknown.N)�__name__�
__module__�__qualname__�__doc__r�r�r�r�r��sr�cCsVtj|j��}|dkrRtj|�}|dkr,t�t|jd��}|dksJ|dkrRtd��|S)z�Convert text into a DNS rdata type value.
    @param text: the text
    @type text: string
    @raises dns.rdatatype.UnknownRdatatype: the type is unknown
    @raises ValueError: the rdata type value is not >= 0 and <= 65535
    @rtype: intNrri��z&type must be between >= 0 and <= 65535)	�_by_text�get�upper�_unknown_type_pattern�matchr��int�group�
ValueError)�text�valuer�r�r�r��	from_text�s
r�cCs:|dks|dkrtd��tj|�}|dkr6dt|�}|S)z�Convert a DNS rdata type to text.
    @param value: the rdata type value
    @type value: int
    @raises ValueError: the rdata type value is not >= 0 and <= 65535
    @rtype: stringri��z&type must be between >= 0 and <= 65535NZTYPE)r��	_by_valuer��repr)r�r�r�r�r��to_text�s
r�cCs |tkr|tks|tkrdSdS)zbTrue if the type is a metatype.
    @param rdtype: the type
    @type rdtype: int
    @rtype: boolTF)rzr��
_metatypes)�rdtyper�r�r��is_metatype�sr�cCs|tkrdSdS)zcTrue if the type is a singleton.
    @param rdtype: the type
    @type rdtype: int
    @rtype: boolTF)�_singletons)r�r�r�r��is_singleton�sr�)Yr��reZ
dns.exceptionZdnsrBrCrDrErFrGrHrIrJrKrLrMrNrOrPrQrRrSrTrUrVrWrXZNSAP_PTRrYrZr[r\r]r^r_r`rarbrcrdrerfrgrhrirjrkrlrmrnrorprqrrrsrtrurvrwrxryrzr{r|r}r~rr�r�r�r�r�r�r��dict�itemsr�r�r��compile�Ir�Z	exceptionZDNSExceptionr�r�r�r�r�r�r�r�r��<module>s0PKj�\-^�L��__pycache__/hash.cpython-36.pycnu�[���3

�b�WL�@sXdZddlZiZejed<ejed<ejed<ejed<ejed<ejed<d	d
�Z	dS)z'Hashing backwards compatibility wrapper�NZMD5ZSHA1ZSHA224ZSHA256ZSHA384ZSHA512cCst|j�S)N)�hashes�upper)�	algorithm�r�/usr/lib/python3.6/hash.py�getsr)
�__doc__ZhashlibrZmd5Zsha1Zsha224Zsha256Zsha384Zsha512rrrrr�<module>s





PKj�\=*ᴈ�'__pycache__/grange.cpython-36.opt-1.pycnu�[���3

�b�W��@sdZddlZdd�ZdS)zDNS GENERATE range conversion.�NcCs�d}d}d}|r(|ddkr(tjjd��xj|D]b}|dkrT|dkrTt|�}d}d}q.|dkrnt|�}d}d}q.|j�r�||7}q.tjjd	|��q.W|dkr�tjj��|dkr�t|�}|dkr�t|�}|||fS)z�Convert the text form of a range in a GENERATE statement to an
    integer.

    @param text: the textual range
    @type text: string
    @return: The start, stop and step values.
    @rtype: tuple
    ��r�-z!Start cannot be a negative number��/�zCould not parse %s�)rr)�dnsZ	exception�SyntaxError�int�isdigit)�text�stepZcur�state�c�start�stop�r�/usr/lib/python3.6/grange.py�	from_texts0


r)�__doc__r	rrrrr�<module>sPKj�\b�?&__pycache__/tsigkeyring.cpython-36.pycnu�[���3

�b�W��@s8dZddlmZmZddlZddlZdd�Zdd�ZdS)zA place to store TSIG keys.�)�maybe_decode�maybe_encodeNcCs<i}x2|D]*}tjj|�}tjt||��}|||<q
W|S)z�Convert a dictionary containing (textual DNS name, base64 secret) pairs
    into a binary keyring which has (dns.name.Name, binary secret) pairs.
    @rtype: dict)�dns�name�	from_text�base64Zdecodestringr)�textring�keyring�keytext�keyname�secret�r
�!/usr/lib/python3.6/tsigkeyring.pyrs
rcCs<i}x2|D]*}t|j��}ttj||��}|||<q
W|S)z�Convert a dictionary containing (dns.name.Name, binary secret) pairs
    into a text keyring which has (textual DNS name, base64 secret) pairs.
    @rtype: dict)r�to_textrZencodestring)r	rrr
rr
r
rr&s
r)	�__doc__Zdns._compatrrrZdns.namerrrr
r
r
r�<module>s

PKj�\�0��qq*__pycache__/exception.cpython-36.opt-1.pycnu�[���3

d��W�@shdZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZGd	d
�d
e�ZGdd�de�Zd
S)zCommon DNS Exceptions.csReZdZdZdZe�ZdZ�fdd�Zdd�Z	dd�Z
d	d
�Z�fdd�Z�Z
S)
�DNSExceptiona�Abstract base class shared by all dnspython exceptions.

    It supports two basic modes of operation:

    a) Old/compatible mode is used if __init__ was called with
    empty **kwargs.
    In compatible mode all *args are passed to standard Python Exception class
    as before and all *args are printed by standard __str__ implementation.
    Class variable msg (or doc string if msg is None) is returned from str()
    if *args is empty.

    b) New/parametrized mode is used if __init__ was called with
    non-empty **kwargs.
    In the new mode *args has to be empty and all kwargs has to exactly match
    set in class variable self.supp_kwargs. All kwargs are stored inside
    self.kwargs and used in new __str__ implementation to construct
    formatted message based on self.fmt string.

    In the simplest case it is enough to override supp_kwargs and fmt
    class variables to get nice parametrized messages.
    Ncsp|j||�|r*|jf|�|_t|�|_nt�|_|jdkrD|j|_|rZtt|�j	|�ntt|�j	|j�dS)N)
�
_check_params�
_check_kwargs�kwargs�str�msg�dict�__doc__�superr�__init__)�self�argsr)�	__class__��/usr/lib/python3.6/exception.pyr
.s
zDNSException.__init__cOs|s|rdS)zsOld exceptions supported only args and not kwargs.

        For sanity we do not allow to mix old and new behavior.Nr)rrrrrrr=szDNSException._check_paramscKs|r|S)Nr)rrrrrrEszDNSException._check_kwargscKshi}x^|j�D]R\}}t|ttf�rXttt|��||<t||�dkr`||j�||<q|||<qW|S)z�Format kwargs before printing them.

        Resulting dictionary has to have keys necessary for str.format call
        on fmt class variable.
        �)�items�
isinstance�list�set�mapr�len�pop)rr�fmtargs�kw�datarrr�_fmt_kwargsLszDNSException._fmt_kwargscs:|jr(|jr(|jf|j�}|jjf|�Stt|�j�SdS)N)r�fmtr�formatr	r�__str__)rr)r
rrr^szDNSException.__str__)�__name__�
__module__�__qualname__rrr�supp_kwargsrr
rrrr�
__classcell__rr)r
rrsrc@seZdZdZdS)�	FormErrorzDNS message is malformed.N)rr r!rrrrrr$hsr$c@seZdZdZdS)�SyntaxErrorzText input is malformed.N)rr r!rrrrrr%msr%c@seZdZdZdS)�
UnexpectedEndzText input ended unexpectedly.N)rr r!rrrrrr&rsr&c@seZdZdZdS)�TooBigzThe DNS message is too big.N)rr r!rrrrrr'wsr'c@seZdZdZedg�ZdZdS)�TimeoutzThe DNS operation timed out.Ztimeoutz3The DNS operation timed out after {timeout} secondsN)rr r!rrr"rrrrrr(|s
r(N)r�	Exceptionrr$r%r&r'r(rrrr�<module>sUPKj�\�zu-\*\*'__pycache__/dnssec.cpython-36.opt-1.pycnu�[���3

�b�W�9�@sHdZddlmZddlZddlZddlZddlZddlZddl	Zddl
ZddlZddlZddl
ZddlmZGdd�dejj�ZGdd	�d	ejj�ZdZd
ZdZdZd
ZdZdZdZdZdZdZdZdZ dZ!eeeeeeeeeeeee e!d�Z"e#dd�e"j$�D��Z%dd�Z&dd�Z'dd�Z(dDd d!�Z)dEd"d#�Z*d$d%�Z+d&d'�Z,d(d)�Z-d*d+�Z.d,d-�Z/d.d/�Z0d0d1�Z1d2d3�Z2d4d5�Z3d6d7�Z4d8d9�Z5dFd:d;�Z6dGd<d=�Z7d>d?�Z8y(ddl9Z:ddl;Z:ddl<Z:e7Z=e6Z>d@Z?Wn"e@k
�r�e8Z=e8Z>dAZ?YnXy8ddlAZAddlBZAddlCZAddlDZAd@ZEGdBdC�dCeF�ZGWne@k
�rBdAZEYnXdS)Hz.Common DNSSEC-related functions and constants.�)�BytesION�)�string_typesc@seZdZdZdS)�UnsupportedAlgorithmz&The DNSSEC algorithm is not supported.N)�__name__�
__module__�__qualname__�__doc__�r
r
�/usr/lib/python3.6/dnssec.pyr!src@seZdZdZdS)�ValidationFailurez The DNSSEC signature is invalid.N)rrrr	r
r
r
rr&sr��������
�
����)�RSAMD5�DH�DSA�ECC�RSASHA1�DSANSEC3SHA1�RSASHA1NSEC3SHA1�	RSASHA256�	RSASHA512�INDIRECT�ECDSAP256SHA256�ECDSAP384SHA384�
PRIVATEDNS�
PRIVATEOIDccs|]\}}||fVqdS)Nr
)�.0�x�yr
r
r�	<genexpr>Nsr+cCs"tj|j��}|dkrt|�}|S)z:Convert text into a DNSSEC algorithm value
    @rtype: intN)�_algorithm_by_text�get�upper�int)�text�valuer
r
r�algorithm_from_textQsr2cCstj|�}|dkrt|�}|S)z;Convert a DNSSEC algorithm value to text
    @rtype: stringN)�_algorithm_by_valuer-�str)r1r0r
r
r�algorithm_to_text[s
r5cCst�}|j||d�|j�S)N)�origin)r�to_wire�getvalue)�recordr6�sr
r
r�	_to_rdataesr;cCs�t||�}t|�}|jtkr0|dd>|d	Sd}x<tt|�d�D](}||d|d>|d|d7}qFWt|�ddkr�||t|�dd>7}||d?d@7}|d@SdS)
Nrrr
rr�i��������)r;�	bytearray�	algorithmr�range�len)�keyr6�rdataZtotal�ir
r
r�key_idks

rFcCs�|j�dkr d}tjjd�}n,|j�dkr@d}tjjd�}ntd|��t|t�rdtjj||�}|j	|j
�j��|j	t||��|j
�}tjdt|�|j|�|}tjjtjjtjj|dt|��S)N�SHA1r�SHA256r
zunsupported algorithm "%s"z!HBBr)r.�dns�hash�hashesr�
isinstancer�name�	from_text�updateZcanonicalizer7r;�digest�struct�packrFr@rDZ	from_wire�
rdataclass�IN�	rdatatypeZDSrB)rMrCr@r6ZdsalgrJrPZdsrdatar
r
r�make_ds{s
rVcCs�g}|j|j�}|dkrdSt|tjj�rZy|jtjjtj	j
�}Wq^tk
rVdSXn|}x0|D](}|j|jkrdt
|�|jkrd|j|�qdW|S)N)r-�signerrLrIZnodeZNodeZ
find_rdatasetrSrTrUZDNSKEY�KeyErrorr@rFZkey_tag�append)�keys�rrsigZcandidate_keysr1�rdatasetrDr
r
r�_find_candidate_keys�s 

r]cCs|tttttfkS)N)rrr r!r")r@r
r
r�_is_rsa�sr^cCs|ttfkS)N)rr)r@r
r
r�_is_dsa�sr_cCsto|ttfkS)N)�_have_ecdsar$r%)r@r
r
r�	_is_ecdsa�sracCs|tkS)N)r)r@r
r
r�_is_md5�srbcCs|ttttfkS)N)rrrr )r@r
r
r�_is_sha1�srccCs|ttfkS)N)r!r$)r@r
r
r�
_is_sha256�srdcCs|tkS)N)r%)r@r
r
r�
_is_sha384�srecCs|tkS)N)r")r@r
r
r�
_is_sha512�srfcCs~t|�rtjjd�St|�r,tjjd�St|�rBtjjd�St|�rXtjjd�St|�rntjjd�Std|��dS)NZMD5rGrHZSHA384ZSHA512zunknown hash for algorithm %u)	rbrIrJrKrcrdrerfr)r@r
r
r�
_make_hash�srgc	Cs�t|�rddddddddg}ndt|�r6dd	d
ddg}nLt|�rVdddd
dd
ddd
g	}n,t|�rvdddd
dd
ddd
g	}ntd|��t|�}t|�j}dgd||gd|dgd|g|ddgd|g}tj	dt|�f|��S)N�*��H�rr
r�+rr��`r�erzunknown algorithm %u�0rrrz!%dB)
rbrcrdrfrrBrgZdigest_sizerQrR)r@ZoidZolenZdlenZidbytesr
r
r�_make_algorithm_id�s
<rqc)Cs�t|t�rtjj|tjj�}�x�t||�D�]�}|s<td��t|t�rX|d}|d}n
|j}|}|dkrrt	j	�}|j
|kr�td��|j|kr�td��t|j
�}t|j
��r`|j}	tjd|	dd��\}
|	dd�}	|
dk�rtjd|	dd	��\}
|	d	d�}	|	d|
�}|	|
d�}t|�d
}
tjjjtjjj|�tjjj|�f�}tjjj|j�f}�nt|j
��rj|j}	tjd|	dd��\}|	dd�}	d|d
}|	dd�}|	dd�}	|	d|�}|	|d�}	|	d|�}|	|d�}	|	d|�}tjjjtjjj|�tjjj|�tjjj|�tjjj|�f�}tjd
|jdd��\}}tjjj|�tjjj|�f}n�t|j
��rX|j
tk�r�tj j!}d}n"|j
t"k�r�tj j#}d}ntd��|j}	tjjj|	d|��}tjjj|	||d	��}tj$j%|j&|||j'�}tj(j)j*||�}t+||�}|jd|�}|j|d�}tjj,tjjj|�tjjj|��}ntd|j
��|j-t.||�dd��|j-|j/j0|��|j1t|�dk�r�|j2|j1d�d} tjjd| �}|j0|�}!tj3d|j4|j5|j6�}"t7|�}#xP|#D]H}$|j-|!�|j-|"�|$j0|�}%tj3dt|%��}&|j-|&�|j-|%��q�W|j8�}'t|j
��r�t9|j
�|'}'|
d
t|'�d}(tj3dd	|(dfddgdg|(dg��|'}'n(t|j
��s�t|j
��r�ntd|j
��|j:|'|�r*dSq*Wtd��dS)a�Validate an RRset against a single signature rdata

    The owner name of the rrsig is assumed to be the same as the owner name
    of the rrset.

    @param rrset: The RRset to validate
    @type rrset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param rrsig: The signature rdata
    @type rrsig: dns.rrset.Rdata
    @param keys: The key dictionary.
    @type keys: a dictionary keyed by dns.name.Name with node or rdataset
    values
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name or None
    @param now: The time to use when validating the signatures.  The default
    is the current time.
    @type now: int
    zunknown keyrrNZexpiredz
not yet validz!Bz!Hr
r�@�z!20s20s� rpzunknown ECDSA curvezunknown algorithm %u��*z!HHIrz!%dB�zverify failure);rLrrIrMrN�rootr]r�tuple�timeZ
expirationZ	inceptionrgr@r^rCrQ�unpackrB�CryptoZ	PublicKeyZRSAZ	construct�Util�number�
bytes_to_longZ	signaturer_rrar$�ecdsaZcurvesZNIST256pr%ZNIST384pZ
ellipticcurveZPoint�curve�orderrZZVerifyingKeyZfrom_public_point�ECKeyWrapperZ	SignaturerOr;rWZ
to_digestableZlabels�splitrRZrdtypeZrdclassZoriginal_ttl�sortedrPrq�verify))�rrsetr[rZr6�nowZ
candidate_key�rrnamer\rJZkeyptrZbytes_Zrsa_eZrsa_nZkeylen�pubkey�sig�tZoctetsZdsa_qZdsa_pZdsa_gZdsa_yZdsa_rZdsa_sr��key_lenr)r*ZpointZ
verifying_key�rr:�suffixZ	rrnamebufZrrfixedZrrlistZrrZrrdataZrrlenrPZpadlenr
r
r�_validate_rrsig�s�














"r�c	
Cs�t|t�rtjj|tjj�}t|t�r0|d}n|j}t|t�rR|d}|d}n
|j}|}|j|�}|j|�}||kr�td��x6|D].}yt	|||||�dStk
r�Yq�Xq�Wtd��dS)ahValidate an RRset

    @param rrset: The RRset to validate
    @type rrset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param rrsigset: The signature RRset
    @type rrsigset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param keys: The key dictionary.
    @type keys: a dictionary keyed by dns.name.Name with node or rdataset
    values
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name or None
    @param now: The time to use when validating the signatures.  The default
    is the current time.
    @type now: int
    rrzowner names do not matchNzno RRSIGs validated)
rLrrIrMrNrxryZchoose_relativityrr�)	r�ZrrsigsetrZr6r�r�Z	rrsignameZ
rrsigrdatasetr[r
r
r�	_validatexs*








r�cOstd��dS)Nz#DNSSEC validation requires pycrypto)�NotImplementedError)�args�kwargsr
r
r�_need_pycrypto�sr�TFc@seZdZdd�Zdd�ZdS)r�cCs||_||_dS)N)rCr�)�selfrCr�r
r
r�__init__�szECKeyWrapper.__init__cCstjjj|�}|jjj||�S)N)r|r}r~rrCr�Zverifies)r�rPr�Zdiglongr
r
rr��szECKeyWrapper.verifyN)rrrr�r�r
r
r
rr��sr�)N)N)NN)NN)Hr	�iorrQrzZ
dns.exceptionrIZdns.hashZdns.nameZdns.nodeZdns.rdatasetZ	dns.rdataZ
dns.rdatatypeZdns.rdataclassZ_compatrZ	exceptionZDNSExceptionrrrrrrrrr r!r"r$r%r#r&r'r,�dict�itemsr3r2r5r;rFrVr]r^r_rarbrcrdrerfrgrqr�r�r�ZCrypto.PublicKey.RSAr|ZCrypto.PublicKey.DSAZCrypto.Util.numberZvalidateZvalidate_rrsigZ_have_pycrypto�ImportErrorr�Zecdsa.ecdsaZecdsa.ellipticcurveZ
ecdsa.keysr`�objectr�r
r
r
r�<module>s�





0

PKj�\����i�i__pycache__/name.cpython-36.pycnu�[���3

�Of�r�@s�dZddlmZddlZddlZddlZddlZyddlZdZ	Wne
k
rXdZ	YnXddlZddl
ZddlmZmZmZmZmZy
ejZWn.ek
r�ddejd	�>d
dZYnXdZdZd
ZdZdZGd
d�dejj�ZGdd�dejj�ZGdd�dejj �Z!Gdd�dejj �Z"Gdd�dejj#�Z$Gdd�dejj �Z%Gdd�dejj�Z&Gdd�dejj#�Z'Gdd�dejj#�Z(Gdd �d ejj#�Z)Gd!d"�d"ejj#�Z*Gd#d$�d$e+�Z,Gd%d&�d&e,�Z-Gd'd(�d(e,�Z.e/d)�Z0d*Z1e-d�Z2e-d�Z3e2Z4e.dddd�Z5e.dddd�Z6e.dddd�Z7e.dddd�Z8e5Z9d+d,�Z:d-d.�Z;d/d0�Z<Gd1d2�d2e+�Z=e=d3g�Z>e=g�Z?e>dfd4d5�Z@e>dfd6d7�ZAd8d9�ZBdS):z�DNS Names.

@var root: The DNS root name.
@type root: dns.name.Name object
@var empty: The empty DNS name.
@type empty: dns.name.Name object
�)�BytesIONTF�)�long�binary_type�	text_type�unichr�maybe_decode��P���c@seZdZdZdS)�
EmptyLabelzA DNS label is empty.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/name.pyr4src@seZdZdZdS)�	BadEscapez8An escaped code in a text format of DNS name is invalid.N)rrrrrrrrr9src@seZdZdZdS)�
BadPointerz=A DNS compression pointer points forward instead of backward.N)rrrrrrrrr>src@seZdZdZdS)�BadLabelTypez2The label type in DNS name wire format is unknown.N)rrrrrrrrrCsrc@seZdZdZdS)�NeedAbsoluteNameOrOriginzvAn attempt was made to convert a non-absolute name to
    wire when there was also a non-absolute (or missing) origin.N)rrrrrrrrrHsrc@seZdZdZdS)�NameTooLongz A DNS name is > 255 octets long.N)rrrrrrrrrNsrc@seZdZdZdS)�LabelTooLongz A DNS label is > 63 octets long.N)rrrrrrrrrSsrc@seZdZdZdS)�AbsoluteConcatenationz]An attempt was made to append anything other than the
    empty name to an absolute DNS name.N)rrrrrrrrrXsrc@seZdZdZdS)�NoParentzMAn attempt was made to get the parent of the root name
    or the empty name.N)rrrrrrrrr^src@seZdZdZdS)�
NoIDNA2008zLIDNA 2008 processing was requested but the idna module is not
    available.N)rrrrrrrrrcsrc@seZdZdZedg�ZdZdS)�
IDNAExceptionz$IDNA processing raised an exception.�idna_exceptionz+IDNA processing exception: {idna_exception}N)rrrr�setZsupp_kwargsZfmtrrrrris
rc@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�	IDNACodecz.Abstract base class for IDNA encoder/decoders.cCsdS)Nr)�selfrrr�__init__tszIDNACodec.__init__cCs|j�jd�S)Nsxn--)�lower�
startswith)r"�labelrrr�is_idnawszIDNACodec.is_idnacCs"x|D]}t|�dkrdSqWdS)N�FT)�ord)r"r&�crrr�is_all_asciizs
zIDNACodec.is_all_asciicCst�dS)N)�NotImplementedError)r"r&rrr�encode�szIDNACodec.encodecCs`|j|�rPy|dd�jd�}WqXtk
rL}zt|d��WYdd}~XqXXnt|�}t|�S)Nr
Zpunycode)r)r'�decode�	Exceptionrr�	_escapify)r"r&�errrr.�s
zIDNACodec.decodeN)	rrrrr#r'r+r-r.rrrrr!psr!cs6eZdZdZd	�fdd�	Zdd�Z�fdd�Z�ZS)
�
IDNA2003CodeczIDNA 2003 encoder/decoder.Fcstt|�j�||_dS)aInitialize the IDNA 2003 encoder/decoder.
        @param strict_decode: If True, then IDNA2003 checking is done when
        decoding.  This can cause failures if the name was encoded with
        IDNA2008.  The default is False.
        @type strict_decode: bool
        N)�superr2r#�
strict_decode)r"r4)�	__class__rrr#�szIDNA2003Codec.__init__cCs6|dkrdSytjj|�Stk
r0t�YnXdS)N��)�	encodings�idnaZToASCII�UnicodeErrorr)r"r&rrrr-�szIDNA2003Codec.encodecsd|jstt|�j|�S|dkr"dSyttjj|��Stk
r^}zt	|d��WYdd}~XnXdS)Nr7r6)r)
r4r3r2r.r0r8r9Z	ToUnicoder/r)r"r&r1)r5rrr.�szIDNA2003Codec.decode)F)rrrrr#r-r.�
__classcell__rr)r5rr2�s
r2cs6eZdZdZd	�fdd�	Zdd�Z�fdd�Z�ZS)
�
IDNA2008CodeczIDNA 2008 encoder/decoder.Fcs*tt|�j�||_||_||_||_dS)a�Initialize the IDNA 2008 encoder/decoder.
        @param uts_46: If True, apply Unicode IDNA compatibility processing
        as described in Unicode Technical Standard #46
        (U{http://unicode.org/reports/tr46/}).  This parameter is only
        meaningful if IDNA 2008 is in use.  If False, do not apply
        the mapping.  The default is False
        @type uts_46: bool
        @param transitional: If True, use the "transitional" mode described
        in Unicode Technical Standard #46.  This parameter is only
        meaningful if IDNA 2008 is in use.  The default is False.
        @type transitional: bool
        @param allow_pure_ascii: If True, then a label which
        consists of only ASCII characters is allowed.  This is less strict
        than regular IDNA 2008, but is also necessary for mixed names,
        e.g. a name with starting with "_sip._tcp." and ending in an IDN
        suffixm which would otherwise be disallowed.  The default is False
        @type allow_pure_ascii: bool
        @param strict_decode: If True, then IDNA2008 checking is done when
        decoding.  This can cause failures if the name was encoded with
        IDNA2003.  The default is False.
        @type strict_decode: bool
        N)r3r<r#�uts_46�transitional�allow_pure_asciir4)r"r=r>r?r4)r5rrr#�s
zIDNA2008Codec.__init__cCs�|dkrdS|jr&|j|�r&|jd�Sts.t�y |jrFtj|d|j�}tj	|�Stj
k
r|}zt|d��WYdd}~XnXdS)Nr6r7�asciiF)r)r?r+r-�have_idna_2008rr=r9�uts46_remapr>Zalabel�	IDNAErrorr)r"r&r1rrrr-�s

zIDNA2008Codec.encodecs�|jstt|�j|�S|dkr"dSts*t�y"|jr@tj|dd�}t	tj
|��Stjk
rz}zt|d��WYdd}~XnXdS)Nr7r6F)r)
r4r3r<r.rArr=r9rBr0ZulabelrCr)r"r&r1)r5rrr.�szIDNA2008Codec.decode)FFFF)rrrrr#r-r.r;rr)r5rr<�s
r<s"().;\@$z"().;\@$cCs�t|t�rzd}t|t�r |j�}xTt|�D]H}|tkrH|dt|�7}q*|dkrf|dkrf|t|�7}q*|d|7}q*W|Sd}xD|D]<}|tkr�|d|7}q�|dkr�|dt|�7}q�||7}q�W|S)zaEscape the characters in label which need it.
    @returns: the escaped string
    @rtype: stringr6�\� r(z\%03d� )	�
isinstance�bytesrr-�	bytearray�_escaped�chr�
_escaped_textr))r&�textr*rrrr0�s&


r0cCs�t|�}d}d}d}xH|D]@}t|�}||d7}|dkr>t�|dkrR|dkrR|}|d7}qW|dkrjt�|dkr�||dkr�t�dS)a/Check for empty labels in the middle of a label sequence,
    labels that are too long, and for too many labels.
    @raises NameTooLong: the name as a whole is too long
    @raises EmptyLabel: a label is empty (i.e. the root label) and appears
    in a position other than the end of the label sequencerr�?r7�N���)�lenrrr)�labels�l�total�i�jr&Zllrrr�_validate_labelss 
rWcCs(t|t�r|St|t�r |j�St�dS)N)rGrrr-�
ValueError)r&rrr�
_ensure_bytes/s


rYcsDeZdZdZdgZ�fdd�Zdd�Zdd�Zd	d
�Zdd�Z	�fd
d�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�ZdLd.d/�ZdMd1d2�ZdNd3d4�ZdOd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d?d@�Z"dAdB�Z#dCdD�Z$dEdF�Z%dPdHdI�Z&dJdK�Z'�Z(S)Q�Namez�A DNS name.

    The dns.name.Name class represents a DNS name as a tuple of labels.
    Instances of the class are immutable.

    @ivar labels: The tuple of labels in the name. Each label is a string of
    up to 63 octets.rRcs2dd�|D�}tt|�jdt|��t|j�dS)z�Initialize a domain name from a list of labels.
        @param labels: the labels
        @type labels: any iterable whose values are strings
        cSsg|]}t|��qSr)rY)�.0�xrrr�
<listcomp>Hsz!Name.__init__.<locals>.<listcomp>rRN)r3rZ�__setattr__�tuplerWrR)r"rR)r5rrr#Csz
Name.__init__cCstd��dS)Nz+object doesn't support attribute assignment)�	TypeError)r"�name�valuerrrr^LszName.__setattr__cCs
t|j�S)N)rZrR)r"rrr�__copy__Osz
Name.__copy__cCsttj|j|��S)N)rZ�copy�deepcopyrR)r"�memorrr�__deepcopy__RszName.__deepcopy__cCs
d|jiS)NrR)rR)r"rrr�__getstate__UszName.__getstate__cs$tt|�jd|d�t|j�dS)NrR)r3rZr^rWrR)r"�state)r5rr�__setstate__XszName.__setstate__cCst|j�dko|jddkS)zXIs the most significant label of this name the root label?
        @rtype: bool
        rrr7rP)rQrR)r"rrr�is_absolute\szName.is_absolutecCst|j�dko|jddkS)z\Is this name wild?  (I.e. Is the least significant label '*'?)
        @rtype: bool
        r�*)rQrR)r"rrr�is_wildcszName.is_wildcCsJtd�}x4|jD]*}x$t|j��D]}||d>|7}q"WqWt|t�S)zHReturn a case-insensitive hash of the name.
        @rtype: int
        rr)rrRrIr$�int�maxint)r"�hr&r*rrr�__hash__js
z
Name.__hash__c
Cs*|j�}|j�}||kr0|r&tddfStddfSt|j�}t|j�}||}|dkrZ|}n|}d}d}	t}
x�|dkr�|d8}|d8}|d8}|j|j�}|j|j�}||kr�d}|	dkr�t}
|
||	fS||kr�d}|	dkr�t}
|
||	fS|	d7}	qlW|}|dk�rt}
n|dk�rt}
nt}
|
||	fS)a�Compare two names, returning a 3-tuple (relation, order, nlabels).

        I{relation} describes the relation ship between the names,
        and is one of: dns.name.NAMERELN_NONE,
        dns.name.NAMERELN_SUPERDOMAIN, dns.name.NAMERELN_SUBDOMAIN,
        dns.name.NAMERELN_EQUAL, or dns.name.NAMERELN_COMMONANCESTOR

        I{order} is < 0 if self < other, > 0 if self > other, and ==
        0 if self == other.  A relative name is always less than an
        absolute name.  If both names have the same relativity, then
        the DNSSEC order relation is used to order them.

        I{nlabels} is the number of significant labels that the two names
        have in common.
        rrrPrP)	rk�
NAMERELN_NONErQrRr$�NAMERELN_COMMONANCESTOR�NAMERELN_SUPERDOMAIN�NAMERELN_SUBDOMAIN�NAMERELN_EQUAL)
r"�otherZsabsZoabs�l1�l2ZldiffrS�orderZnlabelsZnamerelnZlabel1Zlabel2rrr�fullcompareusN








zName.fullcomparecCs(|j|�\}}}|tks |tkr$dSdS)zoIs self a subdomain of other?

        The notion of subdomain includes equality.
        @rtype: bool
        TF)r{rurv)r"rw�nr�o�nlrrr�is_subdomain�szName.is_subdomaincCs(|j|�\}}}|tks |tkr$dSdS)zqIs self a superdomain of other?

        The notion of subdomain includes equality.
        @rtype: bool
        TF)r{rtrv)r"rwr|r}r~rrr�is_superdomain�szName.is_superdomaincCstdd�|jD��S)z�Return a name which is equal to the current name, but is in
        DNSSEC canonical form.
        @rtype: dns.name.Name object
        cSsg|]}|j��qSr)r$)r[r\rrrr]�sz%Name.canonicalize.<locals>.<listcomp>)rZrR)r"rrr�canonicalize�szName.canonicalizecCs$t|t�r|j|�ddkSdSdS)NrrF)rGrZr{)r"rwrrr�__eq__�s
zName.__eq__cCs$t|t�r|j|�ddkSdSdS)NrrT)rGrZr{)r"rwrrr�__ne__�s
zName.__ne__cCs$t|t�r|j|�ddkStSdS)Nrr)rGrZr{�NotImplemented)r"rwrrr�__lt__�s
zName.__lt__cCs$t|t�r|j|�ddkStSdS)Nrr)rGrZr{r�)r"rwrrr�__le__�s
zName.__le__cCs$t|t�r|j|�ddkStSdS)Nrr)rGrZr{r�)r"rwrrr�__ge__�s
zName.__ge__cCs$t|t�r|j|�ddkStSdS)Nrr)rGrZr{r�)r"rwrrr�__gt__�s
zName.__gt__cCsd|j�dS)Nz
<DNS name �>)�__str__)r"rrr�__repr__�sz
Name.__repr__cCs
|jd�S)NF)�to_text)r"rrrr��szName.__str__FcCspt|j�dkrtd�St|j�dkr:|jddkr:td�S|rV|j�rV|jdd�}n|j}djtt|��}|S)	z�Convert name to text format.
        @param omit_final_dot: If True, don't emit the final dot (denoting the
        root label) for absolute names.  The default is False.
        @rtype: string
        r�@rr7�.N�.rP)rQrRrrk�join�mapr0)r"�omit_final_dotrS�srrrr��szName.to_textNcsxt|j�dkrdSt|j�dkr2|jddkr2dS|rN|j�rN|jdd	�}n|j}�dkr`t�dj�fdd�|D��S)
a�Convert name to Unicode text format.

        IDN ACE labels are converted to Unicode.

        @param omit_final_dot: If True, don't emit the final dot (denoting the
        root label) for absolute names.  The default is False.
        @type omit_final_dot: bool
        @param idna_codec: IDNA encoder/decoder.  If None, the
        IDNA_2003_Practical encoder/decoder is used.  The IDNA_2003_Practical
        decoder does not impose any policy, it just decodes punycode, so if
        you don't want checking for compliance, you can use this decoder for
        IDNA2008 as well.
        @type idna_codec: dns.name.IDNA
        @rtype: string
        r�@rr7r�Ncsg|]}�j|��qSr)r.)r[r\)�
idna_codecrrr])sz#Name.to_unicode.<locals>.<listcomp>rP)rQrRrk�IDNA_2003_Practicalr�)r"r�r�rSr)r�r�
to_unicodeszName.to_unicodecCsX|j�s:|dks|j�rt�t|j�}|jt|j��n|j}dd�|D�}dj|�S)aConvert name to a format suitable for digesting in hashes.

        The name is canonicalized and converted to uncompressed wire format.

        @param origin: If the name is relative and origin is not None, then
        origin will be appended to it.
        @type origin: dns.name.Name object
        @raises NeedAbsoluteNameOrOrigin: All names in wire format are
        absolute.  If self is a relative name, then an origin must be supplied;
        if it is missing, then this exception is raised
        @rtype: string
        NcSs*g|]"}tjdt|�t|�|j���qS)z!B%ds)�struct�packrQr$)r[r\rrrr]@sz&Name.to_digestable.<locals>.<listcomp>r7)rkr�listrR�extendr�)r"�originrRZdlabelsrrr�
to_digestable+s
zName.to_digestablec
Cs.|dkrt�}d}nd}|j�sR|dks2|j�r6t�t|j�}|jt|j��n|j}d}x�|D]�}t||d��}|d7}|dk	r�|j|�}	nd}	|	dk	r�d|	}
tj	d|
�}|j
|�Pqb|dk	r�t|�dkr�|j�}	|	dkr�|	||<t|�}|j
tj	d	|��|dkrb|j
|�qbW|�r*|j
�SdS)
a�Convert name to wire format, possibly compressing it.

        @param file: the file where the name is emitted (typically
        a BytesIO file).  If None, a string containing the wire name
        will be returned.
        @type file: file or None
        @param compress: The compression table.  If None (the default) names
        will not be compressed.
        @type compress: dict
        @param origin: If the name is relative and origin is not None, then
        origin will be appended to it.
        @type origin: dns.name.Name object
        @raises NeedAbsoluteNameOrOrigin: All names in wire format are
        absolute.  If self is a relative name, then an origin must be supplied;
        if it is missing, then this exception is raised
        NTFrri�z!Hi�?z!B)rrkrr�rRr�rZ�getr�r��writerQ�tell�getvalue)
r"�file�compressr�Zwant_returnrRrUr&�n�posrbr�rSrrr�to_wireDs@


zName.to_wirecCs
t|j�S)z@The length of the name (in labels).
        @rtype: int
        )rQrR)r"rrr�__len__|szName.__len__cCs
|j|S)N)rR)r"�indexrrr�__getitem__�szName.__getitem__cCs
|j|�S)N)�concatenate)r"rwrrr�__add__�szName.__add__cCs
|j|�S)N)�
relativize)r"rwrrr�__sub__�szName.__sub__cCsnt|j�}|dkr|tjjfS||kr2tjj|fS|dksB||krJtd��t|d|��t||d��fS)a(Split a name into a prefix and suffix at depth.

        @param depth: the number of labels in the suffix
        @type depth: int
        @raises ValueError: the depth was not >= 0 and <= the length of the
        name.
        @returns: the tuple (prefix, suffix)
        @rtype: tuple
        rz0depth must be >= 0 and <= the length of the nameN)rQrR�dnsra�emptyrXrZ)r"�depthrSrrr�split�s
z
Name.splitcCs:|j�rt|�dkrt�t|j�}|jt|j��t|�S)z�Return a new name which is the concatenation of self and other.
        @rtype: dns.name.Name object
        @raises AbsoluteConcatenation: self is absolute and other is
        not the empty name
        r)rkrQrr�rRr�rZ)r"rwrRrrrr��s

zName.concatenatecCs0|dk	r(|j|�r(t|dt|���S|SdS)z�If self is a subdomain of origin, return a new name which is self
        relative to origin.  Otherwise return self.
        @rtype: dns.name.Name object
        N)rrZrQ)r"r�rrrr��szName.relativizecCs|j�s|j|�S|SdS)z�If self is a relative name, return a new name which is the
        concatenation of self and origin.  Otherwise return self.
        @rtype: dns.name.Name object
        N)rkr�)r"r�rrr�derelativize�s
zName.derelativizeTcCs&|r|r|j|�S|j|�Sn|SdS)aReturn a name with the relativity desired by the caller.  If
        origin is None, then self is returned.  Otherwise, if
        relativize is true the name is relativized, and if relativize is
        false the name is derelativized.
        @rtype: dns.name.Name object
        N)r�r�)r"r�r�rrr�choose_relativity�s

zName.choose_relativitycCs&|tks|tkrt�t|jdd��S)z�Return the parent of the name.
        @rtype: dns.name.Name object
        @raises NoParent: the name is either the root name or the empty name,
        and thus has no parent.
        rN)�rootr�rrZrR)r"rrr�parent�szName.parent)F)FN)N)NNN)NT))rrrr�	__slots__r#r^rcrgrhrjrkrmrqr{rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r;rr)r5rrZ7sJ	=



8

rZr7c	Cs�t|t�std��|dkp"t|t�s,td��g}d}d}d}d}|dkrLt}|dkrXd}|�rz|dkrptd	g�Sx�|D]�}|r�|dkr�|j�r�t|�}|d
7}q�||7}d}n@|j�s�t�|d9}|t|�7}|d
7}|dkr�d}|t|�7}qv|dk�r"t	|�dk�rt
�|j|j|��d}qv|dk�r:d}d}d}qv||7}qvW|�rPt�t	|�dk�rp|j|j|��n
|jd	�t	|�dk�s�|dd	k�r�|dk	�r�|j
t|j��t|�S)a�Convert unicode text into a Name object.

    Labels are encoded in IDN ACE form.

    @param text: The text to convert into a name.
    @type text: Unicode string
    @param origin: The origin to append to non-absolute names.
    @type origin: dns.name.Name
    @param idna_codec: IDNA encoder/decoder.  If None, the default IDNA 2003
    encoder/decoder is used.
    @type idna_codec: dns.name.IDNA
    @rtype: dns.name.Name object
    z0input to from_unicode() must be a unicode stringNzorigin must be a Name or Noner6Frr�r�r7r�
r�。�.�。rDT)r�r�r�r�rP)rGrrXrZ�	IDNA_2003�isdigitrnrrrQr�appendr-r�r�rR)	rMr�r�rRr&�escaping�edigitsrTr*rrr�from_unicode�sd






&r�c
Cs�t|t�rt|||�St|t�s(td��|dkp8t|t�sBtd��g}d}d}d}d}|dkrbd}|�r�|dkrztdg�Sx�t|�D]�}tjd	|�}	|�r|dkr�|	j	�r�t
|	�}|d
7}n||	7}d}nF|	j	�s�t�|d9}|t
|	�7}|d
7}|dk�r^d}|tjd	|�7}q�|	dk�r>t|�dk�r.t
�|j|�d}q�|	d
k�rVd}d}d}q�||	7}q�W|�rlt�t|�dk�r�|j|�n
|jd�t|�dk�s�|ddk�r�|dk	�r�|jt|j��t|�S)a}Convert text into a Name object.

    @param text: The text to convert into a name.
    @type text: string
    @param origin: The origin to append to non-absolute names.
    @type origin: dns.name.Name
    @param idna_codec: IDNA encoder/decoder.  If None, the default IDNA 2003
    encoder/decoder is used.
    @type idna_codec: dns.name.IDNA
    @rtype: dns.name.Name object
    z%input to from_text() must be a stringNzorigin must be a Name or Noner7Frr�r�z!Brr�r�\TrP)rGrr�rrXrZrIr�r�r�rnrrQrr�r�r�rR)
rMr�r�rRr&r�r�rTr*Zbyte_rrr�	from_text*sf








&r�cCst|t�std��tjj|�}g}|}d}||}|d7}d}x�|dkr�|dkr�|j||||�j��||7}|dkr�||7}nJ|dkr�|d@d||}|dkr�|d7}||kr�t�|}|d7}nt	�||}|d7}|dkr@|d7}q@W|jd�t
|�|fS)	a^Convert possibly compressed wire format into a Name.
    @param message: the entire DNS message
    @type message: string
    @param current: the offset of the beginning of the name from the start
    of the message
    @type current: int
    @raises dns.name.BadPointer: a compression pointer did not point backwards
    in the message
    @raises dns.name.BadLabelType: an invalid label type was encountered.
    @returns: a tuple consisting of the name that was read and the number
    of bytes of the wire format message which were consumed reading it
    @rtype: (dns.name.Name object, int) tuple
    z*input to from_wire() must be a byte stringrr�@�rN�r6)rGrrXr�ZwiredataZ
maybe_wrapr�ZunwraprrrZ)�messageZcurrentrRZbiggest_pointerZhops�countZcusedrrr�	from_wireps<




r�)Cr�iorr��sysrdZencodings.idnar8r9rA�ImportErrorZ
dns.exceptionr�Zdns.wiredataZ_compatrrrrrro�AttributeError�calcsizerrrtrurvrsZ	exception�SyntaxErrorrrZ	FormErrorrrZDNSExceptionrrrrrrr�objectr!r2r<rIrJrLr�ZIDNA_2003_Strictr�ZIDNA_2008_PracticalZIDNA_2008_UTS_46ZIDNA_2008_StrictZIDNA_2008_TransitionalZ	IDNA_2008r0rWrYrZr�r�r�r�r�rrrr�<module>st

  >*
HFPKj�\���!
!
,__pycache__/reversename.cpython-36.opt-1.pycnu�[���3

�b�W��@sXdZddlZddlZddlZddlZddlZejjd�Z	ejjd�Z
dd�Zdd�ZdS)	aDNS Reverse Map Names.

@var ipv4_reverse_domain: The DNS IPv4 reverse-map domain, in-addr.arpa.
@type ipv4_reverse_domain: dns.name.Name object
@var ipv6_reverse_domain: The DNS IPv6 reverse-map domain, ip6.arpa.
@type ipv6_reverse_domain: dns.name.Name object
�Nz
in-addr.arpa.z	ip6.arpa.cCs�yztjj|�}tjj|�rXtjdkr<dd�|dd�D�}ndd�|dd�D�}t}n dd�ttj	|�j
��D�}t}Wn2tk
r�dd�t
tjj|��D�}t}YnX|j�tjjd	j|�|d
�S)aConvert an IPv4 or IPv6 address in textual form into a Name object whose
    value is the reverse-map domain name of the address.
    @param text: an IPv4 or IPv6 address in textual form (e.g. '127.0.0.1',
    '::1')
    @type text: str
    @rtype: dns.name.Name object
    �cSsg|]}d|�qS)z%d�)�.0�byterr�!/usr/lib/python3.6/reversename.py�
<listcomp>/sz from_address.<locals>.<listcomp>�NcSsg|]}dt|��qS)z%d)�ord)rrrrrr1scSsg|]}|�qSrr)r�xrrrr4scSsg|]}d|�qS)z%dr)rrrrrr7s�.)�origin)r)�dns�ipv6�	inet_atonZ	is_mapped�sys�version_info�ipv4_reverse_domain�str�binasciiZhexlify�decode�ipv6_reverse_domain�	Exception�	bytearray�ipv4�reverse�name�	from_text�join)�textZv6�partsrrrr�from_address#s

r cCs�|jt�rD|jt�}t|j�}|j�dj|�}tjj	tjj
|��S|jt�r�|jt�}t|j�}|j�g}d}t|�}x0||kr�|j
dj|||d���|d7}q|Wdj|�}tjj	tjj
|��Stjjd��dS)z�Convert a reverse map domain name into textual address form.
    @param name: an IPv4 or IPv6 address in reverse-map form.
    @type name: dns.name.Name object
    @rtype: str
    �.r���:z"unknown reverse-map address familyN)Zis_subdomainrZ
relativize�list�labelsrrr
rZ	inet_ntoarr�len�appendrZ	exception�SyntaxError)rr&rr�i�lrrr�
to_address>s&








r,)
�__doc__rrZdns.namer
Zdns.ipv6Zdns.ipv4rrrrr r,rrrr�<module>sPKj�\�ȟ��__pycache__/ipv6.cpython-36.pycnu�[���3

�b�W��@s�dZddlZddlZddlZddlZddlmZmZm	Z	ej
d�Zdd�Zej
d�Z
ej
d	�Zej
d
�Zdd�ZdZdd�ZdS)zIPv6 helper functions.�N�)�xrange�binary_type�maybe_decodes
0+([0-9a-f]+)cCs�t|�dkrtd��tj|�}g}d}t|�}xJ||krx|||d�}tj|�}|dk	rd|jd�}|j|�|d7}q0Wd}d}d}	d}
xNtd�D]B}||d	kr�|
r�|}||	}||kr�|	}|}d}
q�|
s�|}	d
}
q�W|
�r�d}||	}||k�r�|	}|}|dk�r�|dk�rb|dk�s4|dk�rb|dd
k�rb|dk�rDd}
nd}
|
t	j
j|dd��}n,dj|d|��ddj|||d��}n
dj|�}t
|�S)z�Convert a network format IPv6 address into text.

    @param address: the binary address
    @type address: string
    @rtype: string
    @raises ValueError: the address isn't 16 bytes long
    �z IPv6 addresses are 16 bytes longr�NrF��0T��sffffs::s::ffff:��:���)�len�
ValueError�binasciiZhexlify�
_leading_zero�match�group�appendr�dns�ipv4�	inet_ntoa�joinr)�address�hex�chunks�i�l�chunk�mZ
best_startZbest_len�startZ
last_was_zero�endZcurrent_len�prefix�r$�/usr/lib/python3.6/ipv6.pyrs^	










rs(.*):(\d+\.\d+\.\d+\.\d+)$s::.*s.*::$c
Cs�t|t�s|j�}|dkrd}tj|�}|dk	rvttjj|j	d���}d|j	d�j
�|d|d|d|dfj�}tj|�}|dk	r�|dd�}ntj|�}|dk	r�|dd�}|j
d	�}t|�}|d
kr�tjj�d}g}x�|D]�}|dk�r.|�rtjj�d
}xftdd
|d�D]}|jd��qWq�t|�}	|	dk�rHtjj�|	dk�rbdd|	|}|j|�q�W|d
k�r�|�r�tjj�dj|�}y
tj|�Stjtfk
�r�tjj�YnXdS)z�Convert a text format IPv6 address into network format.

    @param text: the textual address
    @type text: string
    @rtype: string
    @raises dns.exception.SyntaxError: the text was not properly formatted
    s::s0::N�z%s:%02x%02x:%02x%02xrr�r
rF�Ts0000rr	r)�
isinstancer�encode�
_v4_endingr�	bytearrayrr�	inet_atonr�decode�_colon_colon_start�_colon_colon_end�splitrZ	exception�SyntaxErrorrrrrZ	unhexlify�Error�	TypeError)
�textr �brrZ
seen_emptyZ	canonical�crZlcr$r$r%r-bsR










r-��
s��cCs
|jt�S)N)�
startswith�_mapped_prefix)rr$r$r%�	is_mapped�sr<s
s��)�__doc__�rerZ
dns.exceptionrZdns.ipv4Z_compatrrr�compilerrr+r/r0r-r;r<r$r$r$r%�<module>s
C


GPKj�\5�
nn"__pycache__/message.cpython-36.pycnu�[���3

�@�Wy��
@s�dZddlmZddlmZddlZddlZddlZddl	Zddl
ZddlZddlZddl
ZddlZddlZddlZddlZddlZddlZddlZddlZddlmZmZmZGdd�dejj�ZGd	d
�d
ejj�ZGdd�dejj�ZGd
d�dejj�Z Gdd�dejj�Z!Gdd�dejj�Z"Gdd�de#�Z$Gdd�de#�Z%d(dd�Z&Gdd�de#�Z'dd�Z(d d!�Z)ej*j+ddddddfd"d#�Z,d)d&d'�Z-dS)*zDNS Messages�)�absolute_import)�StringION�)�long�xrange�string_typesc@seZdZdZdS)�ShortHeaderz2The DNS packet passed to from_wire() is too short.N)�__name__�
__module__�__qualname__�__doc__�r
r
�/usr/lib/python3.6/message.pyr*src@seZdZdZdS)�TrailingJunkzEThe DNS packet passed to from_wire() has extra junk at the end of it.N)r	r
rrr
r
r
rr/src@seZdZdZdS)�UnknownHeaderFieldzVThe header field name was not recognized when converting from text
    into a message.N)r	r
rrr
r
r
rr4src@seZdZdZdS)�BadEDNSzVOPT record occurred somewhere other than the start of
    the additional data section.N)r	r
rrr
r
r
rr:src@seZdZdZdS)�BadTSIGzWA TSIG record occurred somewhere other than the end of
    the additional data section.N)r	r
rrr
r
r
rr@src@seZdZdZdS)�UnknownTSIGKeyz(A TSIG with an unknown key was received.N)r	r
rrr
r
r
rrFsrc@s�eZdZdZd-dd�Zdd�Zdd�Zd.d
d�Zdd
�Zdd�Z	dd�Z
dd�Zej
jdddfdd�Zej
jdddfdd�Zd/dd�Zdddddejjfdd�Zd0d!d"�Zd1d#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�ZdS)2�Messagea,
A DNS message.

    @ivar id: The query id; the default is a randomly chosen id.
    @type id: int
    @ivar flags: The DNS flags of the message.  @see: RFC 1035 for an
    explanation of these flags.
    @type flags: int
    @ivar question: The question section.
    @type question: list of dns.rrset.RRset objects
    @ivar answer: The answer section.
    @type answer: list of dns.rrset.RRset objects
    @ivar authority: The authority section.
    @type authority: list of dns.rrset.RRset objects
    @ivar additional: The additional data section.
    @type additional: list of dns.rrset.RRset objects
    @ivar edns: The EDNS level to use.  The default is -1, no Edns.
    @type edns: int
    @ivar ednsflags: The EDNS flags
    @type ednsflags: long
    @ivar payload: The EDNS payload size.  The default is 0.
    @type payload: int
    @ivar options: The EDNS options
    @type options: list of dns.edns.Option objects
    @ivar request_payload: The associated request's EDNS payload size.
    @type request_payload: int
    @ivar keyring: The TSIG keyring to use.  The default is None.
    @type keyring: dict
    @ivar keyname: The TSIG keyname to use.  The default is None.
    @type keyname: dns.name.Name object
    @ivar keyalgorithm: The TSIG algorithm to use; defaults to
    dns.tsig.default_algorithm.  Constants for TSIG algorithms are defined
    in dns.tsig, and the currently implemented algorithms are
    HMAC_MD5, HMAC_SHA1, HMAC_SHA224, HMAC_SHA256, HMAC_SHA384, and
    HMAC_SHA512.
    @type keyalgorithm: string
    @ivar request_mac: The TSIG MAC of the request message associated with
    this message; used when validating TSIG signatures.   @see: RFC 2845 for
    more information on TSIG fields.
    @type request_mac: string
    @ivar fudge: TSIG time fudge; default is 300 seconds.
    @type fudge: int
    @ivar original_id: TSIG original id; defaults to the message's id
    @type original_id: int
    @ivar tsig_error: TSIG error code; default is 0.
    @type tsig_error: int
    @ivar other_data: TSIG other data.
    @type other_data: string
    @ivar mac: The TSIG MAC for this message.
    @type mac: string
    @ivar xfr: Is the message being used to contain the results of a DNS
    zone transfer?  The default is False.
    @type xfr: bool
    @ivar origin: The origin of the zone in messages which are used for
    zone transfers or for DNS dynamic updates.  The default is None.
    @type origin: dns.name.Name object
    @ivar tsig_ctx: The TSIG signature context associated with this
    message.  The default is None.
    @type tsig_ctx: hmac.HMAC object
    @ivar had_tsig: Did the message decoded from wire format have a TSIG
    signature?
    @type had_tsig: bool
    @ivar multi: Is this message part of a multi-message sequence?  The
    default is false.  This variable is used when validating TSIG signatures
    on messages which are part of a zone transfer.
    @type multi: bool
    @ivar first: Is this message standalone, or the first of a multi
    message sequence?  This variable is used when validating TSIG signatures
    on messages which are part of a zone transfer.
    @type first: bool
    @ivar index: An index of rrsets in the message.  The index key is
    (section, name, rdclass, rdtype, covers, deleting).  Indexing can be
    disabled by setting the index to None.
    @type index: dict
    NcCs�|dkrtjj�|_n||_d|_g|_g|_g|_g|_d|_	d|_
d|_g|_d|_
d|_d|_tjj|_d|_d|_d|_d|_|j|_d|_d|_d|_d|_d|_d|_d|_i|_dS)Nrr�i,FT���) �dnsZentropyZ	random_16�id�flags�question�answer�	authority�
additional�edns�	ednsflags�payload�options�request_payload�keyring�keyname�tsig�default_algorithm�keyalgorithm�request_mac�
other_data�
tsig_error�fudge�original_id�mac�xfr�origin�tsig_ctx�had_tsig�multi�first�index)�selfrr
r
r�__init__�s:
zMessage.__init__cCsdt|j�dS)Nz<DNS message, ID �>)�reprr)r5r
r
r�__repr__�szMessage.__repr__cCs|j�S)N)�to_text)r5r
r
r�__str__�szMessage.__str__TcKst�}|jd|j�|jdtjjtjj|j���tjj|j|j	�}|jdtjj|��|jdtjj|j��|j
dkr�|jd|j
�|j	dkr�|jdtjj|j	��|jd|j�tjj
|j�}|r�|jd	�n
|jd
�x.|jD]$}|j|j||f|��|jd�q�W|�r,|jd�n
|jd
�x0|jD]&}|j|j||f|��|jd��q>W|�rz|jd�n
|jd�x0|jD]&}|j|j||f|��|jd��q�W|jd�x0|jD]&}|j|j||f|��|jd��q�W|j�dd�S)z�Convert the message to text.

        The I{origin}, I{relativize}, and any other keyword
        arguments are passed to the rrset to_wire() method.

        @rtype: string
        zid %d
z
opcode %s
z	rcode %s
z	flags %s
rzedns %s
z
eflags %s
zpayload %d
z;ZONE
z
;QUESTION
�
z;PREREQ
z;ANSWER
z;UPDATE
z;AUTHORITY
z;ADDITIONAL
Nrr)r�writerr�opcoder:�
from_flagsr�rcoderrZedns_to_textr �	is_updaterrrr�getvalue)r5r/�
relativize�kw�sZrcrA�rrsetr
r
rr:�sJ	





zMessage.to_textcCs�t|t�sdS|j|jkrdS|j|jkr.dSx|jD]}||jkr6dSq6Wx|jD]}||jkrTdSqTWx|jD]}||jkrrdSqrWx|jD]}||jkr�dSq�Wx|jD]}||jkr�dSq�Wx|jD]}||jkr�dSq�WdS)z�Two messages are equal if they have the same content in the
        header, question, answer, and authority sections.
        @rtype: boolFT)�
isinstancerrrrrr)r5�other�nr
r
r�__eq__�s2






zMessage.__eq__cCs|j|�S)z0Are two messages not equal?
        @rtype: bool)rJ)r5rHr
r
r�__ne__szMessage.__ne__cCs�|jtjj@dks:|j|jks:tjj|j�tjj|j�kr>dStjj|j|j�tjjkr\dStjj	|j�rndSx|j
D]}||j
krvdSqvWx|j
D]}||j
kr�dSq�WdS)z1Is other a response to self?
        @rtype: boolrFT)rr�QRrr>r?r@rZNOERRORrAr)r5rHrIr
r
r�is_responses"


zMessage.is_responsecCsD||jkrdS||jkrdS||jkr*dS||jkr8dStd��dS)Nrr��zunknown section)rrrr�
ValueError)r5�sectionr
r
r�section_number-s



zMessage.section_numberFc	Cs�|j|�|||||f}	|sb|jdk	r>|jj|	�}
|
dk	rb|
Sn$x"|D]}
|
j|||||�rD|
SqDW|sjt�tjj|||||�}
|j|
�|jdk	r�|
|j|	<|
S)aFind the RRset with the given attributes in the specified section.

        @param section: the section of the message to look in, e.g.
        self.answer.
        @type section: list of dns.rrset.RRset objects
        @param name: the name of the RRset
        @type name: dns.name.Name object
        @param rdclass: the class of the RRset
        @type rdclass: int
        @param rdtype: the type of the RRset
        @type rdtype: int
        @param covers: the covers value of the RRset
        @type covers: int
        @param deleting: the deleting value of the RRset
        @type deleting: int
        @param create: If True, create the RRset if it is not found.
        The created RRset is appended to I{section}.
        @type create: bool
        @param force_unique: If True and create is also True, create a
        new RRset regardless of whether a matching RRset exists already.
        @type force_unique: bool
        @raises KeyError: the RRset was not found and create was False
        @rtype: dns.rrset.RRset objectN)	rRr4�get�match�KeyErrorrrFZRRset�append)r5rQ�name�rdclass�rdtype�covers�deleting�create�force_unique�keyrFr
r
r�
find_rrset9s"




zMessage.find_rrsetc	
Cs:y|j||||||||�}	Wntk
r4d}	YnX|	S)aGet the RRset with the given attributes in the specified section.

        If the RRset is not found, None is returned.

        @param section: the section of the message to look in, e.g.
        self.answer.
        @type section: list of dns.rrset.RRset objects
        @param name: the name of the RRset
        @type name: dns.name.Name object
        @param rdclass: the class of the RRset
        @type rdclass: int
        @param rdtype: the type of the RRset
        @type rdtype: int
        @param covers: the covers value of the RRset
        @type covers: int
        @param deleting: the deleting value of the RRset
        @type deleting: int
        @param create: If True, create the RRset if it is not found.
        The created RRset is appended to I{section}.
        @type create: bool
        @param force_unique: If True and create is also True, create a
        new RRset regardless of whether a matching RRset exists already.
        @type force_unique: bool
        @rtype: dns.rrset.RRset object or NoneN)r_rU)
r5rQrWrXrYrZr[r\r]rFr
r
r�	get_rrsetgs
zMessage.get_rrsetrc	KsR|dkr|jdkr|j}nd}|dkr,d}n|dkr8d}tjj|j|j||�}x"|jD]}|j|j|j	|j
�qVWx"|jD]}|jtjj
|f|�qzWx"|jD]}|jtjj|f|�q�W|jdkr�|j|j|j|j|j�x"|jD]}|jtjj|f|�q�W|j�|jdk	�rJ|j|j|j|j|j|j|j|j|j|j �|j!|_!|j"�S)a7Return a string containing the message in DNS compressed wire
        format.

        Additional keyword arguments are passed to the rrset to_wire()
        method.

        @param origin: The origin to be appended to any relative names.
        @type origin: dns.name.Name object
        @param max_size: The maximum size of the wire format output; default
        is 0, which means 'the message's request payload, if nonzero, or
        65536'.
        @type max_size: int
        @raises dns.exception.TooBig: max_size was exceeded
        @rtype: string
        ri��iN)#r"rZrendererZRendererrrrZadd_questionrWrYrXrZ	add_rrset�ANSWERr�	AUTHORITYrZadd_ednsrr r!r�
ADDITIONALZwrite_headerr$Zadd_tsigr#r+r,r*r)r(r'r-Zget_wire)r5r/Zmax_sizerD�rrFr
r
r�to_wire�s6

zMessage.to_wirei,rcCst||_|dkr$t|jj��d|_nt|t�r:tjj|�}||_||_	||_
|dkr^|j|_n||_||_
||_dS)awWhen sending, a TSIG signature using the specified keyring
        and keyname should be added.

        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @type keyname: dns.name.Name or string
        @param fudge: TSIG time fudge; default is 300 seconds.
        @type fudge: int
        @param original_id: TSIG original id; defaults to the message's id
        @type original_id: int
        @param tsig_error: TSIG error code; default is 0.
        @type tsig_error: int
        @param other_data: TSIG other data.
        @type other_data: string
        @param algorithm: The TSIG algorithm to use; defaults to
        dns.tsig.default_algorithm
        Nr)r#�list�keysr$rGrrrW�	from_textr'r+rr,r*r))r5r#r$r+r,r*r)�	algorithmr
r
r�use_tsig�s

zMessage.use_tsig�cCs�|dks|dkrd}|dkr d}|dkr,|}|dkrFd}d}d}g}n$|td�M}||d>O}|dkrjg}||_||_||_||_||_dS)	a_Configure EDNS behavior.
        @param edns: The EDNS level to use.  Specifying None, False, or -1
        means 'do not use EDNS', and in this case the other parameters are
        ignored.  Specifying True is equivalent to specifying 0, i.e. 'use
        EDNS0'.
        @type edns: int or bool or None
        @param ednsflags: EDNS flag values.
        @type ednsflags: int
        @param payload: The EDNS sender's payload field, which is the maximum
        size of UDP datagram the sender can handle.
        @type payload: int
        @param request_payload: The EDNS payload size to use when sending
        this message.  If not specified, defaults to the value of payload.
        @type request_payload: int or None
        @param options: The EDNS options
        @type options: None or list of dns.edns.Option objects
        @see: RFC 2671
        NFrTrl�~�r)rrrr r!r")r5rrr r"r!r
r
r�use_edns�s(zMessage.use_ednscCsL|r*|jdkr|j�|jtjjO_n|jdkrH|jtjjM_dS)a
Enable or disable 'DNSSEC desired' flag in requests.
        @param wanted: Is DNSSEC desired?  If True, EDNS is enabled if
        required, and then the DO bit is set.  If False, the DO bit is
        cleared if EDNS is enabled.
        @type wanted: bool
        rN)rrmrrrZDO)r5Zwantedr
r
r�want_dnssecs

zMessage.want_dnsseccCstjj|j|j�S)z.Return the rcode.
        @rtype: int
        )rr@r?rr)r5r
r
rr@sz
Message.rcodecCsjtjj|�\}}|jdM_|j|O_|jtd�M_|j|O_|jdkrf|jdkrfd|_dS)zPSet the rcode.
        @param rcode: the rcode
        @type rcode: int
        i�i���rN)rr@�to_flagsrrrr)r5r@�valueZevaluer
r
r�	set_rcode"szMessage.set_rcodecCstjj|j�S)z/Return the opcode.
        @rtype: int
        )rr>r?r)r5r
r
rr>/szMessage.opcodecCs(|jdM_|jtjj|�O_dS)zTSet the opcode.
        @param opcode: the opcode
        @type opcode: int
        i��N)rrr>ro)r5r>r
r
r�
set_opcode5szMessage.set_opcode)N)NT)Nr)rrrkNN)T)r	r
rrr6r9r;r:rJrKrMrRr�	rdatatype�NONEr_r`rer%r&rjrmrnr@rqr>rrr
r
r
rrKs0K
 
7
-
!
.)
*

rc@s2eZdZdZddd�Zdd�Zdd�Zd	d
�ZdS)
�_WireReadera�Wire format reader.

    @ivar wire: the wire-format message.
    @type wire: string
    @ivar message: The message object being built
    @type message: dns.message.Message object
    @ivar current: When building a message object from wire format, this
    variable contains the offset from the beginning of wire of the next octet
    to be read.
    @type current: int
    @ivar updating: Is the message a dynamic update?
    @type updating: bool
    @ivar one_rr_per_rrset: Put each RR into its own RRset?
    @type one_rr_per_rrset: bool
    @ivar ignore_trailing: Ignore trailing junk at end of request?
    @type ignore_trailing: bool
    @ivar zone_rdclass: The class of the zone in messages which are
    DNS dynamic updates.
    @type zone_rdclass: int
    FcCs@tjj|�|_||_d|_d|_tjj|_	||_
||_||_dS)NrF)
rZwiredataZ
maybe_wrap�wire�message�current�updating�
rdataclass�IN�zone_rdclass�
question_only�one_rr_per_rrset�ignore_trailing)r5rvrwr}r~rr
r
rr6Us
z_WireReader.__init__c	Cs�|jr|dkrtjj�x�td|�D]�}tjj|j|j�\}}|j	j
dk	rV|j|j	j
�}|j||_tj
d|j|j|jd��\}}|jd|_|j	j|j	j|||ddd�|jr"||_q"WdS)z�Read the next I{qcount} records from the wire data and add them to
        the question section.
        @param qcount: the number of questions in the message
        @type qcount: intrrNz!HH�T)r\r])ryr�	exception�	FormErrorrrW�	from_wirervrxrwr/rC�struct�unpackr_rr|)r5�qcount�i�qname�usedrYrXr
r
r�
_get_question`sz_WireReader._get_questionc
CsH|js|jrd}nd}d}�x&td|�D�]}|j}tjj|j|j�\}}|}	|jj	dk	rh|j
|jj	�}|j||_tjd|j|j|jd��\}
}}}
|jd|_|
tj
jk�rn||jjk	s�|r�t�||j_||j_|d@d?|j_g|j_|j}|
}xj|dk�rdtjd	|j||d
��\}}|d
}tjj||j||�}|jjj|�||}|d
|}q�Wd}�n�|
tj
jk�rH||jjk�o�||dk�s�t�|jjdk�r�td��|jjj|	�}|dk�r�td
|��|	|j_tjj|j|j|
�\|j_|j_ tjj!|j|	|t"t#j#��|jj$||j|
|jj%|jj&|jj'�|j_%d|j_(n�|dk�rVd}|j�r�|tj)j*k�sz|tj)j+k�r�|}|j,}nd}|tj)j*k�s�|tj)j+k�r�||jj-k�r�tj
j+}d}n&tj.j||
|j|j|
|jj	�}|j/�}|jj0�r|
tj
j1k�rd}|jj2||||
||d|�}|dk	�r4|j3||�|j|
|_q(WdS)a/Read the next I{count} records from the wire data and add them to
        the specified section.
        @param section: the section of the message to which to add records
        @type section: list of dns.rrset.RRset objects
        @param count: the number of records to read
        @type count: intTFrNz!HHIH�
i�rlz!HHr�rz"got signed message without keyringzkey '%s' unknown)4ryr~rrxrrWr�rvrwr/rCr�r�rs�OPTrrr rrr!Zoption_from_wirerVZTSIGrr#rrSr$r%Zget_algorithm_and_macr'r-Zvalidate�int�timer(r0r2r3r1rz�ANYrtr|r�rdatarZr.ZSOAr_�add)r5rQ�countr]Zseen_optr�Zrr_startrWr�Z
absolute_namerYrX�ttlZrdlenrxZoptslenZotypeZolen�optZsecretr[rZ�rdrFr
r
r�_get_sectionxs� 








z_WireReader._get_sectioncCs�t|j�}|dkrt�tjd|jdd��\|j_|j_}}}}d|_t	j
j|jj�r\d|_|j
|�|jrpdS|j|jj|�|j|jj|�|j|jj|�|jr�|j|kr�t�|jjr�|jjr�|jjr�|jjj|j�dS)zNRead a wire format DNS message and build a dns.message.Message
        object.�z!HHHHHHNT)�lenrvrr�r�rwrrrxrr>rAryr�r}r�rrrrrr2r0r1�update)r5�lr�ZancountZaucountZadcountr
r
r�read�s$
*

z_WireReader.readN)FFF)r	r
rrr6r�r�r�r
r
r
rru>s

crurFTc
CsPtdd�}||_||_||_||_||_||_||_t||||	|
�}|j	�|S)a)Convert a DNS wire format message into a message
    object.

    @param keyring: The keyring to use if the message is signed.
    @type keyring: dict
    @param request_mac: If the message is a response to a TSIG-signed request,
    I{request_mac} should be set to the MAC of that request.
    @type request_mac: string
    @param xfr: Is this message part of a zone transfer?
    @type xfr: bool
    @param origin: If the message is part of a zone transfer, I{origin}
    should be the origin name of the zone.
    @type origin: dns.name.Name object
    @param tsig_ctx: The ongoing TSIG context, used when validating zone
    transfers.
    @type tsig_ctx: hmac.HMAC object
    @param multi: Is this message part of a multiple message sequence?
    @type multi: bool
    @param first: Is this message standalone, or the first of a multi
    message sequence?
    @type first: bool
    @param question_only: Read only up to the end of the question section?
    @type question_only: bool
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    @param ignore_trailing: Ignore trailing junk at end of request?
    @type ignore_trailing: bool
    @raises ShortHeader: The message is less than 12 octets long.
    @raises TrailingJunk: There were octets in the message past the end
    of the proper DNS message.
    @raises BadEDNS: An OPT record was in the wrong section, or occurred more
    than once.
    @raises BadTSIG: A TSIG record was not the last record of the additional
    data section.
    @rtype: dns.message.Message objectr)r)
rr#r(r.r/r0r2r3rur�)
rvr#r(r.r/r0r2r3r}r~r�m�readerr
r
rr��s(

r�c@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�_TextReaderaText format reader.

    @ivar tok: the tokenizer
    @type tok: dns.tokenizer.Tokenizer object
    @ivar message: The message object being built
    @type message: dns.message.Message object
    @ivar updating: Is the message a dynamic update?
    @type updating: bool
    @ivar zone_rdclass: The class of the zone in messages which are
    DNS dynamic updates.
    @type zone_rdclass: int
    @ivar last_name: The most recently read name when building a message object
    from text format.
    @type last_name: dns.name.Name object
    cCs.||_tjj|�|_d|_tjj|_d|_	dS)NF)
rwrZ	tokenizer�	Tokenizer�tok�	last_namerzr{r|ry)r5�textrwr
r
rr6>s

z_TextReader.__init__cCs�|jj�}|j}|dkr*|jj�|j_�n�|dkr�x>|jj�}|j�sT|jj|�P|jjt	jj
|j�B|j_q4Wt	jj|jj�r�d|_
�n&|dkr�|jj�|j_|jj|jjd>B|j_n�|dk�r|jjdkr�d|j_x�|jj�}|j��s�|jj|�P|jjt	jj|j�B|j_q�Wn�|dk�rN|jj�|j_|jjdk�r�d|j_nd|d	k�r�|jj�}|jjt	jjt	jj
|��B|j_n.|d
k�r�|jj�}|jjt	jj
|��nt�|jj�dS)z5Process one line from the text format header section.rrTrrlZeflagsrr r>r@N)r�rSrpZget_intrwr�
is_identifier�ungetrrrhr>rAryrrZedns_from_textr Z
get_stringrorqr@r�get_eol)r5rQ�tokenZwhatr�r
r
r�_header_lineEsR











z_TextReader._header_linecCs�|jjdd�}|j�s(tjj|jd�|_|j}|jj�}|j�sHtj	j
�y,tjj|j�}|jj�}|j�srtj	j
�Wn:tj	j
k
r�tj	j
�Yntk
r�tjj
}YnXtjj|j�}|jj|jj|||ddd�|jr�||_|jj�dS)z7Process one line from the text format question section.T)�want_leadingN)r\r])r�rS�
is_whitespacerrWrhrpr�r�r��SyntaxErrorrz�	Exceptionr{rsrwr_rryr|r�)r5rQr�rWrXrYr
r
r�_question_liness.

z_TextReader._question_linecCs�d}|jjdd�}|j�s,tjj|jd�|_|j}|jj�}|j�sLtj	j
�y*t|jd�}|jj�}|j�sttj	j
�Wn6tj	j
k
r�tj	j
�Yntk
r�d}YnXyPtj
j|j�}|jj�}|j�s�tj	j
�|tj
jks�|tj
jk�r�|}|j}Wn>tj	j
k
�r tj	j
�Yntk
�r<tj
j}YnXtjj|j�}|jj�}|j��s�|jj|�tjj|||jd�}|j�}	nd}tjj}	|jj|||||	|d|j�}
|dk	�r�|
j||�dS)zfProcess one line from the text format answer, authority, or
        additional data sections.
        NT)r�r)r�rSr�rrWrhrpr�r�r�r�r�r�rzr�rtr|r{rs�
is_eol_or_eofr�r�rZrwr_ryr�)r5rQr[r�rWr�rXrYr�rZrFr
r
r�_rr_line�sT









z_TextReader._rr_linecCs�|j}d}x�|jjdd�}|j�r$P|j�r�|jj�}|dkrF|j}nv|dksV|dkrf|j}|jj	}nV|dksv|dkr�|j
}|jj}n6|dks�|d	kr�|j
}|jj}n|d
kr�|j
}|jj
}|jj�q|jj|�||�qWdS)zNRead a text format DNS message and build a dns.message.Message
        object.NTZHEADERZQUESTIONZZONEraZPREREQrbZUPDATErc)r�r�rSr�Z
is_commentrp�upperr�rwrr�rrrr�r�)r5Zline_methodrQr��ur
r
rr��s4




z_TextReader.readN)	r	r
rrr6r�r�r�r�r
r
r
rr�,s.5r�cCst�}t||�}|j�|S)z�Convert the text format message into a message object.

    @param text: The text format message.
    @type text: string
    @raises UnknownHeaderField:
    @raises dns.exception.SyntaxError:
    @rtype: dns.message.Message object)rr�r�)r�r�r�r
r
rrh�s

rhc
CsFt}d}t||�r"t||�}d}nd}zt|�}Wd|r@|j�X|S)aRead the next text format message from the specified file.

    @param f: file or string.  If I{f} is a string, it is treated
    as the name of a file to open.
    @raises UnknownHeaderField:
    @raises dns.exception.SyntaxError:
    @rtype: dns.message.Message objectZrUTFN)rrG�openrh�close)�fZstr_typeZoptsZ
want_closer�r
r
r�	from_file�s	


r�c	Cst|t�rtjj|�}t|t�r,tjj|�}t|t�rBtjj|�}t�}	|	jtjj	O_|	j
|	j|||ddd�i}
|dk	r�||
d<|dkr�d}|dk	r�||
d<|dkr�d}|dk	r�||
d<|dkr�d}|dk	r�||
d<|dkr�d}||
d	<|	jf|
�|	j
|�|	S)
aVMake a query message.

    The query name, type, and class may all be specified either
    as objects of the appropriate type, or as strings.

    The query will have a randomly chosen query id, and its DNS flags
    will be set to dns.flags.RD.

    @param qname: The query name.
    @type qname: dns.name.Name object or string
    @param rdtype: The desired rdata type.
    @type rdtype: int
    @param rdclass: The desired rdata class; the default is class IN.
    @type rdclass: int
    @param use_edns: The EDNS level to use; the default is None (no EDNS).
    See the description of dns.message.Message.use_edns() for the possible
    values for use_edns and their meanings.
    @type use_edns: int or bool or None
    @param want_dnssec: Should the query indicate that DNSSEC is desired?
    @type want_dnssec: bool
    @param ednsflags: EDNS flag values.
    @type ednsflags: int
    @param payload: The EDNS sender's payload field, which is the maximum
    size of UDP datagram the sender can handle.
    @type payload: int
    @param request_payload: The EDNS payload size to use when sending
    this message.  If not specified, defaults to the value of payload.
    @type request_payload: int or None
    @param options: The EDNS options
    @type options: None or list of dns.edns.Option objects
    @see: RFC 2671
    @rtype: dns.message.Message objectT)r\r]Nrrr r"r!r)rGrrrWrhrsrzrr�RDr_rrmrn)r�rYrXrmrnrr r"r!r��kwargsr
r
r�
make_querys>$



r�� �,cCs�|jtjj@rtjjd��tjj|j�}tjj|jtjj@B|_|rV|jtjj	O_|j
|j��t|j
�|_
|jdkr�|jdd||j�|jr�|j|j|j|ddd|j�|j|_|S)aMake a message which is a response for the specified query.
    The message returned is really a response skeleton; it has all
    of the infrastructure required of a response, but none of the
    content.

    The response's question section is a shallow copy of the query's
    question section, so the query's question RRsets should not be
    changed.

    @param query: the query to respond to
    @type query: dns.message.Message object
    @param recursion_available: should RA be set in the response?
    @type recursion_available: bool
    @param our_payload: payload size to advertise in EDNS responses; default
    is 8192.
    @type our_payload: int
    @param fudge: TSIG time fudge; default is 300 seconds.
    @type fudge: int
    @rtype: dns.message.Message objectz&specified query message is not a queryrNr)rrrLr�r�rwrrr�ZRArrr>rfrrrmr r1rjr#r$r'r-r()ZqueryZrecursion_availableZour_payloadr+Zresponser
r
r�
make_response\s
r�)
NrFNNFTFFF)Fr�r�).rZ
__future__r�iorr�r�Zdns.ednsrZ
dns.exceptionZ	dns.flagsZdns.nameZ
dns.opcodeZdns.entropyZ	dns.rcodeZ	dns.rdataZdns.rdataclassZ
dns.rdatatypeZ	dns.rrsetZdns.rendererZdns.tsigZdns.wiredataZ_compatrrrr�r�rrZDNSExceptionrrrr�objectrrur�r�rhr�rzr{r�r�r
r
r
r�<module>sXv7
5:FPKj�\`��	77__pycache__/edns.cpython-36.pycnu�[���3

�b�W �@s@dZdZGdd�de�ZGdd�de�ZiZdd�Zdd	�Zd
S)zEDNS Options�c@sdeZdZdZdd�Zdd�Zedd��Zdd	�Zd
d�Z	dd
�Z
dd�Zdd�Zdd�Z
dd�ZdS)�Optionz*Base class for all EDNS option types.
    cCs
||_dS)z\Initialize an option.
        @param otype: The rdata type
        @type otype: int
        N)�otype)�selfr�r�/usr/lib/python3.6/edns.py�__init__szOption.__init__cCst�dS)z*Convert an option to wire format.
        N)�NotImplementedError)r�filerrr�to_wire!szOption.to_wirecCst�dS)a�Build an EDNS option object from wire format

        @param otype: The option type
        @type otype: int
        @param wire: The wire-format message
        @type wire: string
        @param current: The offset in wire of the beginning of the rdata.
        @type current: int
        @param olen: The length of the wire-format option data
        @type olen: int
        @rtype: dns.edns.Option instanceN)r)�clsr�wire�current�olenrrr�	from_wire&s
zOption.from_wirecCst�dS)z�Compare an EDNS option with another option of the same type.
        Return < 0 if self < other, 0 if self == other,
        and > 0 if self > other.
        N)r)r�otherrrr�_cmp5szOption._cmpcCs,t|t�sdS|j|jkrdS|j|�dkS)NF�)�
isinstancerrr)rrrrr�__eq__<s

z
Option.__eq__cCs,t|t�sdS|j|jkrdS|j|�dkS)NFr)rrrr)rrrrr�__ne__Cs

z
Option.__ne__cCs*t|t�s|j|jkrtS|j|�dkS)Nr)rrr�NotImplementedr)rrrrr�__lt__Jsz
Option.__lt__cCs*t|t�s|j|jkrtS|j|�dkS)Nr)rrrrr)rrrrr�__le__Psz
Option.__le__cCs*t|t�s|j|jkrtS|j|�dkS)Nr)rrrrr)rrrrr�__ge__Vsz
Option.__ge__cCs*t|t�s|j|jkrtS|j|�dkS)Nr)rrrrr)rrrrr�__gt__\sz
Option.__gt__N)�__name__�
__module__�__qualname__�__doc__rr
�classmethodrrrrrrrrrrrrrsrcs<eZdZdZ�fdd�Zdd�Zedd��Zdd	�Z�Z	S)
�
GenericOptionzwGenerate Rdata Class

    This class is used for EDNS option types for which we have no better
    implementation.
    cstt|�j|�||_dS)N)�superr r�data)rrr")�	__class__rrrkszGenericOption.__init__cCs|j|j�dS)N)�writer")rr	rrrr
oszGenericOption.to_wirecCs||||||��S)Nr)rrrr
rrrrrrszGenericOption.from_wirecCs$|j|jkrdS|j|jkr dSdS)Nr����)r")rrrrrrvs
zGenericOption._cmp)
rrrrrr
rrr�
__classcell__rr)r#rr cs
r cCstj|�}|dkrt}|S)N)�_type_to_class�getr )rrrrr�get_option_class�s
r*cCst|�}|j||||�S)auBuild an EDNS option object from wire format

    @param otype: The option type
    @type otype: int
    @param wire: The wire-format message
    @type wire: string
    @param current: The offset in wire of the beginning of the rdata.
    @type current: int
    @param olen: The length of the wire-format option data
    @type olen: int
    @rtype: dns.edns.Option instance)r*r)rrr
rrrrr�option_from_wire�s
r+N)rZNSID�objectrr r(r*r+rrrr�<module>sNPKj�\YZ
88&__pycache__/rdata.cpython-36.opt-1.pycnu�[���3

�b�W�:�@s�dZddlmZddlZddlZddlZddlZddlZddl	Zddl
ZddlZddlm
Z
mZmZdZefdd�ZdZefd	d
�Zed�Zdd
�Zdd�ZGdd�de�ZGdd�de�ZiZdZdd�Zddd�Zddd�ZdS)a�DNS rdata.

@var _rdata_modules: A dictionary mapping a (rdclass, rdtype) tuple to
the module which implements that type.
@type _rdata_modules: dict
@var _module_prefix: The prefix to use when forming modules names.  The
default is 'dns.rdtypes'.  Changing this value will break the library.
@type _module_prefix: string
@var _hex_chunk: At most this many octets that will be represented in each
chunk of hexstring that _hexify() produces before whitespace occurs.
@type _hex_chunk: int�)�BytesION�)�xrange�string_types�	text_type� cs4tj|��dj��fdd�tdt����D��j�S)aConvert a binary string into its hex encoding, broken up into chunks
    of I{chunksize} characters separated by a space.

    @param data: the binary string
    @type data: string
    @param chunksize: the chunk size.  Default is L{dns.rdata._hex_chunksize}
    @rtype: string
    � csg|]}�||���qS�r	)�.0�i)�	chunksize�liner	�/usr/lib/python3.6/rdata.py�
<listcomp>6sz_hexify.<locals>.<listcomp>r)�binasciiZhexlify�join�range�len�decode)�datarr	)rr
r�_hexify+s

rcs4tj|��dj��fdd�tdt����D��j�S)a$Convert a binary string into its base64 encoding, broken up into chunks
    of I{chunksize} characters separated by a space.

    @param data: the binary string
    @type data: string
    @param chunksize: the chunk size.  Default is
    L{dns.rdata._base64_chunksize}
    @rtype: string
    rcsg|]}�||���qSr	r	)r
r)rr
r	rrIsz_base64ify.<locals>.<listcomp>r)�base64Z	b64encoderrrr)rrr	)rr
r�
_base64ify=s
rs"\cCs~t|t�r|j�}t|t�s$t|�}d}xP|D]H}|tkrL|dt|�7}q.|dkrj|dkrj|t|�7}q.|d|7}q.W|S)z�Escape the characters in a quoted string which need it.

    @param qstring: the string
    @type qstring: string
    @returns: the escaped string
    @rtype: string
    ��\r�z\%03d)�
isinstancer�encode�	bytearray�	__escaped�chr)Zqstring�text�cr	r	r�	_escapifyOs	


r#cCsFx8tt|�ddd�D] }||dkr|d|d�SqW|dd�S)z�Determine the index of greatest byte that isn't all zeros, and
    return the bitmap that contains all the bytes less than that index.

    @param what: a string of octets representing a bitmap.
    @type what: string
    @rtype: string
    rr���r$)rr)Zwhatrr	r	r�_truncate_bitmaphs	r%c@s�eZdZdZddgZdd�Zdd�Zdd	�Zd.dd
�Zd/dd�Z	d0dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zed1d(d)��Zed2d*d+��Zd3d,d-�Zd
S)4�Rdataz(Base class for all DNS rdata types.
    �rdclass�rdtypecCs||_||_dS)z�Initialize an rdata.
        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        N)r'r()�selfr'r(r	r	r�__init__~szRdata.__init__cCstjjS)a_DNS SIG/RRSIG rdatas apply to a specific type; this type is
        returned by the covers() function.  If the rdata type is not
        SIG or RRSIG, dns.rdatatype.NONE is returned.  This is useful when
        creating rdatasets, allowing the rdataset to contain only RRSIGs
        of a particular type, e.g. RRSIG(NS).
        @rtype: int
        )�dns�	rdatatype�NONE)r)r	r	r�covers�s	zRdata.coverscCs|j�d>|jBS)z�Return a 32-bit type value, the least significant 16 bits of
        which are the ordinary DNS type, and the upper 16 bits of which are
        the "covered" type, if any.
        @rtype: int
        �)r.r()r)r	r	r�extended_rdatatype�szRdata.extended_rdatatypeNTcKst�dS)z@Convert an rdata to text format.
        @rtype: string
        N)�NotImplementedError)r)�origin�
relativize�kwr	r	r�to_text�sz
Rdata.to_textcCst�dS)z@Convert an rdata to wire format.
        @rtype: string
        N)r1)r)�file�compressr2r	r	r�to_wire�sz
Rdata.to_wirecCst�}|j|d|�|j�S)zlConvert rdata to a format suitable for digesting in hashes.  This
        is also the DNSSEC canonical form.N)rr8�getvalue)r)r2�fr	r	r�
to_digestable�szRdata.to_digestablecCstjj|j|j|j��dS)z�Check that the current contents of the rdata's fields are
        valid.  If you change an rdata by assigning to its fields,
        it is a good idea to call validate() when you are done making
        changes.
        N)r+�rdata�	from_textr'r(r5)r)r	r	r�validate�szRdata.validatecCsf|j�}|tjjkrd}ndtjj|�d}dtjj|j�dtjj|j�|dt|�dS)Nr�(�)z<DNS � z rdata: �>)	r.r+r,r-r5�
rdataclassr'r(�str)r)r.Zctextr	r	r�__repr__�s
zRdata.__repr__cCs|j�S)N)r5)r)r	r	r�__str__�sz
Rdata.__str__cCs8|jtjj�}|jtjj�}||kr(dS||kr4dSdS)z�Compare an rdata with another rdata of the same rdtype and
        rdclass.  Return < 0 if self < other in the DNSSEC ordering,
        0 if self == other, and > 0 if self > other.
        rrr$)r;r+�name�root)r)�otherZourZtheirr	r	r�_cmp�sz
Rdata._cmpcCs8t|t�sdS|j|jks&|j|jkr*dS|j|�dkS)NFr)rr&r'r(rJ)r)rIr	r	r�__eq__�s

zRdata.__eq__cCs8t|t�sdS|j|jks&|j|jkr*dS|j|�dkS)NTr)rr&r'r(rJ)r)rIr	r	r�__ne__�s

zRdata.__ne__cCs6t|t�s$|j|jks$|j|jkr(tS|j|�dkS)Nr)rr&r'r(�NotImplementedrJ)r)rIr	r	r�__lt__�szRdata.__lt__cCs6t|t�s$|j|jks$|j|jkr(tS|j|�dkS)Nr)rr&r'r(rMrJ)r)rIr	r	r�__le__�szRdata.__le__cCs6t|t�s$|j|jks$|j|jkr(tS|j|�dkS)Nr)rr&r'r(rMrJ)r)rIr	r	r�__ge__�szRdata.__ge__cCs6t|t�s$|j|jks$|j|jkr(tS|j|�dkS)Nr)rr&r'r(rMrJ)r)rIr	r	r�__gt__�szRdata.__gt__cCst|jtjj��S)N)�hashr;r+rGrH)r)r	r	r�__hash__�szRdata.__hash__cCst�dS)a�Build an rdata object from text format.

        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        @param tok: The tokenizer
        @type tok: dns.tokenizer.Tokenizer
        @param origin: The origin to use for relative names
        @type origin: dns.name.Name
        @param relativize: should names be relativized?
        @type relativize: bool
        @rtype: dns.rdata.Rdata instance
        N)r1)�clsr'r(�tokr2r3r	r	rr=�szRdata.from_textcCst�dS)a<Build an rdata object from wire format

        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        @param wire: The wire-format message
        @type wire: string
        @param current: The offset in wire of the beginning of the rdata.
        @type current: int
        @param rdlen: The length of the wire-format rdata
        @type rdlen: int
        @param origin: The origin to use for relative names
        @type origin: dns.name.Name
        @rtype: dns.rdata.Rdata instance
        N)r1)rTr'r(�wire�current�rdlenr2r	r	r�	from_wireszRdata.from_wirecCsdS)zWConvert any domain names in the rdata to the specified
        relativization.
        Nr	)r)r2r3r	r	r�choose_relativity&szRdata.choose_relativity)NT)NN)N)NT)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__r*r.r0r5r8r;r>rErFrJrKrLrNrOrPrQrS�classmethodr=rYrZr	r	r	rr&ws0	



r&csVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�GenericRdataz�Generate Rdata Class

    This class is used for rdata types for which we have no better
    implementation.  It implements the DNS "unknown RRs" scheme.
    rcstt|�j||�||_dS)N)�superrar*r)r)r'r(r)�	__class__r	rr*8szGenericRdata.__init__NTcKsdt|j�t|j�S)Nz\# %d )rrr)r)r2r3r4r	r	rr5<szGenericRdata.to_textcCs�|j�}|j�s|jdkr(tjjd��|j�}g}x&|j�}|j�rHP|j|jj	��q6Wdj
|�}	tj|	�}
t
|
�|kr�tjjd��||||
�S)Nz\#z$generic rdata does not start with \#�z'generic rdata hex data has wrong length)�get�
is_identifier�valuer+Z	exception�SyntaxErrorZget_intZ
is_eol_or_eof�appendrrrZ	unhexlifyr)rTr'r(rUr2r3�tokenZlengthZchunks�hexrr	r	rr=?s"

zGenericRdata.from_textcCs|j|j�dS)N)�writer)r)r6r7r2r	r	rr8SszGenericRdata.to_wirecCs|||||||��S)Nr	)rTr'r(rVrWrXr2r	r	rrYVszGenericRdata.from_wire)NT)NT)NN)N)r[r\r]r^r_r*r5r`r=r8rY�
__classcell__r	r	)rcrra.s

razdns.rdtypescCs�dd�}tj||f�}tjj|�}tjj|�}|jdd�}|s�tjtjj|f�}|s�y$|djt	||g��}|t||f<WnVt
k
r�y(|djt	d|g��}|ttjj|f<Wnt
k
r�d}YnXYnX|r�t||�}nt}|S)NcSs6t|�}|jd�}x|dd�D]}t||�}q W|S)N�.r)�
__import__�split�getattr)rG�modZ
components�compr	r	r�
import_module`s

z&get_rdata_class.<locals>.import_module�-�_rn�ANY)
�_rdata_modulesrer+rCr5r,�replacerwr�_module_prefix�ImportErrorrqra)r'r(rtrrZrdclass_textZrdtype_textrTr	r	r�get_rdata_class^s.r|TcCs�t|t�rtjj|�}t||�}|tkrx|j�}|j|�|j	�rx|j
dkrxtj|||||�}t|||j
dt|j
�|�S|j|||||�S)adBuild an rdata object from text format.

    This function attempts to dynamically load a class which
    implements the specified rdata class and type.  If there is no
    class-and-type-specific implementation, the GenericRdata class
    is used.

    Once a class is chosen, its from_text() class method is called
    with the parameters to this function.

    If I{tok} is a string, then a tokenizer is created and the string
    is used as its input.

    @param rdclass: The rdata class
    @type rdclass: int
    @param rdtype: The rdata type
    @type rdtype: int
    @param tok: The tokenizer or input text
    @type tok: dns.tokenizer.Tokenizer or string
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name
    @param relativize: Should names be relativized?
    @type relativize: bool
    @rtype: dns.rdata.Rdata instancez\#r)rrr+Z	tokenizer�	Tokenizerr|rareZungetrfrgr=rYrr)r'r(rUr2r3rTrjr<r	r	rr=�s



r=cCs*tjj|�}t||�}|j||||||�S)a>Build an rdata object from wire format

    This function attempts to dynamically load a class which
    implements the specified rdata class and type.  If there is no
    class-and-type-specific implementation, the GenericRdata class
    is used.

    Once a class is chosen, its from_wire() class method is called
    with the parameters to this function.

    @param rdclass: The rdata class
    @type rdclass: int
    @param rdtype: The rdata type
    @type rdtype: int
    @param wire: The wire-format message
    @type wire: string
    @param current: The offset in wire of the beginning of the rdata.
    @type current: int
    @param rdlen: The length of the wire-format rdata
    @type rdlen: int
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name
    @rtype: dns.rdata.Rdata instance)r+ZwiredataZ
maybe_wrapr|rY)r'r(rVrWrXr2rTr	r	rrY�s
rY)NT)N) r^�iorrrZ
dns.exceptionr+Zdns.nameZdns.rdataclassZ
dns.rdatatypeZ
dns.tokenizerZdns.wiredataZ_compatrrrZ_hex_chunksizerZ_base64_chunksizerrrr#r%�objectr&rarxrzr|r=rYr	r	r	r�<module>s28,"
/PKj�\�=���(__pycache__/version.cpython-36.opt-1.pycnu�[���3

�b�W��@s�dZdZdZdZdZdZedkr0deeefZn,edkrJdeeeefZndeeeeefZed>ed>Bed	>Bed
>BeBZdS)z&dnspython release version information.���z%d.%d.%dz%d.%d.%dx%dz%d.%d.%d%x%d����N)�__doc__ZMAJORZMINORZMICROZRELEASELEVELZSERIAL�version�
hexversion�rr�/usr/lib/python3.6/version.py�<module>sPKj�\��''	update.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Dynamic Update Support"""


import dns.message
import dns.name
import dns.opcode
import dns.rdata
import dns.rdataclass
import dns.rdataset
import dns.tsig
from ._compat import string_types


class Update(dns.message.Message):

    def __init__(self, zone, rdclass=dns.rdataclass.IN, keyring=None,
                 keyname=None, keyalgorithm=dns.tsig.default_algorithm):
        """Initialize a new DNS Update object.

        @param zone: The zone which is being updated.
        @type zone: A dns.name.Name or string
        @param rdclass: The class of the zone; defaults to dns.rdataclass.IN.
        @type rdclass: An int designating the class, or a string whose value
        is the name of a class.
        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @type keyname: dns.name.Name or string
        @param keyalgorithm: The TSIG algorithm to use; defaults to
        dns.tsig.default_algorithm.  Constants for TSIG algorithms are defined
        in dns.tsig, and the currently implemented algorithms are
        HMAC_MD5, HMAC_SHA1, HMAC_SHA224, HMAC_SHA256, HMAC_SHA384, and
        HMAC_SHA512.
        @type keyalgorithm: string
        """
        super(Update, self).__init__()
        self.flags |= dns.opcode.to_flags(dns.opcode.UPDATE)
        if isinstance(zone, string_types):
            zone = dns.name.from_text(zone)
        self.origin = zone
        if isinstance(rdclass, string_types):
            rdclass = dns.rdataclass.from_text(rdclass)
        self.zone_rdclass = rdclass
        self.find_rrset(self.question, self.origin, rdclass, dns.rdatatype.SOA,
                        create=True, force_unique=True)
        if keyring is not None:
            self.use_tsig(keyring, keyname, algorithm=keyalgorithm)

    def _add_rr(self, name, ttl, rd, deleting=None, section=None):
        """Add a single RR to the update section."""

        if section is None:
            section = self.authority
        covers = rd.covers()
        rrset = self.find_rrset(section, name, self.zone_rdclass, rd.rdtype,
                                covers, deleting, True, True)
        rrset.add(rd, ttl)

    def _add(self, replace, section, name, *args):
        """Add records.  The first argument is the replace mode.  If
        false, RRs are added to an existing RRset; if true, the RRset
        is replaced with the specified contents.  The second
        argument is the section to add to.  The third argument
        is always a name.  The other arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string..."""

        if isinstance(name, string_types):
            name = dns.name.from_text(name, None)
        if isinstance(args[0], dns.rdataset.Rdataset):
            for rds in args:
                if replace:
                    self.delete(name, rds.rdtype)
                for rd in rds:
                    self._add_rr(name, rds.ttl, rd, section=section)
        else:
            args = list(args)
            ttl = int(args.pop(0))
            if isinstance(args[0], dns.rdata.Rdata):
                if replace:
                    self.delete(name, args[0].rdtype)
                for rd in args:
                    self._add_rr(name, ttl, rd, section=section)
            else:
                rdtype = args.pop(0)
                if isinstance(rdtype, string_types):
                    rdtype = dns.rdatatype.from_text(rdtype)
                if replace:
                    self.delete(name, rdtype)
                for s in args:
                    rd = dns.rdata.from_text(self.zone_rdclass, rdtype, s,
                                             self.origin)
                    self._add_rr(name, ttl, rd, section=section)

    def add(self, name, *args):
        """Add records.  The first argument is always a name.  The other
        arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string..."""
        self._add(False, self.authority, name, *args)

    def delete(self, name, *args):
        """Delete records.  The first argument is always a name.  The other
        arguments can be:

                - I{nothing}

                - rdataset...

                - rdata...

                - rdtype, [string...]"""

        if isinstance(name, string_types):
            name = dns.name.from_text(name, None)
        if len(args) == 0:
            self.find_rrset(self.authority, name, dns.rdataclass.ANY,
                            dns.rdatatype.ANY, dns.rdatatype.NONE,
                            dns.rdatatype.ANY, True, True)
        elif isinstance(args[0], dns.rdataset.Rdataset):
            for rds in args:
                for rd in rds:
                    self._add_rr(name, 0, rd, dns.rdataclass.NONE)
        else:
            args = list(args)
            if isinstance(args[0], dns.rdata.Rdata):
                for rd in args:
                    self._add_rr(name, 0, rd, dns.rdataclass.NONE)
            else:
                rdtype = args.pop(0)
                if isinstance(rdtype, string_types):
                    rdtype = dns.rdatatype.from_text(rdtype)
                if len(args) == 0:
                    self.find_rrset(self.authority, name,
                                    self.zone_rdclass, rdtype,
                                    dns.rdatatype.NONE,
                                    dns.rdataclass.ANY,
                                    True, True)
                else:
                    for s in args:
                        rd = dns.rdata.from_text(self.zone_rdclass, rdtype, s,
                                                 self.origin)
                        self._add_rr(name, 0, rd, dns.rdataclass.NONE)

    def replace(self, name, *args):
        """Replace records.  The first argument is always a name.  The other
        arguments can be:

                - rdataset...

                - ttl, rdata...

                - ttl, rdtype, string...

        Note that if you want to replace the entire node, you should do
        a delete of the name followed by one or more calls to add."""

        self._add(True, self.authority, name, *args)

    def present(self, name, *args):
        """Require that an owner name (and optionally an rdata type,
        or specific rdataset) exists as a prerequisite to the
        execution of the update.  The first argument is always a name.
        The other arguments can be:

                - rdataset...

                - rdata...

                - rdtype, string..."""

        if isinstance(name, string_types):
            name = dns.name.from_text(name, None)
        if len(args) == 0:
            self.find_rrset(self.answer, name,
                            dns.rdataclass.ANY, dns.rdatatype.ANY,
                            dns.rdatatype.NONE, None,
                            True, True)
        elif isinstance(args[0], dns.rdataset.Rdataset) or \
            isinstance(args[0], dns.rdata.Rdata) or \
                len(args) > 1:
            if not isinstance(args[0], dns.rdataset.Rdataset):
                # Add a 0 TTL
                args = list(args)
                args.insert(0, 0)
            self._add(False, self.answer, name, *args)
        else:
            rdtype = args[0]
            if isinstance(rdtype, string_types):
                rdtype = dns.rdatatype.from_text(rdtype)
            self.find_rrset(self.answer, name,
                            dns.rdataclass.ANY, rdtype,
                            dns.rdatatype.NONE, None,
                            True, True)

    def absent(self, name, rdtype=None):
        """Require that an owner name (and optionally an rdata type) does
        not exist as a prerequisite to the execution of the update."""

        if isinstance(name, string_types):
            name = dns.name.from_text(name, None)
        if rdtype is None:
            self.find_rrset(self.answer, name,
                            dns.rdataclass.NONE, dns.rdatatype.ANY,
                            dns.rdatatype.NONE, None,
                            True, True)
        else:
            if isinstance(rdtype, string_types):
                rdtype = dns.rdatatype.from_text(rdtype)
            self.find_rrset(self.answer, name,
                            dns.rdataclass.NONE, rdtype,
                            dns.rdatatype.NONE, None,
                            True, True)

    def to_wire(self, origin=None, max_size=65535):
        """Return a string containing the update in DNS compressed wire
        format.
        @rtype: string"""
        if origin is None:
            origin = self.origin
        return super(Update, self).to_wire(origin, max_size)
PKj�\�^Is��tsigkeyring.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""A place to store TSIG keys."""

from dns._compat import maybe_decode, maybe_encode

import base64

import dns.name


def from_text(textring):
    """Convert a dictionary containing (textual DNS name, base64 secret) pairs
    into a binary keyring which has (dns.name.Name, binary secret) pairs.
    @rtype: dict"""

    keyring = {}
    for keytext in textring:
        keyname = dns.name.from_text(keytext)
        secret = base64.decodestring(maybe_encode(textring[keytext]))
        keyring[keyname] = secret
    return keyring


def to_text(keyring):
    """Convert a dictionary containing (dns.name.Name, binary secret) pairs
    into a text keyring which has (textual DNS name, base64 secret) pairs.
    @rtype: dict"""

    textring = {}
    for keyname in keyring:
        keytext = maybe_decode(keyname.to_text())
        secret = maybe_decode(base64.encodestring(keyring[keyname]))
        textring[keytext] = secret
    return textring
PKj�\D����9�9	dnssec.pynu�[���# Copyright (C) 2003-2007, 2009, 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Common DNSSEC-related functions and constants."""

from io import BytesIO
import struct
import time

import dns.exception
import dns.hash
import dns.name
import dns.node
import dns.rdataset
import dns.rdata
import dns.rdatatype
import dns.rdataclass
from ._compat import string_types


class UnsupportedAlgorithm(dns.exception.DNSException):

    """The DNSSEC algorithm is not supported."""


class ValidationFailure(dns.exception.DNSException):

    """The DNSSEC signature is invalid."""

RSAMD5 = 1
DH = 2
DSA = 3
ECC = 4
RSASHA1 = 5
DSANSEC3SHA1 = 6
RSASHA1NSEC3SHA1 = 7
RSASHA256 = 8
RSASHA512 = 10
ECDSAP256SHA256 = 13
ECDSAP384SHA384 = 14
INDIRECT = 252
PRIVATEDNS = 253
PRIVATEOID = 254

_algorithm_by_text = {
    'RSAMD5': RSAMD5,
    'DH': DH,
    'DSA': DSA,
    'ECC': ECC,
    'RSASHA1': RSASHA1,
    'DSANSEC3SHA1': DSANSEC3SHA1,
    'RSASHA1NSEC3SHA1': RSASHA1NSEC3SHA1,
    'RSASHA256': RSASHA256,
    'RSASHA512': RSASHA512,
    'INDIRECT': INDIRECT,
    'ECDSAP256SHA256': ECDSAP256SHA256,
    'ECDSAP384SHA384': ECDSAP384SHA384,
    'PRIVATEDNS': PRIVATEDNS,
    'PRIVATEOID': PRIVATEOID,
}

# We construct the inverse mapping programmatically to ensure that we
# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
# would cause the mapping not to be true inverse.

_algorithm_by_value = dict((y, x) for x, y in _algorithm_by_text.items())


def algorithm_from_text(text):
    """Convert text into a DNSSEC algorithm value
    @rtype: int"""

    value = _algorithm_by_text.get(text.upper())
    if value is None:
        value = int(text)
    return value


def algorithm_to_text(value):
    """Convert a DNSSEC algorithm value to text
    @rtype: string"""

    text = _algorithm_by_value.get(value)
    if text is None:
        text = str(value)
    return text


def _to_rdata(record, origin):
    s = BytesIO()
    record.to_wire(s, origin=origin)
    return s.getvalue()


def key_id(key, origin=None):
    rdata = _to_rdata(key, origin)
    rdata = bytearray(rdata)
    if key.algorithm == RSAMD5:
        return (rdata[-3] << 8) + rdata[-2]
    else:
        total = 0
        for i in range(len(rdata) // 2):
            total += (rdata[2 * i] << 8) + \
                rdata[2 * i + 1]
        if len(rdata) % 2 != 0:
            total += rdata[len(rdata) - 1] << 8
        total += ((total >> 16) & 0xffff)
        return total & 0xffff


def make_ds(name, key, algorithm, origin=None):
    if algorithm.upper() == 'SHA1':
        dsalg = 1
        hash = dns.hash.hashes['SHA1']()
    elif algorithm.upper() == 'SHA256':
        dsalg = 2
        hash = dns.hash.hashes['SHA256']()
    else:
        raise UnsupportedAlgorithm('unsupported algorithm "%s"' % algorithm)

    if isinstance(name, string_types):
        name = dns.name.from_text(name, origin)
    hash.update(name.canonicalize().to_wire())
    hash.update(_to_rdata(key, origin))
    digest = hash.digest()

    dsrdata = struct.pack("!HBB", key_id(key), key.algorithm, dsalg) + digest
    return dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.DS, dsrdata, 0,
                               len(dsrdata))


def _find_candidate_keys(keys, rrsig):
    candidate_keys = []
    value = keys.get(rrsig.signer)
    if value is None:
        return None
    if isinstance(value, dns.node.Node):
        try:
            rdataset = value.find_rdataset(dns.rdataclass.IN,
                                           dns.rdatatype.DNSKEY)
        except KeyError:
            return None
    else:
        rdataset = value
    for rdata in rdataset:
        if rdata.algorithm == rrsig.algorithm and \
                key_id(rdata) == rrsig.key_tag:
            candidate_keys.append(rdata)
    return candidate_keys


def _is_rsa(algorithm):
    return algorithm in (RSAMD5, RSASHA1,
                         RSASHA1NSEC3SHA1, RSASHA256,
                         RSASHA512)


def _is_dsa(algorithm):
    return algorithm in (DSA, DSANSEC3SHA1)


def _is_ecdsa(algorithm):
    return _have_ecdsa and (algorithm in (ECDSAP256SHA256, ECDSAP384SHA384))


def _is_md5(algorithm):
    return algorithm == RSAMD5


def _is_sha1(algorithm):
    return algorithm in (DSA, RSASHA1,
                         DSANSEC3SHA1, RSASHA1NSEC3SHA1)


def _is_sha256(algorithm):
    return algorithm in (RSASHA256, ECDSAP256SHA256)


def _is_sha384(algorithm):
    return algorithm == ECDSAP384SHA384


def _is_sha512(algorithm):
    return algorithm == RSASHA512


def _make_hash(algorithm):
    if _is_md5(algorithm):
        return dns.hash.hashes['MD5']()
    if _is_sha1(algorithm):
        return dns.hash.hashes['SHA1']()
    if _is_sha256(algorithm):
        return dns.hash.hashes['SHA256']()
    if _is_sha384(algorithm):
        return dns.hash.hashes['SHA384']()
    if _is_sha512(algorithm):
        return dns.hash.hashes['SHA512']()
    raise ValidationFailure('unknown hash for algorithm %u' % algorithm)


def _make_algorithm_id(algorithm):
    if _is_md5(algorithm):
        oid = [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05]
    elif _is_sha1(algorithm):
        oid = [0x2b, 0x0e, 0x03, 0x02, 0x1a]
    elif _is_sha256(algorithm):
        oid = [0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01]
    elif _is_sha512(algorithm):
        oid = [0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03]
    else:
        raise ValidationFailure('unknown algorithm %u' % algorithm)
    olen = len(oid)
    dlen = _make_hash(algorithm).digest_size
    idbytes = [0x30] + [8 + olen + dlen] + \
              [0x30, olen + 4] + [0x06, olen] + oid + \
              [0x05, 0x00] + [0x04, dlen]
    return struct.pack('!%dB' % len(idbytes), *idbytes)


def _validate_rrsig(rrset, rrsig, keys, origin=None, now=None):
    """Validate an RRset against a single signature rdata

    The owner name of the rrsig is assumed to be the same as the owner name
    of the rrset.

    @param rrset: The RRset to validate
    @type rrset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param rrsig: The signature rdata
    @type rrsig: dns.rrset.Rdata
    @param keys: The key dictionary.
    @type keys: a dictionary keyed by dns.name.Name with node or rdataset
    values
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name or None
    @param now: The time to use when validating the signatures.  The default
    is the current time.
    @type now: int
    """

    if isinstance(origin, string_types):
        origin = dns.name.from_text(origin, dns.name.root)

    for candidate_key in _find_candidate_keys(keys, rrsig):
        if not candidate_key:
            raise ValidationFailure('unknown key')

        # For convenience, allow the rrset to be specified as a (name,
        # rdataset) tuple as well as a proper rrset
        if isinstance(rrset, tuple):
            rrname = rrset[0]
            rdataset = rrset[1]
        else:
            rrname = rrset.name
            rdataset = rrset

        if now is None:
            now = time.time()
        if rrsig.expiration < now:
            raise ValidationFailure('expired')
        if rrsig.inception > now:
            raise ValidationFailure('not yet valid')

        hash = _make_hash(rrsig.algorithm)

        if _is_rsa(rrsig.algorithm):
            keyptr = candidate_key.key
            (bytes_,) = struct.unpack('!B', keyptr[0:1])
            keyptr = keyptr[1:]
            if bytes_ == 0:
                (bytes_,) = struct.unpack('!H', keyptr[0:2])
                keyptr = keyptr[2:]
            rsa_e = keyptr[0:bytes_]
            rsa_n = keyptr[bytes_:]
            keylen = len(rsa_n) * 8
            pubkey = Crypto.PublicKey.RSA.construct(
                (Crypto.Util.number.bytes_to_long(rsa_n),
                 Crypto.Util.number.bytes_to_long(rsa_e)))
            sig = (Crypto.Util.number.bytes_to_long(rrsig.signature),)
        elif _is_dsa(rrsig.algorithm):
            keyptr = candidate_key.key
            (t,) = struct.unpack('!B', keyptr[0:1])
            keyptr = keyptr[1:]
            octets = 64 + t * 8
            dsa_q = keyptr[0:20]
            keyptr = keyptr[20:]
            dsa_p = keyptr[0:octets]
            keyptr = keyptr[octets:]
            dsa_g = keyptr[0:octets]
            keyptr = keyptr[octets:]
            dsa_y = keyptr[0:octets]
            pubkey = Crypto.PublicKey.DSA.construct(
                (Crypto.Util.number.bytes_to_long(dsa_y),
                 Crypto.Util.number.bytes_to_long(dsa_g),
                 Crypto.Util.number.bytes_to_long(dsa_p),
                 Crypto.Util.number.bytes_to_long(dsa_q)))
            (dsa_r, dsa_s) = struct.unpack('!20s20s', rrsig.signature[1:])
            sig = (Crypto.Util.number.bytes_to_long(dsa_r),
                   Crypto.Util.number.bytes_to_long(dsa_s))
        elif _is_ecdsa(rrsig.algorithm):
            if rrsig.algorithm == ECDSAP256SHA256:
                curve = ecdsa.curves.NIST256p
                key_len = 32
            elif rrsig.algorithm == ECDSAP384SHA384:
                curve = ecdsa.curves.NIST384p
                key_len = 48
            else:
                # shouldn't happen
                raise ValidationFailure('unknown ECDSA curve')
            keyptr = candidate_key.key
            x = Crypto.Util.number.bytes_to_long(keyptr[0:key_len])
            y = Crypto.Util.number.bytes_to_long(keyptr[key_len:key_len * 2])
            assert ecdsa.ecdsa.point_is_valid(curve.generator, x, y)
            point = ecdsa.ellipticcurve.Point(curve.curve, x, y, curve.order)
            verifying_key = ecdsa.keys.VerifyingKey.from_public_point(point,
                                                                      curve)
            pubkey = ECKeyWrapper(verifying_key, key_len)
            r = rrsig.signature[:key_len]
            s = rrsig.signature[key_len:]
            sig = ecdsa.ecdsa.Signature(Crypto.Util.number.bytes_to_long(r),
                                        Crypto.Util.number.bytes_to_long(s))
        else:
            raise ValidationFailure('unknown algorithm %u' % rrsig.algorithm)

        hash.update(_to_rdata(rrsig, origin)[:18])
        hash.update(rrsig.signer.to_digestable(origin))

        if rrsig.labels < len(rrname) - 1:
            suffix = rrname.split(rrsig.labels + 1)[1]
            rrname = dns.name.from_text('*', suffix)
        rrnamebuf = rrname.to_digestable(origin)
        rrfixed = struct.pack('!HHI', rdataset.rdtype, rdataset.rdclass,
                              rrsig.original_ttl)
        rrlist = sorted(rdataset)
        for rr in rrlist:
            hash.update(rrnamebuf)
            hash.update(rrfixed)
            rrdata = rr.to_digestable(origin)
            rrlen = struct.pack('!H', len(rrdata))
            hash.update(rrlen)
            hash.update(rrdata)

        digest = hash.digest()

        if _is_rsa(rrsig.algorithm):
            # PKCS1 algorithm identifier goop
            digest = _make_algorithm_id(rrsig.algorithm) + digest
            padlen = keylen // 8 - len(digest) - 3
            digest = struct.pack('!%dB' % (2 + padlen + 1),
                                 *([0, 1] + [0xFF] * padlen + [0])) + digest
        elif _is_dsa(rrsig.algorithm) or _is_ecdsa(rrsig.algorithm):
            pass
        else:
            # Raise here for code clarity; this won't actually ever happen
            # since if the algorithm is really unknown we'd already have
            # raised an exception above
            raise ValidationFailure('unknown algorithm %u' % rrsig.algorithm)

        if pubkey.verify(digest, sig):
            return
    raise ValidationFailure('verify failure')


def _validate(rrset, rrsigset, keys, origin=None, now=None):
    """Validate an RRset

    @param rrset: The RRset to validate
    @type rrset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param rrsigset: The signature RRset
    @type rrsigset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset)
    tuple
    @param keys: The key dictionary.
    @type keys: a dictionary keyed by dns.name.Name with node or rdataset
    values
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name or None
    @param now: The time to use when validating the signatures.  The default
    is the current time.
    @type now: int
    """

    if isinstance(origin, string_types):
        origin = dns.name.from_text(origin, dns.name.root)

    if isinstance(rrset, tuple):
        rrname = rrset[0]
    else:
        rrname = rrset.name

    if isinstance(rrsigset, tuple):
        rrsigname = rrsigset[0]
        rrsigrdataset = rrsigset[1]
    else:
        rrsigname = rrsigset.name
        rrsigrdataset = rrsigset

    rrname = rrname.choose_relativity(origin)
    rrsigname = rrname.choose_relativity(origin)
    if rrname != rrsigname:
        raise ValidationFailure("owner names do not match")

    for rrsig in rrsigrdataset:
        try:
            _validate_rrsig(rrset, rrsig, keys, origin, now)
            return
        except ValidationFailure:
            pass
    raise ValidationFailure("no RRSIGs validated")


def _need_pycrypto(*args, **kwargs):
    raise NotImplementedError("DNSSEC validation requires pycrypto")

try:
    import Crypto.PublicKey.RSA
    import Crypto.PublicKey.DSA
    import Crypto.Util.number
    validate = _validate
    validate_rrsig = _validate_rrsig
    _have_pycrypto = True
except ImportError:
    validate = _need_pycrypto
    validate_rrsig = _need_pycrypto
    _have_pycrypto = False

try:
    import ecdsa
    import ecdsa.ecdsa
    import ecdsa.ellipticcurve
    import ecdsa.keys
    _have_ecdsa = True

    class ECKeyWrapper(object):

        def __init__(self, key, key_len):
            self.key = key
            self.key_len = key_len

        def verify(self, digest, sig):
            diglong = Crypto.Util.number.bytes_to_long(digest)
            return self.key.pubkey.verifies(diglong, sig)

except ImportError:
    _have_ecdsa = False
PKj�\`�oLLhash.pynu�[���# Copyright (C) 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Hashing backwards compatibility wrapper"""

import hashlib


hashes = {}
hashes['MD5'] = hashlib.md5
hashes['SHA1'] = hashlib.sha1
hashes['SHA224'] = hashlib.sha224
hashes['SHA256'] = hashlib.sha256
hashes['SHA384'] = hashlib.sha384
hashes['SHA512'] = hashlib.sha512


def get(algorithm):
    return hashes[algorithm.upper()]
PKj�\K�炕:�:rdata.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS rdata.

@var _rdata_modules: A dictionary mapping a (rdclass, rdtype) tuple to
the module which implements that type.
@type _rdata_modules: dict
@var _module_prefix: The prefix to use when forming modules names.  The
default is 'dns.rdtypes'.  Changing this value will break the library.
@type _module_prefix: string
@var _hex_chunk: At most this many octets that will be represented in each
chunk of hexstring that _hexify() produces before whitespace occurs.
@type _hex_chunk: int"""

from io import BytesIO
import base64
import binascii

import dns.exception
import dns.name
import dns.rdataclass
import dns.rdatatype
import dns.tokenizer
import dns.wiredata
from ._compat import xrange, string_types, text_type

_hex_chunksize = 32


def _hexify(data, chunksize=_hex_chunksize):
    """Convert a binary string into its hex encoding, broken up into chunks
    of I{chunksize} characters separated by a space.

    @param data: the binary string
    @type data: string
    @param chunksize: the chunk size.  Default is L{dns.rdata._hex_chunksize}
    @rtype: string
    """

    line = binascii.hexlify(data)
    return b' '.join([line[i:i + chunksize]
                      for i
                      in range(0, len(line), chunksize)]).decode()

_base64_chunksize = 32


def _base64ify(data, chunksize=_base64_chunksize):
    """Convert a binary string into its base64 encoding, broken up into chunks
    of I{chunksize} characters separated by a space.

    @param data: the binary string
    @type data: string
    @param chunksize: the chunk size.  Default is
    L{dns.rdata._base64_chunksize}
    @rtype: string
    """

    line = base64.b64encode(data)
    return b' '.join([line[i:i + chunksize]
                      for i
                      in range(0, len(line), chunksize)]).decode()

__escaped = bytearray(b'"\\')

def _escapify(qstring):
    """Escape the characters in a quoted string which need it.

    @param qstring: the string
    @type qstring: string
    @returns: the escaped string
    @rtype: string
    """

    if isinstance(qstring, text_type):
        qstring = qstring.encode()
    if not isinstance(qstring, bytearray):
        qstring = bytearray(qstring)

    text = ''
    for c in qstring:
        if c in __escaped:
            text += '\\' + chr(c)
        elif c >= 0x20 and c < 0x7F:
            text += chr(c)
        else:
            text += '\\%03d' % c
    return text


def _truncate_bitmap(what):
    """Determine the index of greatest byte that isn't all zeros, and
    return the bitmap that contains all the bytes less than that index.

    @param what: a string of octets representing a bitmap.
    @type what: string
    @rtype: string
    """

    for i in xrange(len(what) - 1, -1, -1):
        if what[i] != 0:
            return what[0: i + 1]
    return what[0:1]


class Rdata(object):

    """Base class for all DNS rdata types.
    """

    __slots__ = ['rdclass', 'rdtype']

    def __init__(self, rdclass, rdtype):
        """Initialize an rdata.
        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        """

        self.rdclass = rdclass
        self.rdtype = rdtype

    def covers(self):
        """DNS SIG/RRSIG rdatas apply to a specific type; this type is
        returned by the covers() function.  If the rdata type is not
        SIG or RRSIG, dns.rdatatype.NONE is returned.  This is useful when
        creating rdatasets, allowing the rdataset to contain only RRSIGs
        of a particular type, e.g. RRSIG(NS).
        @rtype: int
        """

        return dns.rdatatype.NONE

    def extended_rdatatype(self):
        """Return a 32-bit type value, the least significant 16 bits of
        which are the ordinary DNS type, and the upper 16 bits of which are
        the "covered" type, if any.
        @rtype: int
        """

        return self.covers() << 16 | self.rdtype

    def to_text(self, origin=None, relativize=True, **kw):
        """Convert an rdata to text format.
        @rtype: string
        """
        raise NotImplementedError

    def to_wire(self, file, compress=None, origin=None):
        """Convert an rdata to wire format.
        @rtype: string
        """

        raise NotImplementedError

    def to_digestable(self, origin=None):
        """Convert rdata to a format suitable for digesting in hashes.  This
        is also the DNSSEC canonical form."""
        f = BytesIO()
        self.to_wire(f, None, origin)
        return f.getvalue()

    def validate(self):
        """Check that the current contents of the rdata's fields are
        valid.  If you change an rdata by assigning to its fields,
        it is a good idea to call validate() when you are done making
        changes.
        """
        dns.rdata.from_text(self.rdclass, self.rdtype, self.to_text())

    def __repr__(self):
        covers = self.covers()
        if covers == dns.rdatatype.NONE:
            ctext = ''
        else:
            ctext = '(' + dns.rdatatype.to_text(covers) + ')'
        return '<DNS ' + dns.rdataclass.to_text(self.rdclass) + ' ' + \
               dns.rdatatype.to_text(self.rdtype) + ctext + ' rdata: ' + \
               str(self) + '>'

    def __str__(self):
        return self.to_text()

    def _cmp(self, other):
        """Compare an rdata with another rdata of the same rdtype and
        rdclass.  Return < 0 if self < other in the DNSSEC ordering,
        0 if self == other, and > 0 if self > other.
        """
        our = self.to_digestable(dns.name.root)
        their = other.to_digestable(dns.name.root)
        if our == their:
            return 0
        if our > their:
            return 1

        return -1

    def __eq__(self, other):
        if not isinstance(other, Rdata):
            return False
        if self.rdclass != other.rdclass or self.rdtype != other.rdtype:
            return False
        return self._cmp(other) == 0

    def __ne__(self, other):
        if not isinstance(other, Rdata):
            return True
        if self.rdclass != other.rdclass or self.rdtype != other.rdtype:
            return True
        return self._cmp(other) != 0

    def __lt__(self, other):
        if not isinstance(other, Rdata) or \
                self.rdclass != other.rdclass or self.rdtype != other.rdtype:

            return NotImplemented
        return self._cmp(other) < 0

    def __le__(self, other):
        if not isinstance(other, Rdata) or \
                self.rdclass != other.rdclass or self.rdtype != other.rdtype:
            return NotImplemented
        return self._cmp(other) <= 0

    def __ge__(self, other):
        if not isinstance(other, Rdata) or \
                self.rdclass != other.rdclass or self.rdtype != other.rdtype:
            return NotImplemented
        return self._cmp(other) >= 0

    def __gt__(self, other):
        if not isinstance(other, Rdata) or \
                self.rdclass != other.rdclass or self.rdtype != other.rdtype:
            return NotImplemented
        return self._cmp(other) > 0

    def __hash__(self):
        return hash(self.to_digestable(dns.name.root))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        """Build an rdata object from text format.

        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        @param tok: The tokenizer
        @type tok: dns.tokenizer.Tokenizer
        @param origin: The origin to use for relative names
        @type origin: dns.name.Name
        @param relativize: should names be relativized?
        @type relativize: bool
        @rtype: dns.rdata.Rdata instance
        """

        raise NotImplementedError

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        """Build an rdata object from wire format

        @param rdclass: The rdata class
        @type rdclass: int
        @param rdtype: The rdata type
        @type rdtype: int
        @param wire: The wire-format message
        @type wire: string
        @param current: The offset in wire of the beginning of the rdata.
        @type current: int
        @param rdlen: The length of the wire-format rdata
        @type rdlen: int
        @param origin: The origin to use for relative names
        @type origin: dns.name.Name
        @rtype: dns.rdata.Rdata instance
        """

        raise NotImplementedError

    def choose_relativity(self, origin=None, relativize=True):
        """Convert any domain names in the rdata to the specified
        relativization.
        """

        pass


class GenericRdata(Rdata):

    """Generate Rdata Class

    This class is used for rdata types for which we have no better
    implementation.  It implements the DNS "unknown RRs" scheme.
    """

    __slots__ = ['data']

    def __init__(self, rdclass, rdtype, data):
        super(GenericRdata, self).__init__(rdclass, rdtype)
        self.data = data

    def to_text(self, origin=None, relativize=True, **kw):
        return r'\# %d ' % len(self.data) + _hexify(self.data)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        token = tok.get()
        if not token.is_identifier() or token.value != '\#':
            raise dns.exception.SyntaxError(
                r'generic rdata does not start with \#')
        length = tok.get_int()
        chunks = []
        while 1:
            token = tok.get()
            if token.is_eol_or_eof():
                break
            chunks.append(token.value.encode())
        hex = b''.join(chunks)
        data = binascii.unhexlify(hex)
        if len(data) != length:
            raise dns.exception.SyntaxError(
                'generic rdata hex data has wrong length')
        return cls(rdclass, rdtype, data)

    def to_wire(self, file, compress=None, origin=None):
        file.write(self.data)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        return cls(rdclass, rdtype, wire[current: current + rdlen])

_rdata_modules = {}
_module_prefix = 'dns.rdtypes'


def get_rdata_class(rdclass, rdtype):

    def import_module(name):
        mod = __import__(name)
        components = name.split('.')
        for comp in components[1:]:
            mod = getattr(mod, comp)
        return mod

    mod = _rdata_modules.get((rdclass, rdtype))
    rdclass_text = dns.rdataclass.to_text(rdclass)
    rdtype_text = dns.rdatatype.to_text(rdtype)
    rdtype_text = rdtype_text.replace('-', '_')
    if not mod:
        mod = _rdata_modules.get((dns.rdatatype.ANY, rdtype))
        if not mod:
            try:
                mod = import_module('.'.join([_module_prefix,
                                              rdclass_text, rdtype_text]))
                _rdata_modules[(rdclass, rdtype)] = mod
            except ImportError:
                try:
                    mod = import_module('.'.join([_module_prefix,
                                                  'ANY', rdtype_text]))
                    _rdata_modules[(dns.rdataclass.ANY, rdtype)] = mod
                except ImportError:
                    mod = None
    if mod:
        cls = getattr(mod, rdtype_text)
    else:
        cls = GenericRdata
    return cls


def from_text(rdclass, rdtype, tok, origin=None, relativize=True):
    """Build an rdata object from text format.

    This function attempts to dynamically load a class which
    implements the specified rdata class and type.  If there is no
    class-and-type-specific implementation, the GenericRdata class
    is used.

    Once a class is chosen, its from_text() class method is called
    with the parameters to this function.

    If I{tok} is a string, then a tokenizer is created and the string
    is used as its input.

    @param rdclass: The rdata class
    @type rdclass: int
    @param rdtype: The rdata type
    @type rdtype: int
    @param tok: The tokenizer or input text
    @type tok: dns.tokenizer.Tokenizer or string
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name
    @param relativize: Should names be relativized?
    @type relativize: bool
    @rtype: dns.rdata.Rdata instance"""

    if isinstance(tok, string_types):
        tok = dns.tokenizer.Tokenizer(tok)
    cls = get_rdata_class(rdclass, rdtype)
    if cls != GenericRdata:
        # peek at first token
        token = tok.get()
        tok.unget(token)
        if token.is_identifier() and \
           token.value == r'\#':
            #
            # Known type using the generic syntax.  Extract the
            # wire form from the generic syntax, and then run
            # from_wire on it.
            #
            rdata = GenericRdata.from_text(rdclass, rdtype, tok, origin,
                                           relativize)
            return from_wire(rdclass, rdtype, rdata.data, 0, len(rdata.data),
                             origin)
    return cls.from_text(rdclass, rdtype, tok, origin, relativize)


def from_wire(rdclass, rdtype, wire, current, rdlen, origin=None):
    """Build an rdata object from wire format

    This function attempts to dynamically load a class which
    implements the specified rdata class and type.  If there is no
    class-and-type-specific implementation, the GenericRdata class
    is used.

    Once a class is chosen, its from_wire() class method is called
    with the parameters to this function.

    @param rdclass: The rdata class
    @type rdclass: int
    @param rdtype: The rdata type
    @type rdtype: int
    @param wire: The wire-format message
    @type wire: string
    @param current: The offset in wire of the beginning of the rdata.
    @type current: int
    @param rdlen: The length of the wire-format rdata
    @type rdlen: int
    @param origin: The origin to use for relative names
    @type origin: dns.name.Name
    @rtype: dns.rdata.Rdata instance"""

    wire = dns.wiredata.maybe_wrap(wire)
    cls = get_rdata_class(rdclass, rdtype)
    return cls.from_wire(rdclass, rdtype, wire, current, rdlen, origin)
PKj�\�2Y9��inet.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Generic Internet address helper functions."""

import socket

import dns.ipv4
import dns.ipv6


# We assume that AF_INET is always defined.

AF_INET = socket.AF_INET

# AF_INET6 might not be defined in the socket module, but we need it.
# We'll try to use the socket module's value, and if it doesn't work,
# we'll use our own value.

try:
    AF_INET6 = socket.AF_INET6
except AttributeError:
    AF_INET6 = 9999


def inet_pton(family, text):
    """Convert the textual form of a network address into its binary form.

    @param family: the address family
    @type family: int
    @param text: the textual address
    @type text: string
    @raises NotImplementedError: the address family specified is not
    implemented.
    @rtype: string
    """

    if family == AF_INET:
        return dns.ipv4.inet_aton(text)
    elif family == AF_INET6:
        return dns.ipv6.inet_aton(text)
    else:
        raise NotImplementedError


def inet_ntop(family, address):
    """Convert the binary form of a network address into its textual form.

    @param family: the address family
    @type family: int
    @param address: the binary address
    @type address: string
    @raises NotImplementedError: the address family specified is not
    implemented.
    @rtype: string
    """
    if family == AF_INET:
        return dns.ipv4.inet_ntoa(address)
    elif family == AF_INET6:
        return dns.ipv6.inet_ntoa(address)
    else:
        raise NotImplementedError


def af_for_address(text):
    """Determine the address family of a textual-form network address.

    @param text: the textual address
    @type text: string
    @raises ValueError: the address family cannot be determined from the input.
    @rtype: int
    """
    try:
        dns.ipv4.inet_aton(text)
        return AF_INET
    except Exception:
        try:
            dns.ipv6.inet_aton(text)
            return AF_INET6
        except:
            raise ValueError


def is_multicast(text):
    """Is the textual-form network address a multicast address?

    @param text: the textual address
    @raises ValueError: the address family cannot be determined from the input.
    @rtype: bool
    """
    try:
        first = ord(dns.ipv4.inet_aton(text)[0])
        return first >= 224 and first <= 239
    except Exception:
        try:
            first = ord(dns.ipv6.inet_aton(text)[0])
            return first == 255
        except Exception:
            raise ValueError
PKj�\��9�//__init__.pynu�[���# Copyright (C) 2003-2007, 2009, 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""dnspython DNS toolkit"""

__all__ = [
    'dnssec',
    'e164',
    'edns',
    'entropy',
    'exception',
    'flags',
    'hash',
    'inet',
    'ipv4',
    'ipv6',
    'message',
    'name',
    'namedict',
    'node',
    'opcode',
    'query',
    'rcode',
    'rdata',
    'rdataclass',
    'rdataset',
    'rdatatype',
    'renderer',
    'resolver',
    'reversename',
    'rrset',
    'set',
    'tokenizer',
    'tsig',
    'tsigkeyring',
    'ttl',
    'rdtypes',
    'update',
    'version',
    'wiredata',
    'zone',
]
PKj�\�E!o&&tsig.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS TSIG support."""

import hmac
import struct

import dns.exception
import dns.hash
import dns.rdataclass
import dns.name
from ._compat import long, string_types, text_type

class BadTime(dns.exception.DNSException):

    """The current time is not within the TSIG's validity time."""


class BadSignature(dns.exception.DNSException):

    """The TSIG signature fails to verify."""


class PeerError(dns.exception.DNSException):

    """Base class for all TSIG errors generated by the remote peer"""


class PeerBadKey(PeerError):

    """The peer didn't know the key we used"""


class PeerBadSignature(PeerError):

    """The peer didn't like the signature we sent"""


class PeerBadTime(PeerError):

    """The peer didn't like the time we sent"""


class PeerBadTruncation(PeerError):

    """The peer didn't like amount of truncation in the TSIG we sent"""

# TSIG Algorithms

HMAC_MD5 = dns.name.from_text("HMAC-MD5.SIG-ALG.REG.INT")
HMAC_SHA1 = dns.name.from_text("hmac-sha1")
HMAC_SHA224 = dns.name.from_text("hmac-sha224")
HMAC_SHA256 = dns.name.from_text("hmac-sha256")
HMAC_SHA384 = dns.name.from_text("hmac-sha384")
HMAC_SHA512 = dns.name.from_text("hmac-sha512")

_hashes = {
    HMAC_SHA224: 'SHA224',
    HMAC_SHA256: 'SHA256',
    HMAC_SHA384: 'SHA384',
    HMAC_SHA512: 'SHA512',
    HMAC_SHA1: 'SHA1',
    HMAC_MD5: 'MD5',
}

default_algorithm = HMAC_MD5

BADSIG = 16
BADKEY = 17
BADTIME = 18
BADTRUNC = 22


def sign(wire, keyname, secret, time, fudge, original_id, error,
         other_data, request_mac, ctx=None, multi=False, first=True,
         algorithm=default_algorithm):
    """Return a (tsig_rdata, mac, ctx) tuple containing the HMAC TSIG rdata
    for the input parameters, the HMAC MAC calculated by applying the
    TSIG signature algorithm, and the TSIG digest context.
    @rtype: (string, string, hmac.HMAC object)
    @raises ValueError: I{other_data} is too long
    @raises NotImplementedError: I{algorithm} is not supported
    """

    if isinstance(other_data, text_type):
        other_data = other_data.encode()
    (algorithm_name, digestmod) = get_algorithm(algorithm)
    if first:
        ctx = hmac.new(secret, digestmod=digestmod)
        ml = len(request_mac)
        if ml > 0:
            ctx.update(struct.pack('!H', ml))
            ctx.update(request_mac)
    id = struct.pack('!H', original_id)
    ctx.update(id)
    ctx.update(wire[2:])
    if first:
        ctx.update(keyname.to_digestable())
        ctx.update(struct.pack('!H', dns.rdataclass.ANY))
        ctx.update(struct.pack('!I', 0))
    long_time = time + long(0)
    upper_time = (long_time >> 32) & long(0xffff)
    lower_time = long_time & long(0xffffffff)
    time_mac = struct.pack('!HIH', upper_time, lower_time, fudge)
    pre_mac = algorithm_name + time_mac
    ol = len(other_data)
    if ol > 65535:
        raise ValueError('TSIG Other Data is > 65535 bytes')
    post_mac = struct.pack('!HH', error, ol) + other_data
    if first:
        ctx.update(pre_mac)
        ctx.update(post_mac)
    else:
        ctx.update(time_mac)
    mac = ctx.digest()
    mpack = struct.pack('!H', len(mac))
    tsig_rdata = pre_mac + mpack + mac + id + post_mac
    if multi:
        ctx = hmac.new(secret, digestmod=digestmod)
        ml = len(mac)
        ctx.update(struct.pack('!H', ml))
        ctx.update(mac)
    else:
        ctx = None
    return (tsig_rdata, mac, ctx)


def hmac_md5(wire, keyname, secret, time, fudge, original_id, error,
             other_data, request_mac, ctx=None, multi=False, first=True,
             algorithm=default_algorithm):
    return sign(wire, keyname, secret, time, fudge, original_id, error,
                other_data, request_mac, ctx, multi, first, algorithm)


def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata,
             tsig_rdlen, ctx=None, multi=False, first=True):
    """Validate the specified TSIG rdata against the other input parameters.

    @raises FormError: The TSIG is badly formed.
    @raises BadTime: There is too much time skew between the client and the
    server.
    @raises BadSignature: The TSIG signature did not validate
    @rtype: hmac.HMAC object"""

    (adcount,) = struct.unpack("!H", wire[10:12])
    if adcount == 0:
        raise dns.exception.FormError
    adcount -= 1
    new_wire = wire[0:10] + struct.pack("!H", adcount) + wire[12:tsig_start]
    current = tsig_rdata
    (aname, used) = dns.name.from_wire(wire, current)
    current = current + used
    (upper_time, lower_time, fudge, mac_size) = \
        struct.unpack("!HIHH", wire[current:current + 10])
    time = ((upper_time + long(0)) << 32) + (lower_time + long(0))
    current += 10
    mac = wire[current:current + mac_size]
    current += mac_size
    (original_id, error, other_size) = \
        struct.unpack("!HHH", wire[current:current + 6])
    current += 6
    other_data = wire[current:current + other_size]
    current += other_size
    if current != tsig_rdata + tsig_rdlen:
        raise dns.exception.FormError
    if error != 0:
        if error == BADSIG:
            raise PeerBadSignature
        elif error == BADKEY:
            raise PeerBadKey
        elif error == BADTIME:
            raise PeerBadTime
        elif error == BADTRUNC:
            raise PeerBadTruncation
        else:
            raise PeerError('unknown TSIG error code %d' % error)
    time_low = time - fudge
    time_high = time + fudge
    if now < time_low or now > time_high:
        raise BadTime
    (junk, our_mac, ctx) = sign(new_wire, keyname, secret, time, fudge,
                                original_id, error, other_data,
                                request_mac, ctx, multi, first, aname)
    if our_mac != mac:
        raise BadSignature
    return ctx


def get_algorithm(algorithm):
    """Returns the wire format string and the hash module to use for the
    specified TSIG algorithm

    @rtype: (string, hash constructor)
    @raises NotImplementedError: I{algorithm} is not supported
    """

    if isinstance(algorithm, string_types):
        algorithm = dns.name.from_text(algorithm)

    try:
        return (algorithm.to_digestable(), dns.hash.hashes[_hashes[algorithm]])
    except KeyError:
        raise NotImplementedError("TSIG algorithm " + str(algorithm) +
                                  " is not supported")


def get_algorithm_and_mac(wire, tsig_rdata, tsig_rdlen):
    """Return the tsig algorithm for the specified tsig_rdata
    @raises FormError: The TSIG is badly formed.
    """
    current = tsig_rdata
    (aname, used) = dns.name.from_wire(wire, current)
    current = current + used
    (upper_time, lower_time, fudge, mac_size) = \
        struct.unpack("!HIHH", wire[current:current + 10])
    current += 10
    mac = wire[current:current + mac_size]
    current += mac_size
    if current > tsig_rdata + tsig_rdlen:
        raise dns.exception.FormError
    return (aname, mac)
PKj�\���)!!
_compat.pynu�[���import sys
import decimal
from decimal import Context

if sys.version_info > (3,):
    long = int
    xrange = range
else:
    long = long  # pylint: disable=long-builtin
    xrange = xrange  # pylint: disable=xrange-builtin

# unicode / binary types
if sys.version_info > (3,):
    text_type = str
    binary_type = bytes
    string_types = (str,)
    unichr = chr
    def maybe_decode(x):
        return x.decode()
    def maybe_encode(x):
        return x.encode()
else:
    text_type = unicode  # pylint: disable=unicode-builtin, undefined-variable
    binary_type = str
    string_types = (
        basestring,  # pylint: disable=basestring-builtin, undefined-variable
    )
    unichr = unichr  # pylint: disable=unichr-builtin
    def maybe_decode(x):
        return x
    def maybe_encode(x):
        return x


def round_py2_compat(what):
    """
    Python 2 and Python 3 use different rounding strategies in round(). This
    function ensures that results are python2/3 compatible and backward
    compatible with previous py2 releases
    :param what: float
    :return: rounded long
    """
    d = Context(
        prec=len(str(long(what))),  # round to integer with max precision
        rounding=decimal.ROUND_HALF_UP
    ).create_decimal(str(what))  # str(): python 2.6 compat
    return long(d)
PKj�\9R����resolver.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS stub resolver.

@var default_resolver: The default resolver object
@type default_resolver: dns.resolver.Resolver object"""

import socket
import sys
import time
import random

try:
    import threading as _threading
except ImportError:
    import dummy_threading as _threading

import dns.exception
import dns.flags
import dns.ipv4
import dns.ipv6
import dns.message
import dns.name
import dns.query
import dns.rcode
import dns.rdataclass
import dns.rdatatype
import dns.reversename
import dns.tsig
from ._compat import xrange, string_types

if sys.platform == 'win32':
    try:
        import winreg as _winreg
    except ImportError:
        import _winreg  # pylint: disable=import-error

class NXDOMAIN(dns.exception.DNSException):

    """The DNS query name does not exist."""
    supp_kwargs = set(['qnames', 'responses'])
    fmt = None  # we have our own __str__ implementation

    def _check_kwargs(self, qnames, responses=None):
        if not isinstance(qnames, (list, tuple, set)):
            raise AttributeError("qnames must be a list, tuple or set")
        if len(qnames) == 0:
            raise AttributeError("qnames must contain at least one element")
        if responses is None:
            responses = {}
        elif not isinstance(responses, dict):
            raise AttributeError("responses must be a dict(qname=response)")
        kwargs = dict(qnames=qnames, responses=responses)
        return kwargs

    def __str__(self):
        if 'qnames' not in self.kwargs:
            return super(NXDOMAIN, self).__str__()
        qnames = self.kwargs['qnames']
        if len(qnames) > 1:
            msg = 'None of DNS query names exist'
        else:
            msg = self.__doc__[:-1]
        qnames = ', '.join(map(str, qnames))
        return "%s: %s" % (msg, qnames)

    def canonical_name(self):
        if not 'qnames' in self.kwargs:
            raise TypeError("parametrized exception required")
        IN = dns.rdataclass.IN
        CNAME = dns.rdatatype.CNAME
        cname = None
        for qname in self.kwargs['qnames']:
            response = self.kwargs['responses'][qname]
            for answer in response.answer:
                if answer.rdtype != CNAME or answer.rdclass != IN:
                    continue
                cname = answer.items[0].target.to_text()
            if cname is not None:
                return dns.name.from_text(cname)
        return self.kwargs['qnames'][0]
    canonical_name = property(canonical_name, doc=(
        "Return the unresolved canonical name."))

    def __add__(self, e_nx):
        """Augment by results from another NXDOMAIN exception."""
        qnames0 = list(self.kwargs.get('qnames', []))
        responses0 = dict(self.kwargs.get('responses', {}))
        responses1 = e_nx.kwargs.get('responses', {})
        for qname1 in e_nx.kwargs.get('qnames', []):
            if qname1 not in qnames0:
                qnames0.append(qname1)
            if qname1 in responses1:
                responses0[qname1] = responses1[qname1]
        return NXDOMAIN(qnames=qnames0, responses=responses0)


class YXDOMAIN(dns.exception.DNSException):

    """The DNS query name is too long after DNAME substitution."""

# The definition of the Timeout exception has moved from here to the
# dns.exception module.  We keep dns.resolver.Timeout defined for
# backwards compatibility.

Timeout = dns.exception.Timeout


class NoAnswer(dns.exception.DNSException):

    """The DNS response does not contain an answer to the question."""
    fmt = 'The DNS response does not contain an answer ' + \
          'to the question: {query}'
    supp_kwargs = set(['response'])

    def _fmt_kwargs(self, **kwargs):
        return super(NoAnswer, self)._fmt_kwargs(
            query=kwargs['response'].question)


class NoNameservers(dns.exception.DNSException):

    """All nameservers failed to answer the query.

    errors: list of servers and respective errors
    The type of errors is
    [(server ip address, any object convertible to string)].
    Non-empty errors list will add explanatory message ()
    """

    msg = "All nameservers failed to answer the query."
    fmt = "%s {query}: {errors}" % msg[:-1]
    supp_kwargs = set(['request', 'errors'])

    def _fmt_kwargs(self, **kwargs):
        srv_msgs = []
        for err in kwargs['errors']:
            srv_msgs.append('Server %s %s port %s answered %s' % (err[0],
                            'TCP' if err[1] else 'UDP', err[2], err[3]))
        return super(NoNameservers, self)._fmt_kwargs(
            query=kwargs['request'].question, errors='; '.join(srv_msgs))


class NotAbsolute(dns.exception.DNSException):

    """An absolute domain name is required but a relative name was provided."""


class NoRootSOA(dns.exception.DNSException):

    """There is no SOA RR at the DNS root name. This should never happen!"""


class NoMetaqueries(dns.exception.DNSException):

    """DNS metaqueries are not allowed."""


class Answer(object):

    """DNS stub resolver answer

    Instances of this class bundle up the result of a successful DNS
    resolution.

    For convenience, the answer object implements much of the sequence
    protocol, forwarding to its rrset.  E.g. "for a in answer" is
    equivalent to "for a in answer.rrset", "answer[i]" is equivalent
    to "answer.rrset[i]", and "answer[i:j]" is equivalent to
    "answer.rrset[i:j]".

    Note that CNAMEs or DNAMEs in the response may mean that answer
    node's name might not be the query name.

    @ivar qname: The query name
    @type qname: dns.name.Name object
    @ivar rdtype: The query type
    @type rdtype: int
    @ivar rdclass: The query class
    @type rdclass: int
    @ivar response: The response message
    @type response: dns.message.Message object
    @ivar rrset: The answer
    @type rrset: dns.rrset.RRset object
    @ivar expiration: The time when the answer expires
    @type expiration: float (seconds since the epoch)
    @ivar canonical_name: The canonical name of the query name
    @type canonical_name: dns.name.Name object
    """

    def __init__(self, qname, rdtype, rdclass, response,
                 raise_on_no_answer=True):
        self.qname = qname
        self.rdtype = rdtype
        self.rdclass = rdclass
        self.response = response
        min_ttl = -1
        rrset = None
        for count in xrange(0, 15):
            try:
                rrset = response.find_rrset(response.answer, qname,
                                            rdclass, rdtype)
                if min_ttl == -1 or rrset.ttl < min_ttl:
                    min_ttl = rrset.ttl
                break
            except KeyError:
                if rdtype != dns.rdatatype.CNAME:
                    try:
                        crrset = response.find_rrset(response.answer,
                                                     qname,
                                                     rdclass,
                                                     dns.rdatatype.CNAME)
                        if min_ttl == -1 or crrset.ttl < min_ttl:
                            min_ttl = crrset.ttl
                        for rd in crrset:
                            qname = rd.target
                            break
                        continue
                    except KeyError:
                        if raise_on_no_answer:
                            raise NoAnswer(response=response)
                if raise_on_no_answer:
                    raise NoAnswer(response=response)
        if rrset is None and raise_on_no_answer:
            raise NoAnswer(response=response)
        self.canonical_name = qname
        self.rrset = rrset
        if rrset is None:
            while 1:
                # Look for a SOA RR whose owner name is a superdomain
                # of qname.
                try:
                    srrset = response.find_rrset(response.authority, qname,
                                                 rdclass, dns.rdatatype.SOA)
                    if min_ttl == -1 or srrset.ttl < min_ttl:
                        min_ttl = srrset.ttl
                    if srrset[0].minimum < min_ttl:
                        min_ttl = srrset[0].minimum
                    break
                except KeyError:
                    try:
                        qname = qname.parent()
                    except dns.name.NoParent:
                        break
        self.expiration = time.time() + min_ttl

    def __getattr__(self, attr):
        if attr == 'name':
            return self.rrset.name
        elif attr == 'ttl':
            return self.rrset.ttl
        elif attr == 'covers':
            return self.rrset.covers
        elif attr == 'rdclass':
            return self.rrset.rdclass
        elif attr == 'rdtype':
            return self.rrset.rdtype
        else:
            raise AttributeError(attr)

    def __len__(self):
        return self.rrset and len(self.rrset) or 0

    def __iter__(self):
        return self.rrset and iter(self.rrset) or iter(tuple())

    def __getitem__(self, i):
        return self.rrset[i]

    def __delitem__(self, i):
        del self.rrset[i]


class Cache(object):

    """Simple DNS answer cache.

    @ivar data: A dictionary of cached data
    @type data: dict
    @ivar cleaning_interval: The number of seconds between cleanings.  The
    default is 300 (5 minutes).
    @type cleaning_interval: float
    @ivar next_cleaning: The time the cache should next be cleaned (in seconds
    since the epoch.)
    @type next_cleaning: float
    """

    def __init__(self, cleaning_interval=300.0):
        """Initialize a DNS cache.

        @param cleaning_interval: the number of seconds between periodic
        cleanings.  The default is 300.0
        @type cleaning_interval: float.
        """

        self.data = {}
        self.cleaning_interval = cleaning_interval
        self.next_cleaning = time.time() + self.cleaning_interval
        self.lock = _threading.Lock()

    def _maybe_clean(self):
        """Clean the cache if it's time to do so."""

        now = time.time()
        if self.next_cleaning <= now:
            keys_to_delete = []
            for (k, v) in self.data.items():
                if v.expiration <= now:
                    keys_to_delete.append(k)
            for k in keys_to_delete:
                del self.data[k]
            now = time.time()
            self.next_cleaning = now + self.cleaning_interval

    def get(self, key):
        """Get the answer associated with I{key}.  Returns None if
        no answer is cached for the key.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @rtype: dns.resolver.Answer object or None
        """

        try:
            self.lock.acquire()
            self._maybe_clean()
            v = self.data.get(key)
            if v is None or v.expiration <= time.time():
                return None
            return v
        finally:
            self.lock.release()

    def put(self, key, value):
        """Associate key and value in the cache.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @param value: The answer being cached
        @type value: dns.resolver.Answer object
        """

        try:
            self.lock.acquire()
            self._maybe_clean()
            self.data[key] = value
        finally:
            self.lock.release()

    def flush(self, key=None):
        """Flush the cache.

        If I{key} is specified, only that item is flushed.  Otherwise
        the entire cache is flushed.

        @param key: the key to flush
        @type key: (dns.name.Name, int, int) tuple or None
        """

        try:
            self.lock.acquire()
            if key is not None:
                if key in self.data:
                    del self.data[key]
            else:
                self.data = {}
                self.next_cleaning = time.time() + self.cleaning_interval
        finally:
            self.lock.release()


class LRUCacheNode(object):

    """LRUCache node.
    """

    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.prev = self
        self.next = self

    def link_before(self, node):
        self.prev = node.prev
        self.next = node
        node.prev.next = self
        node.prev = self

    def link_after(self, node):
        self.prev = node
        self.next = node.next
        node.next.prev = self
        node.next = self

    def unlink(self):
        self.next.prev = self.prev
        self.prev.next = self.next


class LRUCache(object):

    """Bounded least-recently-used DNS answer cache.

    This cache is better than the simple cache (above) if you're
    running a web crawler or other process that does a lot of
    resolutions.  The LRUCache has a maximum number of nodes, and when
    it is full, the least-recently used node is removed to make space
    for a new one.

    @ivar data: A dictionary of cached data
    @type data: dict
    @ivar sentinel: sentinel node for circular doubly linked list of nodes
    @type sentinel: LRUCacheNode object
    @ivar max_size: The maximum number of nodes
    @type max_size: int
    """

    def __init__(self, max_size=100000):
        """Initialize a DNS cache.

        @param max_size: The maximum number of nodes to cache; the default is
        100,000. Must be greater than 1.
        @type max_size: int
        """
        self.data = {}
        self.set_max_size(max_size)
        self.sentinel = LRUCacheNode(None, None)
        self.lock = _threading.Lock()

    def set_max_size(self, max_size):
        if max_size < 1:
            max_size = 1
        self.max_size = max_size

    def get(self, key):
        """Get the answer associated with I{key}.  Returns None if
        no answer is cached for the key.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @rtype: dns.resolver.Answer object or None
        """
        try:
            self.lock.acquire()
            node = self.data.get(key)
            if node is None:
                return None
            # Unlink because we're either going to move the node to the front
            # of the LRU list or we're going to free it.
            node.unlink()
            if node.value.expiration <= time.time():
                del self.data[node.key]
                return None
            node.link_after(self.sentinel)
            return node.value
        finally:
            self.lock.release()

    def put(self, key, value):
        """Associate key and value in the cache.
        @param key: the key
        @type key: (dns.name.Name, int, int) tuple whose values are the
        query name, rdtype, and rdclass.
        @param value: The answer being cached
        @type value: dns.resolver.Answer object
        """
        try:
            self.lock.acquire()
            node = self.data.get(key)
            if node is not None:
                node.unlink()
                del self.data[node.key]
            while len(self.data) >= self.max_size:
                node = self.sentinel.prev
                node.unlink()
                del self.data[node.key]
            node = LRUCacheNode(key, value)
            node.link_after(self.sentinel)
            self.data[key] = node
        finally:
            self.lock.release()

    def flush(self, key=None):
        """Flush the cache.

        If I{key} is specified, only that item is flushed.  Otherwise
        the entire cache is flushed.

        @param key: the key to flush
        @type key: (dns.name.Name, int, int) tuple or None
        """
        try:
            self.lock.acquire()
            if key is not None:
                node = self.data.get(key)
                if node is not None:
                    node.unlink()
                    del self.data[node.key]
            else:
                node = self.sentinel.next
                while node != self.sentinel:
                    next = node.next
                    node.prev = None
                    node.next = None
                    node = next
                self.data = {}
        finally:
            self.lock.release()


class Resolver(object):

    """DNS stub resolver

    @ivar domain: The domain of this host
    @type domain: dns.name.Name object
    @ivar nameservers: A list of nameservers to query.  Each nameserver is
    a string which contains the IP address of a nameserver.
    @type nameservers: list of strings
    @ivar search: The search list.  If the query name is a relative name,
    the resolver will construct an absolute query name by appending the search
    names one by one to the query name.
    @type search: list of dns.name.Name objects
    @ivar port: The port to which to send queries.  The default is 53.
    @type port: int
    @ivar timeout: The number of seconds to wait for a response from a
    server, before timing out.
    @type timeout: float
    @ivar lifetime: The total number of seconds to spend trying to get an
    answer to the question.  If the lifetime expires, a Timeout exception
    will occur.
    @type lifetime: float
    @ivar keyring: The TSIG keyring to use.  The default is None.
    @type keyring: dict
    @ivar keyname: The TSIG keyname to use.  The default is None.
    @type keyname: dns.name.Name object
    @ivar keyalgorithm: The TSIG key algorithm to use.  The default is
    dns.tsig.default_algorithm.
    @type keyalgorithm: string
    @ivar edns: The EDNS level to use.  The default is -1, no Edns.
    @type edns: int
    @ivar ednsflags: The EDNS flags
    @type ednsflags: int
    @ivar payload: The EDNS payload size.  The default is 0.
    @type payload: int
    @ivar flags: The message flags to use.  The default is None (i.e. not
    overwritten)
    @type flags: int
    @ivar cache: The cache to use.  The default is None.
    @type cache: dns.resolver.Cache object
    @ivar retry_servfail: should we retry a nameserver if it says SERVFAIL?
    The default is 'false'.
    @type retry_servfail: bool
    """

    def __init__(self, filename='/etc/resolv.conf', configure=True):
        """Initialize a resolver instance.

        @param filename: The filename of a configuration file in
        standard /etc/resolv.conf format.  This parameter is meaningful
        only when I{configure} is true and the platform is POSIX.
        @type filename: string or file object
        @param configure: If True (the default), the resolver instance
        is configured in the normal fashion for the operating system
        the resolver is running on.  (I.e. a /etc/resolv.conf file on
        POSIX systems and from the registry on Windows systems.)
        @type configure: bool"""

        self.domain = None
        self.nameservers = None
        self.nameserver_ports = None
        self.port = None
        self.search = None
        self.timeout = None
        self.lifetime = None
        self.keyring = None
        self.keyname = None
        self.keyalgorithm = None
        self.edns = None
        self.ednsflags = None
        self.payload = None
        self.cache = None
        self.flags = None
        self.retry_servfail = False
        self.rotate = False

        self.reset()
        if configure:
            if sys.platform == 'win32':
                self.read_registry()
            elif filename:
                self.read_resolv_conf(filename)

    def reset(self):
        """Reset all resolver configuration to the defaults."""
        self.domain = \
            dns.name.Name(dns.name.from_text(socket.gethostname())[1:])
        if len(self.domain) == 0:
            self.domain = dns.name.root
        self.nameservers = []
        self.nameserver_ports = {}
        self.port = 53
        self.search = []
        self.timeout = 2.0
        self.lifetime = 30.0
        self.keyring = None
        self.keyname = None
        self.keyalgorithm = dns.tsig.default_algorithm
        self.edns = -1
        self.ednsflags = 0
        self.payload = 0
        self.cache = None
        self.flags = None
        self.retry_servfail = False
        self.rotate = False

    def read_resolv_conf(self, f):
        """Process f as a file in the /etc/resolv.conf format.  If f is
        a string, it is used as the name of the file to open; otherwise it
        is treated as the file itself."""
        if isinstance(f, string_types):
            try:
                f = open(f, 'r')
            except IOError:
                # /etc/resolv.conf doesn't exist, can't be read, etc.
                # We'll just use the default resolver configuration.
                self.nameservers = ['127.0.0.1']
                return
            want_close = True
        else:
            want_close = False
        try:
            for l in f:
                if len(l) == 0 or l[0] == '#' or l[0] == ';':
                    continue
                tokens = l.split()

                # Any line containing less than 2 tokens is malformed
                if len(tokens) < 2:
                    continue

                if tokens[0] == 'nameserver':
                    self.nameservers.append(tokens[1])
                elif tokens[0] == 'domain':
                    self.domain = dns.name.from_text(tokens[1])
                elif tokens[0] == 'search':
                    for suffix in tokens[1:]:
                        self.search.append(dns.name.from_text(suffix))
                elif tokens[0] == 'options':
                    if 'rotate' in tokens[1:]:
                        self.rotate = True
        finally:
            if want_close:
                f.close()
        if len(self.nameservers) == 0:
            self.nameservers.append('127.0.0.1')

    def _determine_split_char(self, entry):
        #
        # The windows registry irritatingly changes the list element
        # delimiter in between ' ' and ',' (and vice-versa) in various
        # versions of windows.
        #
        if entry.find(' ') >= 0:
            split_char = ' '
        elif entry.find(',') >= 0:
            split_char = ','
        else:
            # probably a singleton; treat as a space-separated list.
            split_char = ' '
        return split_char

    def _config_win32_nameservers(self, nameservers):
        """Configure a NameServer registry entry."""
        # we call str() on nameservers to convert it from unicode to ascii
        nameservers = str(nameservers)
        split_char = self._determine_split_char(nameservers)
        ns_list = nameservers.split(split_char)
        for ns in ns_list:
            if ns not in self.nameservers:
                self.nameservers.append(ns)

    def _config_win32_domain(self, domain):
        """Configure a Domain registry entry."""
        # we call str() on domain to convert it from unicode to ascii
        self.domain = dns.name.from_text(str(domain))

    def _config_win32_search(self, search):
        """Configure a Search registry entry."""
        # we call str() on search to convert it from unicode to ascii
        search = str(search)
        split_char = self._determine_split_char(search)
        search_list = search.split(split_char)
        for s in search_list:
            if s not in self.search:
                self.search.append(dns.name.from_text(s))

    def _config_win32_fromkey(self, key):
        """Extract DNS info from a registry key."""
        try:
            servers, rtype = _winreg.QueryValueEx(key, 'NameServer')
        except WindowsError:  # pylint: disable=undefined-variable
            servers = None
        if servers:
            self._config_win32_nameservers(servers)
            try:
                dom, rtype = _winreg.QueryValueEx(key, 'Domain')
                if dom:
                    self._config_win32_domain(dom)
            except WindowsError:  # pylint: disable=undefined-variable
                pass
        else:
            try:
                servers, rtype = _winreg.QueryValueEx(key, 'DhcpNameServer')
            except WindowsError:  # pylint: disable=undefined-variable
                servers = None
            if servers:
                self._config_win32_nameservers(servers)
                try:
                    dom, rtype = _winreg.QueryValueEx(key, 'DhcpDomain')
                    if dom:
                        self._config_win32_domain(dom)
                except WindowsError:  # pylint: disable=undefined-variable
                    pass
        try:
            search, rtype = _winreg.QueryValueEx(key, 'SearchList')
        except WindowsError:  # pylint: disable=undefined-variable
            search = None
        if search:
            self._config_win32_search(search)

    def read_registry(self):
        """Extract resolver configuration from the Windows registry."""
        lm = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
        want_scan = False
        try:
            try:
                # XP, 2000
                tcp_params = _winreg.OpenKey(lm,
                                             r'SYSTEM\CurrentControlSet'
                                             r'\Services\Tcpip\Parameters')
                want_scan = True
            except EnvironmentError:
                # ME
                tcp_params = _winreg.OpenKey(lm,
                                             r'SYSTEM\CurrentControlSet'
                                             r'\Services\VxD\MSTCP')
            try:
                self._config_win32_fromkey(tcp_params)
            finally:
                tcp_params.Close()
            if want_scan:
                interfaces = _winreg.OpenKey(lm,
                                             r'SYSTEM\CurrentControlSet'
                                             r'\Services\Tcpip\Parameters'
                                             r'\Interfaces')
                try:
                    i = 0
                    while True:
                        try:
                            guid = _winreg.EnumKey(interfaces, i)
                            i += 1
                            key = _winreg.OpenKey(interfaces, guid)
                            if not self._win32_is_nic_enabled(lm, guid, key):
                                continue
                            try:
                                self._config_win32_fromkey(key)
                            finally:
                                key.Close()
                        except EnvironmentError:
                            break
                finally:
                    interfaces.Close()
        finally:
            lm.Close()

    def _win32_is_nic_enabled(self, lm, guid, interface_key):
        # Look in the Windows Registry to determine whether the network
        # interface corresponding to the given guid is enabled.
        #
        # (Code contributed by Paul Marks, thanks!)
        #
        try:
            # This hard-coded location seems to be consistent, at least
            # from Windows 2000 through Vista.
            connection_key = _winreg.OpenKey(
                lm,
                r'SYSTEM\CurrentControlSet\Control\Network'
                r'\{4D36E972-E325-11CE-BFC1-08002BE10318}'
                r'\%s\Connection' % guid)

            try:
                # The PnpInstanceID points to a key inside Enum
                (pnp_id, ttype) = _winreg.QueryValueEx(
                    connection_key, 'PnpInstanceID')

                if ttype != _winreg.REG_SZ:
                    raise ValueError

                device_key = _winreg.OpenKey(
                    lm, r'SYSTEM\CurrentControlSet\Enum\%s' % pnp_id)

                try:
                    # Get ConfigFlags for this device
                    (flags, ttype) = _winreg.QueryValueEx(
                        device_key, 'ConfigFlags')

                    if ttype != _winreg.REG_DWORD:
                        raise ValueError

                    # Based on experimentation, bit 0x1 indicates that the
                    # device is disabled.
                    return not flags & 0x1

                finally:
                    device_key.Close()
            finally:
                connection_key.Close()
        except (EnvironmentError, ValueError):
            # Pre-vista, enabled interfaces seem to have a non-empty
            # NTEContextList; this was how dnspython detected enabled
            # nics before the code above was contributed.  We've retained
            # the old method since we don't know if the code above works
            # on Windows 95/98/ME.
            try:
                (nte, ttype) = _winreg.QueryValueEx(interface_key,
                                                    'NTEContextList')
                return nte is not None
            except WindowsError:  # pylint: disable=undefined-variable
                return False

    def _compute_timeout(self, start):
        now = time.time()
        duration = now - start
        if duration < 0:
            if duration < -1:
                # Time going backwards is bad.  Just give up.
                raise Timeout(timeout=duration)
            else:
                # Time went backwards, but only a little.  This can
                # happen, e.g. under vmware with older linux kernels.
                # Pretend it didn't happen.
                now = start
        if duration >= self.lifetime:
            raise Timeout(timeout=duration)
        return min(self.lifetime - duration, self.timeout)

    def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
              tcp=False, source=None, raise_on_no_answer=True, source_port=0):
        """Query nameservers to find the answer to the question.

        The I{qname}, I{rdtype}, and I{rdclass} parameters may be objects
        of the appropriate type, or strings that can be converted into objects
        of the appropriate type.  E.g. For I{rdtype} the integer 2 and the
        the string 'NS' both mean to query for records with DNS rdata type NS.

        @param qname: the query name
        @type qname: dns.name.Name object or string
        @param rdtype: the query type
        @type rdtype: int or string
        @param rdclass: the query class
        @type rdclass: int or string
        @param tcp: use TCP to make the query (default is False).
        @type tcp: bool
        @param source: bind to this IP address (defaults to machine default
        IP).
        @type source: IP address in dotted quad notation
        @param raise_on_no_answer: raise NoAnswer if there's no answer
        (defaults is True).
        @type raise_on_no_answer: bool
        @param source_port: The port from which to send the message.
        The default is 0.
        @type source_port: int
        @rtype: dns.resolver.Answer instance
        @raises Timeout: no answers could be found in the specified lifetime
        @raises NXDOMAIN: the query name does not exist
        @raises YXDOMAIN: the query name is too long after DNAME substitution
        @raises NoAnswer: the response did not contain an answer and
        raise_on_no_answer is True.
        @raises NoNameservers: no non-broken nameservers are available to
        answer the question."""

        if isinstance(qname, string_types):
            qname = dns.name.from_text(qname, None)
        if isinstance(rdtype, string_types):
            rdtype = dns.rdatatype.from_text(rdtype)
        if dns.rdatatype.is_metatype(rdtype):
            raise NoMetaqueries
        if isinstance(rdclass, string_types):
            rdclass = dns.rdataclass.from_text(rdclass)
        if dns.rdataclass.is_metaclass(rdclass):
            raise NoMetaqueries
        qnames_to_try = []
        if qname.is_absolute():
            qnames_to_try.append(qname)
        else:
            if len(qname) > 1:
                qnames_to_try.append(qname.concatenate(dns.name.root))
            if self.search:
                for suffix in self.search:
                    qnames_to_try.append(qname.concatenate(suffix))
            else:
                qnames_to_try.append(qname.concatenate(self.domain))
        all_nxdomain = True
        nxdomain_responses = {}
        start = time.time()
        _qname = None # make pylint happy
        for _qname in qnames_to_try:
            if self.cache:
                answer = self.cache.get((_qname, rdtype, rdclass))
                if answer is not None:
                    if answer.rrset is None and raise_on_no_answer:
                        raise NoAnswer(response=answer.response)
                    else:
                        return answer
            request = dns.message.make_query(_qname, rdtype, rdclass)
            if self.keyname is not None:
                request.use_tsig(self.keyring, self.keyname,
                                 algorithm=self.keyalgorithm)
            request.use_edns(self.edns, self.ednsflags, self.payload)
            if self.flags is not None:
                request.flags = self.flags
            response = None
            #
            # make a copy of the servers list so we can alter it later.
            #
            nameservers = self.nameservers[:]
            errors = []
            if self.rotate:
                random.shuffle(nameservers)
            backoff = 0.10
            while response is None:
                if len(nameservers) == 0:
                    raise NoNameservers(request=request, errors=errors)
                for nameserver in nameservers[:]:
                    timeout = self._compute_timeout(start)
                    port = self.nameserver_ports.get(nameserver, self.port)
                    try:
                        tcp_attempt = tcp
                        if tcp:
                            response = dns.query.tcp(request, nameserver,
                                                     timeout, port,
                                                     source=source,
                                                     source_port=source_port)
                        else:
                            response = dns.query.udp(request, nameserver,
                                                     timeout, port,
                                                     source=source,
                                                     source_port=source_port)
                            if response.flags & dns.flags.TC:
                                # Response truncated; retry with TCP.
                                tcp_attempt = True
                                timeout = self._compute_timeout(start)
                                response = \
                                    dns.query.tcp(request, nameserver,
                                                  timeout, port,
                                                  source=source,
                                                  source_port=source_port)
                    except (socket.error, dns.exception.Timeout) as ex:
                        #
                        # Communication failure or timeout.  Go to the
                        # next server
                        #
                        errors.append((nameserver, tcp_attempt, port, ex,
                                       response))
                        response = None
                        continue
                    except dns.query.UnexpectedSource as ex:
                        #
                        # Who knows?  Keep going.
                        #
                        errors.append((nameserver, tcp_attempt, port, ex,
                                       response))
                        response = None
                        continue
                    except dns.exception.FormError as ex:
                        #
                        # We don't understand what this server is
                        # saying.  Take it out of the mix and
                        # continue.
                        #
                        nameservers.remove(nameserver)
                        errors.append((nameserver, tcp_attempt, port, ex,
                                       response))
                        response = None
                        continue
                    except EOFError as ex:
                        #
                        # We're using TCP and they hung up on us.
                        # Probably they don't support TCP (though
                        # they're supposed to!).  Take it out of the
                        # mix and continue.
                        #
                        nameservers.remove(nameserver)
                        errors.append((nameserver, tcp_attempt, port, ex,
                                       response))
                        response = None
                        continue
                    rcode = response.rcode()
                    if rcode == dns.rcode.YXDOMAIN:
                        ex = YXDOMAIN()
                        errors.append((nameserver, tcp_attempt, port, ex,
                                       response))
                        raise ex
                    if rcode == dns.rcode.NOERROR or \
                            rcode == dns.rcode.NXDOMAIN:
                        break
                    #
                    # We got a response, but we're not happy with the
                    # rcode in it.  Remove the server from the mix if
                    # the rcode isn't SERVFAIL.
                    #
                    if rcode != dns.rcode.SERVFAIL or not self.retry_servfail:
                        nameservers.remove(nameserver)
                    errors.append((nameserver, tcp_attempt, port,
                                   dns.rcode.to_text(rcode), response))
                    response = None
                if response is not None:
                    break
                #
                # All nameservers failed!
                #
                if len(nameservers) > 0:
                    #
                    # But we still have servers to try.  Sleep a bit
                    # so we don't pound them!
                    #
                    timeout = self._compute_timeout(start)
                    sleep_time = min(timeout, backoff)
                    backoff *= 2
                    time.sleep(sleep_time)
            if response.rcode() == dns.rcode.NXDOMAIN:
                nxdomain_responses[_qname] = response
                continue
            all_nxdomain = False
            break
        if all_nxdomain:
            raise NXDOMAIN(qnames=qnames_to_try, responses=nxdomain_responses)
        answer = Answer(_qname, rdtype, rdclass, response,
                        raise_on_no_answer)
        if self.cache:
            self.cache.put((_qname, rdtype, rdclass), answer)
        return answer

    def use_tsig(self, keyring, keyname=None,
                 algorithm=dns.tsig.default_algorithm):
        """Add a TSIG signature to the query.

        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @param algorithm: The TSIG key algorithm to use.  The default
        is dns.tsig.default_algorithm.
        @type algorithm: string"""
        self.keyring = keyring
        if keyname is None:
            self.keyname = list(self.keyring.keys())[0]
        else:
            self.keyname = keyname
        self.keyalgorithm = algorithm

    def use_edns(self, edns, ednsflags, payload):
        """Configure Edns.

        @param edns: The EDNS level to use.  The default is -1, no Edns.
        @type edns: int
        @param ednsflags: The EDNS flags
        @type ednsflags: int
        @param payload: The EDNS payload size.  The default is 0.
        @type payload: int"""

        if edns is None:
            edns = -1
        self.edns = edns
        self.ednsflags = ednsflags
        self.payload = payload

    def set_flags(self, flags):
        """Overrides the default flags with your own

        @param flags: The flags to overwrite the default with
        @type flags: int"""
        self.flags = flags

default_resolver = None


def get_default_resolver():
    """Get the default resolver, initializing it if necessary."""
    if default_resolver is None:
        reset_default_resolver()
    return default_resolver


def reset_default_resolver():
    """Re-initialize default resolver.

    resolv.conf will be re-read immediatelly.
    """
    global default_resolver
    default_resolver = Resolver()


def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
          tcp=False, source=None, raise_on_no_answer=True,
          source_port=0):
    """Query nameservers to find the answer to the question.

    This is a convenience function that uses the default resolver
    object to make the query.
    @see: L{dns.resolver.Resolver.query} for more information on the
    parameters."""
    return get_default_resolver().query(qname, rdtype, rdclass, tcp, source,
                                        raise_on_no_answer, source_port)


def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None):
    """Find the name of the zone which contains the specified name.

    @param name: the query name
    @type name: absolute dns.name.Name object or string
    @param rdclass: The query class
    @type rdclass: int
    @param tcp: use TCP to make the query (default is False).
    @type tcp: bool
    @param resolver: the resolver to use
    @type resolver: dns.resolver.Resolver object or None
    @rtype: dns.name.Name"""

    if isinstance(name, string_types):
        name = dns.name.from_text(name, dns.name.root)
    if resolver is None:
        resolver = get_default_resolver()
    if not name.is_absolute():
        raise NotAbsolute(name)
    while 1:
        try:
            answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp)
            if answer.rrset.name == name:
                return name
            # otherwise we were CNAMEd or DNAMEd and need to look higher
        except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
            pass
        try:
            name = name.parent()
        except dns.name.NoParent:
            raise NoRootSOA

#
# Support for overriding the system resolver for all python code in the
# running process.
#

_protocols_for_socktype = {
    socket.SOCK_DGRAM: [socket.SOL_UDP],
    socket.SOCK_STREAM: [socket.SOL_TCP],
}

_resolver = None
_original_getaddrinfo = socket.getaddrinfo
_original_getnameinfo = socket.getnameinfo
_original_getfqdn = socket.getfqdn
_original_gethostbyname = socket.gethostbyname
_original_gethostbyname_ex = socket.gethostbyname_ex
_original_gethostbyaddr = socket.gethostbyaddr


def _getaddrinfo(host=None, service=None, family=socket.AF_UNSPEC, socktype=0,
                 proto=0, flags=0):
    if flags & (socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) != 0:
        raise NotImplementedError
    if host is None and service is None:
        raise socket.gaierror(socket.EAI_NONAME)
    v6addrs = []
    v4addrs = []
    canonical_name = None
    try:
        # Is host None or a V6 address literal?
        if host is None:
            canonical_name = 'localhost'
            if flags & socket.AI_PASSIVE != 0:
                v6addrs.append('::')
                v4addrs.append('0.0.0.0')
            else:
                v6addrs.append('::1')
                v4addrs.append('127.0.0.1')
        else:
            parts = host.split('%')
            if len(parts) == 2:
                ahost = parts[0]
            else:
                ahost = host
            addr = dns.ipv6.inet_aton(ahost)
            v6addrs.append(host)
            canonical_name = host
    except Exception:
        try:
            # Is it a V4 address literal?
            addr = dns.ipv4.inet_aton(host)
            v4addrs.append(host)
            canonical_name = host
        except Exception:
            if flags & socket.AI_NUMERICHOST == 0:
                try:
                    if family == socket.AF_INET6 or family == socket.AF_UNSPEC:
                        v6 = _resolver.query(host, dns.rdatatype.AAAA,
                                             raise_on_no_answer=False)
                        # Note that setting host ensures we query the same name
                        # for A as we did for AAAA.
                        host = v6.qname
                        canonical_name = v6.canonical_name.to_text(True)
                        if v6.rrset is not None:
                            for rdata in v6.rrset:
                                v6addrs.append(rdata.address)
                    if family == socket.AF_INET or family == socket.AF_UNSPEC:
                        v4 = _resolver.query(host, dns.rdatatype.A,
                                             raise_on_no_answer=False)
                        host = v4.qname
                        canonical_name = v4.canonical_name.to_text(True)
                        if v4.rrset is not None:
                            for rdata in v4.rrset:
                                v4addrs.append(rdata.address)
                except dns.resolver.NXDOMAIN:
                    raise socket.gaierror(socket.EAI_NONAME)
                except:
                    raise socket.gaierror(socket.EAI_SYSTEM)
    port = None
    try:
        # Is it a port literal?
        if service is None:
            port = 0
        else:
            port = int(service)
    except Exception:
        if flags & socket.AI_NUMERICSERV == 0:
            try:
                port = socket.getservbyname(service)
            except Exception:
                pass
    if port is None:
        raise socket.gaierror(socket.EAI_NONAME)
    tuples = []
    if socktype == 0:
        socktypes = [socket.SOCK_DGRAM, socket.SOCK_STREAM]
    else:
        socktypes = [socktype]
    if flags & socket.AI_CANONNAME != 0:
        cname = canonical_name
    else:
        cname = ''
    if family == socket.AF_INET6 or family == socket.AF_UNSPEC:
        for addr in v6addrs:
            for socktype in socktypes:
                for proto in _protocols_for_socktype[socktype]:
                    tuples.append((socket.AF_INET6, socktype, proto,
                                   cname, (addr, port, 0, 0)))
    if family == socket.AF_INET or family == socket.AF_UNSPEC:
        for addr in v4addrs:
            for socktype in socktypes:
                for proto in _protocols_for_socktype[socktype]:
                    tuples.append((socket.AF_INET, socktype, proto,
                                   cname, (addr, port)))
    if len(tuples) == 0:
        raise socket.gaierror(socket.EAI_NONAME)
    return tuples


def _getnameinfo(sockaddr, flags=0):
    host = sockaddr[0]
    port = sockaddr[1]
    if len(sockaddr) == 4:
        scope = sockaddr[3]
        family = socket.AF_INET6
    else:
        scope = None
        family = socket.AF_INET
    tuples = _getaddrinfo(host, port, family, socket.SOCK_STREAM,
                          socket.SOL_TCP, 0)
    if len(tuples) > 1:
        raise socket.error('sockaddr resolved to multiple addresses')
    addr = tuples[0][4][0]
    if flags & socket.NI_DGRAM:
        pname = 'udp'
    else:
        pname = 'tcp'
    qname = dns.reversename.from_address(addr)
    if flags & socket.NI_NUMERICHOST == 0:
        try:
            answer = _resolver.query(qname, 'PTR')
            hostname = answer.rrset[0].target.to_text(True)
        except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
            if flags & socket.NI_NAMEREQD:
                raise socket.gaierror(socket.EAI_NONAME)
            hostname = addr
            if scope is not None:
                hostname += '%' + str(scope)
    else:
        hostname = addr
        if scope is not None:
            hostname += '%' + str(scope)
    if flags & socket.NI_NUMERICSERV:
        service = str(port)
    else:
        service = socket.getservbyport(port, pname)
    return (hostname, service)


def _getfqdn(name=None):
    if name is None:
        name = socket.gethostname()
    try:
        return _getnameinfo(_getaddrinfo(name, 80)[0][4])[0]
    except Exception:
        return name


def _gethostbyname(name):
    return _gethostbyname_ex(name)[2][0]


def _gethostbyname_ex(name):
    aliases = []
    addresses = []
    tuples = _getaddrinfo(name, 0, socket.AF_INET, socket.SOCK_STREAM,
                          socket.SOL_TCP, socket.AI_CANONNAME)
    canonical = tuples[0][3]
    for item in tuples:
        addresses.append(item[4][0])
    # XXX we just ignore aliases
    return (canonical, aliases, addresses)


def _gethostbyaddr(ip):
    try:
        dns.ipv6.inet_aton(ip)
        sockaddr = (ip, 80, 0, 0)
        family = socket.AF_INET6
    except Exception:
        sockaddr = (ip, 80)
        family = socket.AF_INET
    (name, port) = _getnameinfo(sockaddr, socket.NI_NAMEREQD)
    aliases = []
    addresses = []
    tuples = _getaddrinfo(name, 0, family, socket.SOCK_STREAM, socket.SOL_TCP,
                          socket.AI_CANONNAME)
    canonical = tuples[0][3]
    for item in tuples:
        addresses.append(item[4][0])
    # XXX we just ignore aliases
    return (canonical, aliases, addresses)


def override_system_resolver(resolver=None):
    """Override the system resolver routines in the socket module with
    versions which use dnspython's resolver.

    This can be useful in testing situations where you want to control
    the resolution behavior of python code without having to change
    the system's resolver settings (e.g. /etc/resolv.conf).

    The resolver to use may be specified; if it's not, the default
    resolver will be used.

    @param resolver: the resolver to use
    @type resolver: dns.resolver.Resolver object or None
    """
    if resolver is None:
        resolver = get_default_resolver()
    global _resolver
    _resolver = resolver
    socket.getaddrinfo = _getaddrinfo
    socket.getnameinfo = _getnameinfo
    socket.getfqdn = _getfqdn
    socket.gethostbyname = _gethostbyname
    socket.gethostbyname_ex = _gethostbyname_ex
    socket.gethostbyaddr = _gethostbyaddr


def restore_system_resolver():
    """Undo the effects of override_system_resolver().
    """
    global _resolver
    _resolver = None
    socket.getaddrinfo = _original_getaddrinfo
    socket.getnameinfo = _original_getnameinfo
    socket.getfqdn = _original_getfqdn
    socket.gethostbyname = _original_gethostbyname
    socket.gethostbyname_ex = _original_gethostbyname_ex
    socket.gethostbyaddr = _original_gethostbyaddr
PKj�\2�5
##set.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""A simple Set class."""


class Set(object):

    """A simple set class.

    Sets are not in Python until 2.3, and rdata are not immutable so
    we cannot use sets.Set anyway.  This class implements subset of
    the 2.3 Set interface using a list as the container.

    @ivar items: A list of the items which are in the set
    @type items: list"""

    __slots__ = ['items']

    def __init__(self, items=None):
        """Initialize the set.

        @param items: the initial set of items
        @type items: any iterable or None
        """

        self.items = []
        if items is not None:
            for item in items:
                self.add(item)

    def __repr__(self):
        return "dns.simpleset.Set(%s)" % repr(self.items)

    def add(self, item):
        """Add an item to the set."""
        if item not in self.items:
            self.items.append(item)

    def remove(self, item):
        """Remove an item from the set."""
        self.items.remove(item)

    def discard(self, item):
        """Remove an item from the set if present."""
        try:
            self.items.remove(item)
        except ValueError:
            pass

    def _clone(self):
        """Make a (shallow) copy of the set.

        There is a 'clone protocol' that subclasses of this class
        should use.  To make a copy, first call your super's _clone()
        method, and use the object returned as the new instance.  Then
        make shallow copies of the attributes defined in the subclass.

        This protocol allows us to write the set algorithms that
        return new instances (e.g. union) once, and keep using them in
        subclasses.
        """

        cls = self.__class__
        obj = cls.__new__(cls)
        obj.items = list(self.items)
        return obj

    def __copy__(self):
        """Make a (shallow) copy of the set."""
        return self._clone()

    def copy(self):
        """Make a (shallow) copy of the set."""
        return self._clone()

    def union_update(self, other):
        """Update the set, adding any elements from other which are not
        already in the set.
        @param other: the collection of items with which to update the set
        @type other: Set object
        """
        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        if self is other:
            return
        for item in other.items:
            self.add(item)

    def intersection_update(self, other):
        """Update the set, removing any elements from other which are not
        in both sets.
        @param other: the collection of items with which to update the set
        @type other: Set object
        """
        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        if self is other:
            return
        # we make a copy of the list so that we can remove items from
        # the list without breaking the iterator.
        for item in list(self.items):
            if item not in other.items:
                self.items.remove(item)

    def difference_update(self, other):
        """Update the set, removing any elements from other which are in
        the set.
        @param other: the collection of items with which to update the set
        @type other: Set object
        """
        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        if self is other:
            self.items = []
        else:
            for item in other.items:
                self.discard(item)

    def union(self, other):
        """Return a new set which is the union of I{self} and I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        """

        obj = self._clone()
        obj.union_update(other)
        return obj

    def intersection(self, other):
        """Return a new set which is the intersection of I{self} and I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        """

        obj = self._clone()
        obj.intersection_update(other)
        return obj

    def difference(self, other):
        """Return a new set which I{self} - I{other}, i.e. the items
        in I{self} which are not also in I{other}.

        @param other: the other set
        @type other: Set object
        @rtype: the same type as I{self}
        """

        obj = self._clone()
        obj.difference_update(other)
        return obj

    def __or__(self, other):
        return self.union(other)

    def __and__(self, other):
        return self.intersection(other)

    def __add__(self, other):
        return self.union(other)

    def __sub__(self, other):
        return self.difference(other)

    def __ior__(self, other):
        self.union_update(other)
        return self

    def __iand__(self, other):
        self.intersection_update(other)
        return self

    def __iadd__(self, other):
        self.union_update(other)
        return self

    def __isub__(self, other):
        self.difference_update(other)
        return self

    def update(self, other):
        """Update the set, adding any elements from other which are not
        already in the set.
        @param other: the collection of items with which to update the set
        @type other: any iterable type"""
        for item in other:
            self.add(item)

    def clear(self):
        """Make the set empty."""
        self.items = []

    def __eq__(self, other):
        # Yes, this is inefficient but the sets we're dealing with are
        # usually quite small, so it shouldn't hurt too much.
        for item in self.items:
            if item not in other.items:
                return False
        for item in other.items:
            if item not in self.items:
                return False
        return True

    def __ne__(self, other):
        return not self.__eq__(other)

    def __len__(self):
        return len(self.items)

    def __iter__(self):
        return iter(self.items)

    def __getitem__(self, i):
        return self.items[i]

    def __delitem__(self, i):
        del self.items[i]

    def issubset(self, other):
        """Is I{self} a subset of I{other}?

        @rtype: bool
        """

        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        for item in self.items:
            if item not in other.items:
                return False
        return True

    def issuperset(self, other):
        """Is I{self} a superset of I{other}?

        @rtype: bool
        """

        if not isinstance(other, Set):
            raise ValueError('other must be a Set instance')
        for item in other.items:
            if item not in self.items:
                return False
        return True
PKj�\���ӉG�Gtokenizer.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Tokenize DNS master file format"""

from io import StringIO
import sys

import dns.exception
import dns.name
import dns.ttl
from ._compat import long, text_type, binary_type

_DELIMITERS = {
    ' ': True,
    '\t': True,
    '\n': True,
    ';': True,
    '(': True,
    ')': True,
    '"': True}

_QUOTING_DELIMITERS = {'"': True}

EOF = 0
EOL = 1
WHITESPACE = 2
IDENTIFIER = 3
QUOTED_STRING = 4
COMMENT = 5
DELIMITER = 6


class UngetBufferFull(dns.exception.DNSException):

    """An attempt was made to unget a token when the unget buffer was full."""


class Token(object):

    """A DNS master file format token.

    @ivar ttype: The token type
    @type ttype: int
    @ivar value: The token value
    @type value: string
    @ivar has_escape: Does the token value contain escapes?
    @type has_escape: bool
    """

    def __init__(self, ttype, value='', has_escape=False):
        """Initialize a token instance.

        @param ttype: The token type
        @type ttype: int
        @param value: The token value
        @type value: string
        @param has_escape: Does the token value contain escapes?
        @type has_escape: bool
        """
        self.ttype = ttype
        self.value = value
        self.has_escape = has_escape

    def is_eof(self):
        return self.ttype == EOF

    def is_eol(self):
        return self.ttype == EOL

    def is_whitespace(self):
        return self.ttype == WHITESPACE

    def is_identifier(self):
        return self.ttype == IDENTIFIER

    def is_quoted_string(self):
        return self.ttype == QUOTED_STRING

    def is_comment(self):
        return self.ttype == COMMENT

    def is_delimiter(self):
        return self.ttype == DELIMITER

    def is_eol_or_eof(self):
        return self.ttype == EOL or self.ttype == EOF

    def __eq__(self, other):
        if not isinstance(other, Token):
            return False
        return (self.ttype == other.ttype and
                self.value == other.value)

    def __ne__(self, other):
        if not isinstance(other, Token):
            return True
        return (self.ttype != other.ttype or
                self.value != other.value)

    def __str__(self):
        return '%d "%s"' % (self.ttype, self.value)

    def unescape(self):
        if not self.has_escape:
            return self
        unescaped = ''
        l = len(self.value)
        i = 0
        while i < l:
            c = self.value[i]
            i += 1
            if c == '\\':
                if i >= l:
                    raise dns.exception.UnexpectedEnd
                c = self.value[i]
                i += 1
                if c.isdigit():
                    if i >= l:
                        raise dns.exception.UnexpectedEnd
                    c2 = self.value[i]
                    i += 1
                    if i >= l:
                        raise dns.exception.UnexpectedEnd
                    c3 = self.value[i]
                    i += 1
                    if not (c2.isdigit() and c3.isdigit()):
                        raise dns.exception.SyntaxError
                    c = chr(int(c) * 100 + int(c2) * 10 + int(c3))
            unescaped += c
        return Token(self.ttype, unescaped)

    # compatibility for old-style tuple tokens

    def __len__(self):
        return 2

    def __iter__(self):
        return iter((self.ttype, self.value))

    def __getitem__(self, i):
        if i == 0:
            return self.ttype
        elif i == 1:
            return self.value
        else:
            raise IndexError


class Tokenizer(object):

    """A DNS master file format tokenizer.

    A token is a (type, value) tuple, where I{type} is an int, and
    I{value} is a string.  The valid types are EOF, EOL, WHITESPACE,
    IDENTIFIER, QUOTED_STRING, COMMENT, and DELIMITER.

    @ivar file: The file to tokenize
    @type file: file
    @ivar ungotten_char: The most recently ungotten character, or None.
    @type ungotten_char: string
    @ivar ungotten_token: The most recently ungotten token, or None.
    @type ungotten_token: (int, string) token tuple
    @ivar multiline: The current multiline level.  This value is increased
    by one every time a '(' delimiter is read, and decreased by one every time
    a ')' delimiter is read.
    @type multiline: int
    @ivar quoting: This variable is true if the tokenizer is currently
    reading a quoted string.
    @type quoting: bool
    @ivar eof: This variable is true if the tokenizer has encountered EOF.
    @type eof: bool
    @ivar delimiters: The current delimiter dictionary.
    @type delimiters: dict
    @ivar line_number: The current line number
    @type line_number: int
    @ivar filename: A filename that will be returned by the L{where} method.
    @type filename: string
    """

    def __init__(self, f=sys.stdin, filename=None):
        """Initialize a tokenizer instance.

        @param f: The file to tokenize.  The default is sys.stdin.
        This parameter may also be a string, in which case the tokenizer
        will take its input from the contents of the string.
        @type f: file or string
        @param filename: the name of the filename that the L{where} method
        will return.
        @type filename: string
        """

        if isinstance(f, text_type):
            f = StringIO(f)
            if filename is None:
                filename = '<string>'
        elif isinstance(f, binary_type):
            f = StringIO(f.decode())
            if filename is None:
                filename = '<string>'
        else:
            if filename is None:
                if f is sys.stdin:
                    filename = '<stdin>'
                else:
                    filename = '<file>'
        self.file = f
        self.ungotten_char = None
        self.ungotten_token = None
        self.multiline = 0
        self.quoting = False
        self.eof = False
        self.delimiters = _DELIMITERS
        self.line_number = 1
        self.filename = filename

    def _get_char(self):
        """Read a character from input.
        @rtype: string
        """

        if self.ungotten_char is None:
            if self.eof:
                c = ''
            else:
                c = self.file.read(1)
                if c == '':
                    self.eof = True
                elif c == '\n':
                    self.line_number += 1
        else:
            c = self.ungotten_char
            self.ungotten_char = None
        return c

    def where(self):
        """Return the current location in the input.

        @rtype: (string, int) tuple.  The first item is the filename of
        the input, the second is the current line number.
        """

        return (self.filename, self.line_number)

    def _unget_char(self, c):
        """Unget a character.

        The unget buffer for characters is only one character large; it is
        an error to try to unget a character when the unget buffer is not
        empty.

        @param c: the character to unget
        @type c: string
        @raises UngetBufferFull: there is already an ungotten char
        """

        if self.ungotten_char is not None:
            raise UngetBufferFull
        self.ungotten_char = c

    def skip_whitespace(self):
        """Consume input until a non-whitespace character is encountered.

        The non-whitespace character is then ungotten, and the number of
        whitespace characters consumed is returned.

        If the tokenizer is in multiline mode, then newlines are whitespace.

        @rtype: int
        """

        skipped = 0
        while True:
            c = self._get_char()
            if c != ' ' and c != '\t':
                if (c != '\n') or not self.multiline:
                    self._unget_char(c)
                    return skipped
            skipped += 1

    def get(self, want_leading=False, want_comment=False):
        """Get the next token.

        @param want_leading: If True, return a WHITESPACE token if the
        first character read is whitespace.  The default is False.
        @type want_leading: bool
        @param want_comment: If True, return a COMMENT token if the
        first token read is a comment.  The default is False.
        @type want_comment: bool
        @rtype: Token object
        @raises dns.exception.UnexpectedEnd: input ended prematurely
        @raises dns.exception.SyntaxError: input was badly formed
        """

        if self.ungotten_token is not None:
            token = self.ungotten_token
            self.ungotten_token = None
            if token.is_whitespace():
                if want_leading:
                    return token
            elif token.is_comment():
                if want_comment:
                    return token
            else:
                return token
        skipped = self.skip_whitespace()
        if want_leading and skipped > 0:
            return Token(WHITESPACE, ' ')
        token = ''
        ttype = IDENTIFIER
        has_escape = False
        while True:
            c = self._get_char()
            if c == '' or c in self.delimiters:
                if c == '' and self.quoting:
                    raise dns.exception.UnexpectedEnd
                if token == '' and ttype != QUOTED_STRING:
                    if c == '(':
                        self.multiline += 1
                        self.skip_whitespace()
                        continue
                    elif c == ')':
                        if self.multiline <= 0:
                            raise dns.exception.SyntaxError
                        self.multiline -= 1
                        self.skip_whitespace()
                        continue
                    elif c == '"':
                        if not self.quoting:
                            self.quoting = True
                            self.delimiters = _QUOTING_DELIMITERS
                            ttype = QUOTED_STRING
                            continue
                        else:
                            self.quoting = False
                            self.delimiters = _DELIMITERS
                            self.skip_whitespace()
                            continue
                    elif c == '\n':
                        return Token(EOL, '\n')
                    elif c == ';':
                        while 1:
                            c = self._get_char()
                            if c == '\n' or c == '':
                                break
                            token += c
                        if want_comment:
                            self._unget_char(c)
                            return Token(COMMENT, token)
                        elif c == '':
                            if self.multiline:
                                raise dns.exception.SyntaxError(
                                    'unbalanced parentheses')
                            return Token(EOF)
                        elif self.multiline:
                            self.skip_whitespace()
                            token = ''
                            continue
                        else:
                            return Token(EOL, '\n')
                    else:
                        # This code exists in case we ever want a
                        # delimiter to be returned.  It never produces
                        # a token currently.
                        token = c
                        ttype = DELIMITER
                else:
                    self._unget_char(c)
                break
            elif self.quoting:
                if c == '\\':
                    c = self._get_char()
                    if c == '':
                        raise dns.exception.UnexpectedEnd
                    if c.isdigit():
                        c2 = self._get_char()
                        if c2 == '':
                            raise dns.exception.UnexpectedEnd
                        c3 = self._get_char()
                        if c == '':
                            raise dns.exception.UnexpectedEnd
                        if not (c2.isdigit() and c3.isdigit()):
                            raise dns.exception.SyntaxError
                        c = chr(int(c) * 100 + int(c2) * 10 + int(c3))
                elif c == '\n':
                    raise dns.exception.SyntaxError('newline in quoted string')
            elif c == '\\':
                #
                # It's an escape.  Put it and the next character into
                # the token; it will be checked later for goodness.
                #
                token += c
                has_escape = True
                c = self._get_char()
                if c == '' or c == '\n':
                    raise dns.exception.UnexpectedEnd
            token += c
        if token == '' and ttype != QUOTED_STRING:
            if self.multiline:
                raise dns.exception.SyntaxError('unbalanced parentheses')
            ttype = EOF
        return Token(ttype, token, has_escape)

    def unget(self, token):
        """Unget a token.

        The unget buffer for tokens is only one token large; it is
        an error to try to unget a token when the unget buffer is not
        empty.

        @param token: the token to unget
        @type token: Token object
        @raises UngetBufferFull: there is already an ungotten token
        """

        if self.ungotten_token is not None:
            raise UngetBufferFull
        self.ungotten_token = token

    def next(self):
        """Return the next item in an iteration.
        @rtype: (int, string)
        """

        token = self.get()
        if token.is_eof():
            raise StopIteration
        return token

    __next__ = next

    def __iter__(self):
        return self

    # Helpers

    def get_int(self):
        """Read the next token and interpret it as an integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        """

        token = self.get().unescape()
        if not token.is_identifier():
            raise dns.exception.SyntaxError('expecting an identifier')
        if not token.value.isdigit():
            raise dns.exception.SyntaxError('expecting an integer')
        return int(token.value)

    def get_uint8(self):
        """Read the next token and interpret it as an 8-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        """

        value = self.get_int()
        if value < 0 or value > 255:
            raise dns.exception.SyntaxError(
                '%d is not an unsigned 8-bit integer' % value)
        return value

    def get_uint16(self):
        """Read the next token and interpret it as a 16-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        """

        value = self.get_int()
        if value < 0 or value > 65535:
            raise dns.exception.SyntaxError(
                '%d is not an unsigned 16-bit integer' % value)
        return value

    def get_uint32(self):
        """Read the next token and interpret it as a 32-bit unsigned
        integer.

        @raises dns.exception.SyntaxError:
        @rtype: int
        """

        token = self.get().unescape()
        if not token.is_identifier():
            raise dns.exception.SyntaxError('expecting an identifier')
        if not token.value.isdigit():
            raise dns.exception.SyntaxError('expecting an integer')
        value = long(token.value)
        if value < 0 or value > long(4294967296):
            raise dns.exception.SyntaxError(
                '%d is not an unsigned 32-bit integer' % value)
        return value

    def get_string(self, origin=None):
        """Read the next token and interpret it as a string.

        @raises dns.exception.SyntaxError:
        @rtype: string
        """

        token = self.get().unescape()
        if not (token.is_identifier() or token.is_quoted_string()):
            raise dns.exception.SyntaxError('expecting a string')
        return token.value

    def get_identifier(self, origin=None):
        """Read the next token and raise an exception if it is not an identifier.

        @raises dns.exception.SyntaxError:
        @rtype: string
        """

        token = self.get().unescape()
        if not token.is_identifier():
            raise dns.exception.SyntaxError('expecting an identifier')
        return token.value

    def get_name(self, origin=None):
        """Read the next token and interpret it as a DNS name.

        @raises dns.exception.SyntaxError:
        @rtype: dns.name.Name object"""

        token = self.get()
        if not token.is_identifier():
            raise dns.exception.SyntaxError('expecting an identifier')
        return dns.name.from_text(token.value, origin)

    def get_eol(self):
        """Read the next token and raise an exception if it isn't EOL or
        EOF.

        @raises dns.exception.SyntaxError:
        @rtype: string
        """

        token = self.get()
        if not token.is_eol_or_eof():
            raise dns.exception.SyntaxError(
                'expected EOL or EOF, got %d "%s"' % (token.ttype,
                                                      token.value))
        return token.value

    def get_ttl(self):
        token = self.get().unescape()
        if not token.is_identifier():
            raise dns.exception.SyntaxError('expecting an identifier')
        return dns.ttl.from_text(token.value)
PKj�\���	�		opcode.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Opcodes."""

import dns.exception

QUERY = 0
IQUERY = 1
STATUS = 2
NOTIFY = 4
UPDATE = 5

_by_text = {
    'QUERY': QUERY,
    'IQUERY': IQUERY,
    'STATUS': STATUS,
    'NOTIFY': NOTIFY,
    'UPDATE': UPDATE
}

# We construct the inverse mapping programmatically to ensure that we
# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
# would cause the mapping not to be true inverse.

_by_value = dict((y, x) for x, y in _by_text.items())


class UnknownOpcode(dns.exception.DNSException):

    """An DNS opcode is unknown."""


def from_text(text):
    """Convert text into an opcode.

    @param text: the textual opcode
    @type text: string
    @raises UnknownOpcode: the opcode is unknown
    @rtype: int
    """

    if text.isdigit():
        value = int(text)
        if value >= 0 and value <= 15:
            return value
    value = _by_text.get(text.upper())
    if value is None:
        raise UnknownOpcode
    return value


def from_flags(flags):
    """Extract an opcode from DNS message flags.

    @param flags: int
    @rtype: int
    """

    return (flags & 0x7800) >> 11


def to_flags(value):
    """Convert an opcode to a value suitable for ORing into DNS message
    flags.
    @rtype: int
    """

    return (value << 11) & 0x7800


def to_text(value):
    """Convert an opcode to text.

    @param value: the opcdoe
    @type value: int
    @raises UnknownOpcode: the opcode is unknown
    @rtype: string
    """

    text = _by_value.get(value)
    if text is None:
        text = str(value)
    return text


def is_update(flags):
    """True if the opcode in flags is UPDATE.

    @param flags: DNS flags
    @type flags: int
    @rtype: bool
    """

    return from_flags(flags) == UPDATE
PKj�\O���ttl.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS TTL conversion."""

import dns.exception
from ._compat import long


class BadTTL(dns.exception.SyntaxError):

    """DNS TTL value is not well-formed."""


def from_text(text):
    """Convert the text form of a TTL to an integer.

    The BIND 8 units syntax for TTLs (e.g. '1w6d4h3m10s') is supported.

    @param text: the textual TTL
    @type text: string
    @raises dns.ttl.BadTTL: the TTL is not well-formed
    @rtype: int
    """

    if text.isdigit():
        total = long(text)
    else:
        if not text[0].isdigit():
            raise BadTTL
        total = long(0)
        current = long(0)
        for c in text:
            if c.isdigit():
                current *= 10
                current += long(c)
            else:
                c = c.lower()
                if c == 'w':
                    total += current * long(604800)
                elif c == 'd':
                    total += current * long(86400)
                elif c == 'h':
                    total += current * long(3600)
                elif c == 'm':
                    total += current * long(60)
                elif c == 's':
                    total += current
                else:
                    raise BadTTL("unknown unit '%s'" % c)
                current = 0
        if not current == 0:
            raise BadTTL("trailing integer")
    if total < long(0) or total > long(2147483647):
        raise BadTTL("TTL should be between 0 and 2^31 - 1 (inclusive)")
    return total
PKj�\��קqq
entropy.pynu�[���# Copyright (C) 2009, 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import os
import random
import time
from ._compat import long, binary_type
try:
    import threading as _threading
except ImportError:
    import dummy_threading as _threading


class EntropyPool(object):

    def __init__(self, seed=None):
        self.pool_index = 0
        self.digest = None
        self.next_byte = 0
        self.lock = _threading.Lock()
        try:
            import hashlib
            self.hash = hashlib.sha1()
            self.hash_len = 20
        except ImportError:
            try:
                import sha
                self.hash = sha.new()
                self.hash_len = 20
            except ImportError:
                import md5  # pylint: disable=import-error
                self.hash = md5.new()
                self.hash_len = 16
        self.pool = bytearray(b'\0' * self.hash_len)
        if seed is not None:
            self.stir(bytearray(seed))
            self.seeded = True
            self.seed_pid = os.getpid()
        else:
            self.seeded = False
            self.seed_pid = 0

    def stir(self, entropy, already_locked=False):
        if not already_locked:
            self.lock.acquire()
        try:
            for c in entropy:
                if self.pool_index == self.hash_len:
                    self.pool_index = 0
                b = c & 0xff
                self.pool[self.pool_index] ^= b
                self.pool_index += 1
        finally:
            if not already_locked:
                self.lock.release()

    def _maybe_seed(self):
        if not self.seeded or self.seed_pid != os.getpid():
            try:
                seed = os.urandom(16)
            except Exception:
                try:
                    r = open('/dev/urandom', 'rb', 0)
                    try:
                        seed = r.read(16)
                    finally:
                        r.close()
                except Exception:
                    seed = str(time.time())
            self.seeded = True
            self.seed_pid = os.getpid()
            self.digest = None
            seed = bytearray(seed)
            self.stir(seed, True)

    def random_8(self):
        self.lock.acquire()
        try:
            self._maybe_seed()
            if self.digest is None or self.next_byte == self.hash_len:
                self.hash.update(binary_type(self.pool))
                self.digest = bytearray(self.hash.digest())
                self.stir(self.digest, True)
                self.next_byte = 0
            value = self.digest[self.next_byte]
            self.next_byte += 1
        finally:
            self.lock.release()
        return value

    def random_16(self):
        return self.random_8() * 256 + self.random_8()

    def random_32(self):
        return self.random_16() * 65536 + self.random_16()

    def random_between(self, first, last):
        size = last - first + 1
        if size > long(4294967296):
            raise ValueError('too big')
        if size > 65536:
            rand = self.random_32
            max = long(4294967295)
        elif size > 256:
            rand = self.random_16
            max = 65535
        else:
            rand = self.random_8
            max = 255
        return first + size * rand() // (max + 1)

pool = EntropyPool()

try:
    system_random = random.SystemRandom()
except Exception:
    system_random = None

def random_16():
    if system_random is not None:
        return system_random.randrange(0, 65536)
    else:
        return pool.random_16()

def between(first, last):
    if system_random is not None:
        return system_random.randrange(first, last + 1)
    else:
        return pool.random_between(first, last)
PKj�\���	grange.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS GENERATE range conversion."""

import dns


def from_text(text):
    """Convert the text form of a range in a GENERATE statement to an
    integer.

    @param text: the textual range
    @type text: string
    @return: The start, stop and step values.
    @rtype: tuple
    """
    # TODO, figure out the bounds on start, stop and step.

    step = 1
    cur = ''
    state = 0
    # state   0 1 2 3 4
    #         x - y / z

    if text and text[0] == '-':
        raise dns.exception.SyntaxError("Start cannot be a negative number")

    for c in text:
        if c == '-' and state == 0:
            start = int(cur)
            cur = ''
            state = 2
        elif c == '/':
            stop = int(cur)
            cur = ''
            state = 4
        elif c.isdigit():
            cur += c
        else:
            raise dns.exception.SyntaxError("Could not parse %s" % (c))

    if state in (1, 3):
        raise dns.exception.SyntaxError()

    if state == 2:
        stop = int(cur)

    if state == 4:
        step = int(cur)

    assert step >= 1
    assert start >= 0
    assert start <= stop
    # TODO, can start == stop?

    return (start, stop, step)
PKj�\��Qy�y�
message.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Messages"""

from __future__ import absolute_import

from io import StringIO
import struct
import time

import dns.edns
import dns.exception
import dns.flags
import dns.name
import dns.opcode
import dns.entropy
import dns.rcode
import dns.rdata
import dns.rdataclass
import dns.rdatatype
import dns.rrset
import dns.renderer
import dns.tsig
import dns.wiredata

from ._compat import long, xrange, string_types


class ShortHeader(dns.exception.FormError):

    """The DNS packet passed to from_wire() is too short."""


class TrailingJunk(dns.exception.FormError):

    """The DNS packet passed to from_wire() has extra junk at the end of it."""


class UnknownHeaderField(dns.exception.DNSException):

    """The header field name was not recognized when converting from text
    into a message."""


class BadEDNS(dns.exception.FormError):

    """OPT record occurred somewhere other than the start of
    the additional data section."""


class BadTSIG(dns.exception.FormError):

    """A TSIG record occurred somewhere other than the end of
    the additional data section."""


class UnknownTSIGKey(dns.exception.DNSException):

    """A TSIG with an unknown key was received."""


class Message(object):

    """A DNS message.

    @ivar id: The query id; the default is a randomly chosen id.
    @type id: int
    @ivar flags: The DNS flags of the message.  @see: RFC 1035 for an
    explanation of these flags.
    @type flags: int
    @ivar question: The question section.
    @type question: list of dns.rrset.RRset objects
    @ivar answer: The answer section.
    @type answer: list of dns.rrset.RRset objects
    @ivar authority: The authority section.
    @type authority: list of dns.rrset.RRset objects
    @ivar additional: The additional data section.
    @type additional: list of dns.rrset.RRset objects
    @ivar edns: The EDNS level to use.  The default is -1, no Edns.
    @type edns: int
    @ivar ednsflags: The EDNS flags
    @type ednsflags: long
    @ivar payload: The EDNS payload size.  The default is 0.
    @type payload: int
    @ivar options: The EDNS options
    @type options: list of dns.edns.Option objects
    @ivar request_payload: The associated request's EDNS payload size.
    @type request_payload: int
    @ivar keyring: The TSIG keyring to use.  The default is None.
    @type keyring: dict
    @ivar keyname: The TSIG keyname to use.  The default is None.
    @type keyname: dns.name.Name object
    @ivar keyalgorithm: The TSIG algorithm to use; defaults to
    dns.tsig.default_algorithm.  Constants for TSIG algorithms are defined
    in dns.tsig, and the currently implemented algorithms are
    HMAC_MD5, HMAC_SHA1, HMAC_SHA224, HMAC_SHA256, HMAC_SHA384, and
    HMAC_SHA512.
    @type keyalgorithm: string
    @ivar request_mac: The TSIG MAC of the request message associated with
    this message; used when validating TSIG signatures.   @see: RFC 2845 for
    more information on TSIG fields.
    @type request_mac: string
    @ivar fudge: TSIG time fudge; default is 300 seconds.
    @type fudge: int
    @ivar original_id: TSIG original id; defaults to the message's id
    @type original_id: int
    @ivar tsig_error: TSIG error code; default is 0.
    @type tsig_error: int
    @ivar other_data: TSIG other data.
    @type other_data: string
    @ivar mac: The TSIG MAC for this message.
    @type mac: string
    @ivar xfr: Is the message being used to contain the results of a DNS
    zone transfer?  The default is False.
    @type xfr: bool
    @ivar origin: The origin of the zone in messages which are used for
    zone transfers or for DNS dynamic updates.  The default is None.
    @type origin: dns.name.Name object
    @ivar tsig_ctx: The TSIG signature context associated with this
    message.  The default is None.
    @type tsig_ctx: hmac.HMAC object
    @ivar had_tsig: Did the message decoded from wire format have a TSIG
    signature?
    @type had_tsig: bool
    @ivar multi: Is this message part of a multi-message sequence?  The
    default is false.  This variable is used when validating TSIG signatures
    on messages which are part of a zone transfer.
    @type multi: bool
    @ivar first: Is this message standalone, or the first of a multi
    message sequence?  This variable is used when validating TSIG signatures
    on messages which are part of a zone transfer.
    @type first: bool
    @ivar index: An index of rrsets in the message.  The index key is
    (section, name, rdclass, rdtype, covers, deleting).  Indexing can be
    disabled by setting the index to None.
    @type index: dict
    """

    def __init__(self, id=None):
        if id is None:
            self.id = dns.entropy.random_16()
        else:
            self.id = id
        self.flags = 0
        self.question = []
        self.answer = []
        self.authority = []
        self.additional = []
        self.edns = -1
        self.ednsflags = 0
        self.payload = 0
        self.options = []
        self.request_payload = 0
        self.keyring = None
        self.keyname = None
        self.keyalgorithm = dns.tsig.default_algorithm
        self.request_mac = ''
        self.other_data = ''
        self.tsig_error = 0
        self.fudge = 300
        self.original_id = self.id
        self.mac = ''
        self.xfr = False
        self.origin = None
        self.tsig_ctx = None
        self.had_tsig = False
        self.multi = False
        self.first = True
        self.index = {}

    def __repr__(self):
        return '<DNS message, ID ' + repr(self.id) + '>'

    def __str__(self):
        return self.to_text()

    def to_text(self, origin=None, relativize=True, **kw):
        """Convert the message to text.

        The I{origin}, I{relativize}, and any other keyword
        arguments are passed to the rrset to_wire() method.

        @rtype: string
        """

        s = StringIO()
        s.write(u'id %d\n' % self.id)
        s.write(u'opcode %s\n' %
                dns.opcode.to_text(dns.opcode.from_flags(self.flags)))
        rc = dns.rcode.from_flags(self.flags, self.ednsflags)
        s.write(u'rcode %s\n' % dns.rcode.to_text(rc))
        s.write(u'flags %s\n' % dns.flags.to_text(self.flags))
        if self.edns >= 0:
            s.write(u'edns %s\n' % self.edns)
            if self.ednsflags != 0:
                s.write(u'eflags %s\n' %
                        dns.flags.edns_to_text(self.ednsflags))
            s.write(u'payload %d\n' % self.payload)
        is_update = dns.opcode.is_update(self.flags)
        if is_update:
            s.write(u';ZONE\n')
        else:
            s.write(u';QUESTION\n')
        for rrset in self.question:
            s.write(rrset.to_text(origin, relativize, **kw))
            s.write(u'\n')
        if is_update:
            s.write(u';PREREQ\n')
        else:
            s.write(u';ANSWER\n')
        for rrset in self.answer:
            s.write(rrset.to_text(origin, relativize, **kw))
            s.write(u'\n')
        if is_update:
            s.write(u';UPDATE\n')
        else:
            s.write(u';AUTHORITY\n')
        for rrset in self.authority:
            s.write(rrset.to_text(origin, relativize, **kw))
            s.write(u'\n')
        s.write(u';ADDITIONAL\n')
        for rrset in self.additional:
            s.write(rrset.to_text(origin, relativize, **kw))
            s.write(u'\n')
        #
        # We strip off the final \n so the caller can print the result without
        # doing weird things to get around eccentricities in Python print
        # formatting
        #
        return s.getvalue()[:-1]

    def __eq__(self, other):
        """Two messages are equal if they have the same content in the
        header, question, answer, and authority sections.
        @rtype: bool"""
        if not isinstance(other, Message):
            return False
        if self.id != other.id:
            return False
        if self.flags != other.flags:
            return False
        for n in self.question:
            if n not in other.question:
                return False
        for n in other.question:
            if n not in self.question:
                return False
        for n in self.answer:
            if n not in other.answer:
                return False
        for n in other.answer:
            if n not in self.answer:
                return False
        for n in self.authority:
            if n not in other.authority:
                return False
        for n in other.authority:
            if n not in self.authority:
                return False
        return True

    def __ne__(self, other):
        """Are two messages not equal?
        @rtype: bool"""
        return not self.__eq__(other)

    def is_response(self, other):
        """Is other a response to self?
        @rtype: bool"""
        if other.flags & dns.flags.QR == 0 or \
           self.id != other.id or \
           dns.opcode.from_flags(self.flags) != \
           dns.opcode.from_flags(other.flags):
            return False
        if dns.rcode.from_flags(other.flags, other.ednsflags) != \
                dns.rcode.NOERROR:
            return True
        if dns.opcode.is_update(self.flags):
            return True
        for n in self.question:
            if n not in other.question:
                return False
        for n in other.question:
            if n not in self.question:
                return False
        return True

    def section_number(self, section):
        if section is self.question:
            return 0
        elif section is self.answer:
            return 1
        elif section is self.authority:
            return 2
        elif section is self.additional:
            return 3
        else:
            raise ValueError('unknown section')

    def find_rrset(self, section, name, rdclass, rdtype,
                   covers=dns.rdatatype.NONE, deleting=None, create=False,
                   force_unique=False):
        """Find the RRset with the given attributes in the specified section.

        @param section: the section of the message to look in, e.g.
        self.answer.
        @type section: list of dns.rrset.RRset objects
        @param name: the name of the RRset
        @type name: dns.name.Name object
        @param rdclass: the class of the RRset
        @type rdclass: int
        @param rdtype: the type of the RRset
        @type rdtype: int
        @param covers: the covers value of the RRset
        @type covers: int
        @param deleting: the deleting value of the RRset
        @type deleting: int
        @param create: If True, create the RRset if it is not found.
        The created RRset is appended to I{section}.
        @type create: bool
        @param force_unique: If True and create is also True, create a
        new RRset regardless of whether a matching RRset exists already.
        @type force_unique: bool
        @raises KeyError: the RRset was not found and create was False
        @rtype: dns.rrset.RRset object"""

        key = (self.section_number(section),
               name, rdclass, rdtype, covers, deleting)
        if not force_unique:
            if self.index is not None:
                rrset = self.index.get(key)
                if rrset is not None:
                    return rrset
            else:
                for rrset in section:
                    if rrset.match(name, rdclass, rdtype, covers, deleting):
                        return rrset
        if not create:
            raise KeyError
        rrset = dns.rrset.RRset(name, rdclass, rdtype, covers, deleting)
        section.append(rrset)
        if self.index is not None:
            self.index[key] = rrset
        return rrset

    def get_rrset(self, section, name, rdclass, rdtype,
                  covers=dns.rdatatype.NONE, deleting=None, create=False,
                  force_unique=False):
        """Get the RRset with the given attributes in the specified section.

        If the RRset is not found, None is returned.

        @param section: the section of the message to look in, e.g.
        self.answer.
        @type section: list of dns.rrset.RRset objects
        @param name: the name of the RRset
        @type name: dns.name.Name object
        @param rdclass: the class of the RRset
        @type rdclass: int
        @param rdtype: the type of the RRset
        @type rdtype: int
        @param covers: the covers value of the RRset
        @type covers: int
        @param deleting: the deleting value of the RRset
        @type deleting: int
        @param create: If True, create the RRset if it is not found.
        The created RRset is appended to I{section}.
        @type create: bool
        @param force_unique: If True and create is also True, create a
        new RRset regardless of whether a matching RRset exists already.
        @type force_unique: bool
        @rtype: dns.rrset.RRset object or None"""

        try:
            rrset = self.find_rrset(section, name, rdclass, rdtype, covers,
                                    deleting, create, force_unique)
        except KeyError:
            rrset = None
        return rrset

    def to_wire(self, origin=None, max_size=0, **kw):
        """Return a string containing the message in DNS compressed wire
        format.

        Additional keyword arguments are passed to the rrset to_wire()
        method.

        @param origin: The origin to be appended to any relative names.
        @type origin: dns.name.Name object
        @param max_size: The maximum size of the wire format output; default
        is 0, which means 'the message's request payload, if nonzero, or
        65536'.
        @type max_size: int
        @raises dns.exception.TooBig: max_size was exceeded
        @rtype: string
        """

        if max_size == 0:
            if self.request_payload != 0:
                max_size = self.request_payload
            else:
                max_size = 65535
        if max_size < 512:
            max_size = 512
        elif max_size > 65535:
            max_size = 65535
        r = dns.renderer.Renderer(self.id, self.flags, max_size, origin)
        for rrset in self.question:
            r.add_question(rrset.name, rrset.rdtype, rrset.rdclass)
        for rrset in self.answer:
            r.add_rrset(dns.renderer.ANSWER, rrset, **kw)
        for rrset in self.authority:
            r.add_rrset(dns.renderer.AUTHORITY, rrset, **kw)
        if self.edns >= 0:
            r.add_edns(self.edns, self.ednsflags, self.payload, self.options)
        for rrset in self.additional:
            r.add_rrset(dns.renderer.ADDITIONAL, rrset, **kw)
        r.write_header()
        if self.keyname is not None:
            r.add_tsig(self.keyname, self.keyring[self.keyname],
                       self.fudge, self.original_id, self.tsig_error,
                       self.other_data, self.request_mac,
                       self.keyalgorithm)
            self.mac = r.mac
        return r.get_wire()

    def use_tsig(self, keyring, keyname=None, fudge=300,
                 original_id=None, tsig_error=0, other_data='',
                 algorithm=dns.tsig.default_algorithm):
        """When sending, a TSIG signature using the specified keyring
        and keyname should be added.

        @param keyring: The TSIG keyring to use; defaults to None.
        @type keyring: dict
        @param keyname: The name of the TSIG key to use; defaults to None.
        The key must be defined in the keyring.  If a keyring is specified
        but a keyname is not, then the key used will be the first key in the
        keyring.  Note that the order of keys in a dictionary is not defined,
        so applications should supply a keyname when a keyring is used, unless
        they know the keyring contains only one key.
        @type keyname: dns.name.Name or string
        @param fudge: TSIG time fudge; default is 300 seconds.
        @type fudge: int
        @param original_id: TSIG original id; defaults to the message's id
        @type original_id: int
        @param tsig_error: TSIG error code; default is 0.
        @type tsig_error: int
        @param other_data: TSIG other data.
        @type other_data: string
        @param algorithm: The TSIG algorithm to use; defaults to
        dns.tsig.default_algorithm
        """

        self.keyring = keyring
        if keyname is None:
            self.keyname = list(self.keyring.keys())[0]
        else:
            if isinstance(keyname, string_types):
                keyname = dns.name.from_text(keyname)
            self.keyname = keyname
        self.keyalgorithm = algorithm
        self.fudge = fudge
        if original_id is None:
            self.original_id = self.id
        else:
            self.original_id = original_id
        self.tsig_error = tsig_error
        self.other_data = other_data

    def use_edns(self, edns=0, ednsflags=0, payload=1280, request_payload=None,
                 options=None):
        """Configure EDNS behavior.
        @param edns: The EDNS level to use.  Specifying None, False, or -1
        means 'do not use EDNS', and in this case the other parameters are
        ignored.  Specifying True is equivalent to specifying 0, i.e. 'use
        EDNS0'.
        @type edns: int or bool or None
        @param ednsflags: EDNS flag values.
        @type ednsflags: int
        @param payload: The EDNS sender's payload field, which is the maximum
        size of UDP datagram the sender can handle.
        @type payload: int
        @param request_payload: The EDNS payload size to use when sending
        this message.  If not specified, defaults to the value of payload.
        @type request_payload: int or None
        @param options: The EDNS options
        @type options: None or list of dns.edns.Option objects
        @see: RFC 2671
        """
        if edns is None or edns is False:
            edns = -1
        if edns is True:
            edns = 0
        if request_payload is None:
            request_payload = payload
        if edns < 0:
            ednsflags = 0
            payload = 0
            request_payload = 0
            options = []
        else:
            # make sure the EDNS version in ednsflags agrees with edns
            ednsflags &= long(0xFF00FFFF)
            ednsflags |= (edns << 16)
            if options is None:
                options = []
        self.edns = edns
        self.ednsflags = ednsflags
        self.payload = payload
        self.options = options
        self.request_payload = request_payload

    def want_dnssec(self, wanted=True):
        """Enable or disable 'DNSSEC desired' flag in requests.
        @param wanted: Is DNSSEC desired?  If True, EDNS is enabled if
        required, and then the DO bit is set.  If False, the DO bit is
        cleared if EDNS is enabled.
        @type wanted: bool
        """
        if wanted:
            if self.edns < 0:
                self.use_edns()
            self.ednsflags |= dns.flags.DO
        elif self.edns >= 0:
            self.ednsflags &= ~dns.flags.DO

    def rcode(self):
        """Return the rcode.
        @rtype: int
        """
        return dns.rcode.from_flags(self.flags, self.ednsflags)

    def set_rcode(self, rcode):
        """Set the rcode.
        @param rcode: the rcode
        @type rcode: int
        """
        (value, evalue) = dns.rcode.to_flags(rcode)
        self.flags &= 0xFFF0
        self.flags |= value
        self.ednsflags &= long(0x00FFFFFF)
        self.ednsflags |= evalue
        if self.ednsflags != 0 and self.edns < 0:
            self.edns = 0

    def opcode(self):
        """Return the opcode.
        @rtype: int
        """
        return dns.opcode.from_flags(self.flags)

    def set_opcode(self, opcode):
        """Set the opcode.
        @param opcode: the opcode
        @type opcode: int
        """
        self.flags &= 0x87FF
        self.flags |= dns.opcode.to_flags(opcode)


class _WireReader(object):

    """Wire format reader.

    @ivar wire: the wire-format message.
    @type wire: string
    @ivar message: The message object being built
    @type message: dns.message.Message object
    @ivar current: When building a message object from wire format, this
    variable contains the offset from the beginning of wire of the next octet
    to be read.
    @type current: int
    @ivar updating: Is the message a dynamic update?
    @type updating: bool
    @ivar one_rr_per_rrset: Put each RR into its own RRset?
    @type one_rr_per_rrset: bool
    @ivar ignore_trailing: Ignore trailing junk at end of request?
    @type ignore_trailing: bool
    @ivar zone_rdclass: The class of the zone in messages which are
    DNS dynamic updates.
    @type zone_rdclass: int
    """

    def __init__(self, wire, message, question_only=False,
                 one_rr_per_rrset=False, ignore_trailing=False):
        self.wire = dns.wiredata.maybe_wrap(wire)
        self.message = message
        self.current = 0
        self.updating = False
        self.zone_rdclass = dns.rdataclass.IN
        self.question_only = question_only
        self.one_rr_per_rrset = one_rr_per_rrset
        self.ignore_trailing = ignore_trailing

    def _get_question(self, qcount):
        """Read the next I{qcount} records from the wire data and add them to
        the question section.
        @param qcount: the number of questions in the message
        @type qcount: int"""

        if self.updating and qcount > 1:
            raise dns.exception.FormError

        for i in xrange(0, qcount):
            (qname, used) = dns.name.from_wire(self.wire, self.current)
            if self.message.origin is not None:
                qname = qname.relativize(self.message.origin)
            self.current = self.current + used
            (rdtype, rdclass) = \
                struct.unpack('!HH',
                              self.wire[self.current:self.current + 4])
            self.current = self.current + 4
            self.message.find_rrset(self.message.question, qname,
                                    rdclass, rdtype, create=True,
                                    force_unique=True)
            if self.updating:
                self.zone_rdclass = rdclass

    def _get_section(self, section, count):
        """Read the next I{count} records from the wire data and add them to
        the specified section.
        @param section: the section of the message to which to add records
        @type section: list of dns.rrset.RRset objects
        @param count: the number of records to read
        @type count: int"""

        if self.updating or self.one_rr_per_rrset:
            force_unique = True
        else:
            force_unique = False
        seen_opt = False
        for i in xrange(0, count):
            rr_start = self.current
            (name, used) = dns.name.from_wire(self.wire, self.current)
            absolute_name = name
            if self.message.origin is not None:
                name = name.relativize(self.message.origin)
            self.current = self.current + used
            (rdtype, rdclass, ttl, rdlen) = \
                struct.unpack('!HHIH',
                              self.wire[self.current:self.current + 10])
            self.current = self.current + 10
            if rdtype == dns.rdatatype.OPT:
                if section is not self.message.additional or seen_opt:
                    raise BadEDNS
                self.message.payload = rdclass
                self.message.ednsflags = ttl
                self.message.edns = (ttl & 0xff0000) >> 16
                self.message.options = []
                current = self.current
                optslen = rdlen
                while optslen > 0:
                    (otype, olen) = \
                        struct.unpack('!HH',
                                      self.wire[current:current + 4])
                    current = current + 4
                    opt = dns.edns.option_from_wire(
                        otype, self.wire, current, olen)
                    self.message.options.append(opt)
                    current = current + olen
                    optslen = optslen - 4 - olen
                seen_opt = True
            elif rdtype == dns.rdatatype.TSIG:
                if not (section is self.message.additional and
                        i == (count - 1)):
                    raise BadTSIG
                if self.message.keyring is None:
                    raise UnknownTSIGKey('got signed message without keyring')
                secret = self.message.keyring.get(absolute_name)
                if secret is None:
                    raise UnknownTSIGKey("key '%s' unknown" % name)
                self.message.keyname = absolute_name
                (self.message.keyalgorithm, self.message.mac) = \
                    dns.tsig.get_algorithm_and_mac(self.wire, self.current,
                                                   rdlen)
                self.message.tsig_ctx = \
                    dns.tsig.validate(self.wire,
                                      absolute_name,
                                      secret,
                                      int(time.time()),
                                      self.message.request_mac,
                                      rr_start,
                                      self.current,
                                      rdlen,
                                      self.message.tsig_ctx,
                                      self.message.multi,
                                      self.message.first)
                self.message.had_tsig = True
            else:
                if ttl < 0:
                    ttl = 0
                if self.updating and \
                   (rdclass == dns.rdataclass.ANY or
                        rdclass == dns.rdataclass.NONE):
                    deleting = rdclass
                    rdclass = self.zone_rdclass
                else:
                    deleting = None
                if deleting == dns.rdataclass.ANY or \
                   (deleting == dns.rdataclass.NONE and
                        section is self.message.answer):
                    covers = dns.rdatatype.NONE
                    rd = None
                else:
                    rd = dns.rdata.from_wire(rdclass, rdtype, self.wire,
                                             self.current, rdlen,
                                             self.message.origin)
                    covers = rd.covers()
                if self.message.xfr and rdtype == dns.rdatatype.SOA:
                    force_unique = True
                rrset = self.message.find_rrset(section, name,
                                                rdclass, rdtype, covers,
                                                deleting, True, force_unique)
                if rd is not None:
                    rrset.add(rd, ttl)
            self.current = self.current + rdlen

    def read(self):
        """Read a wire format DNS message and build a dns.message.Message
        object."""

        l = len(self.wire)
        if l < 12:
            raise ShortHeader
        (self.message.id, self.message.flags, qcount, ancount,
         aucount, adcount) = struct.unpack('!HHHHHH', self.wire[:12])
        self.current = 12
        if dns.opcode.is_update(self.message.flags):
            self.updating = True
        self._get_question(qcount)
        if self.question_only:
            return
        self._get_section(self.message.answer, ancount)
        self._get_section(self.message.authority, aucount)
        self._get_section(self.message.additional, adcount)
        if not self.ignore_trailing and self.current != l:
            raise TrailingJunk
        if self.message.multi and self.message.tsig_ctx and \
                not self.message.had_tsig:
            self.message.tsig_ctx.update(self.wire)


def from_wire(wire, keyring=None, request_mac='', xfr=False, origin=None,
              tsig_ctx=None, multi=False, first=True,
              question_only=False, one_rr_per_rrset=False,
              ignore_trailing=False):
    """Convert a DNS wire format message into a message
    object.

    @param keyring: The keyring to use if the message is signed.
    @type keyring: dict
    @param request_mac: If the message is a response to a TSIG-signed request,
    I{request_mac} should be set to the MAC of that request.
    @type request_mac: string
    @param xfr: Is this message part of a zone transfer?
    @type xfr: bool
    @param origin: If the message is part of a zone transfer, I{origin}
    should be the origin name of the zone.
    @type origin: dns.name.Name object
    @param tsig_ctx: The ongoing TSIG context, used when validating zone
    transfers.
    @type tsig_ctx: hmac.HMAC object
    @param multi: Is this message part of a multiple message sequence?
    @type multi: bool
    @param first: Is this message standalone, or the first of a multi
    message sequence?
    @type first: bool
    @param question_only: Read only up to the end of the question section?
    @type question_only: bool
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    @param ignore_trailing: Ignore trailing junk at end of request?
    @type ignore_trailing: bool
    @raises ShortHeader: The message is less than 12 octets long.
    @raises TrailingJunk: There were octets in the message past the end
    of the proper DNS message.
    @raises BadEDNS: An OPT record was in the wrong section, or occurred more
    than once.
    @raises BadTSIG: A TSIG record was not the last record of the additional
    data section.
    @rtype: dns.message.Message object"""

    m = Message(id=0)
    m.keyring = keyring
    m.request_mac = request_mac
    m.xfr = xfr
    m.origin = origin
    m.tsig_ctx = tsig_ctx
    m.multi = multi
    m.first = first

    reader = _WireReader(wire, m, question_only, one_rr_per_rrset,
                         ignore_trailing)
    reader.read()

    return m


class _TextReader(object):

    """Text format reader.

    @ivar tok: the tokenizer
    @type tok: dns.tokenizer.Tokenizer object
    @ivar message: The message object being built
    @type message: dns.message.Message object
    @ivar updating: Is the message a dynamic update?
    @type updating: bool
    @ivar zone_rdclass: The class of the zone in messages which are
    DNS dynamic updates.
    @type zone_rdclass: int
    @ivar last_name: The most recently read name when building a message object
    from text format.
    @type last_name: dns.name.Name object
    """

    def __init__(self, text, message):
        self.message = message
        self.tok = dns.tokenizer.Tokenizer(text)
        self.last_name = None
        self.zone_rdclass = dns.rdataclass.IN
        self.updating = False

    def _header_line(self, section):
        """Process one line from the text format header section."""

        token = self.tok.get()
        what = token.value
        if what == 'id':
            self.message.id = self.tok.get_int()
        elif what == 'flags':
            while True:
                token = self.tok.get()
                if not token.is_identifier():
                    self.tok.unget(token)
                    break
                self.message.flags = self.message.flags | \
                    dns.flags.from_text(token.value)
            if dns.opcode.is_update(self.message.flags):
                self.updating = True
        elif what == 'edns':
            self.message.edns = self.tok.get_int()
            self.message.ednsflags = self.message.ednsflags | \
                (self.message.edns << 16)
        elif what == 'eflags':
            if self.message.edns < 0:
                self.message.edns = 0
            while True:
                token = self.tok.get()
                if not token.is_identifier():
                    self.tok.unget(token)
                    break
                self.message.ednsflags = self.message.ednsflags | \
                    dns.flags.edns_from_text(token.value)
        elif what == 'payload':
            self.message.payload = self.tok.get_int()
            if self.message.edns < 0:
                self.message.edns = 0
        elif what == 'opcode':
            text = self.tok.get_string()
            self.message.flags = self.message.flags | \
                dns.opcode.to_flags(dns.opcode.from_text(text))
        elif what == 'rcode':
            text = self.tok.get_string()
            self.message.set_rcode(dns.rcode.from_text(text))
        else:
            raise UnknownHeaderField
        self.tok.get_eol()

    def _question_line(self, section):
        """Process one line from the text format question section."""

        token = self.tok.get(want_leading=True)
        if not token.is_whitespace():
            self.last_name = dns.name.from_text(token.value, None)
        name = self.last_name
        token = self.tok.get()
        if not token.is_identifier():
            raise dns.exception.SyntaxError
        # Class
        try:
            rdclass = dns.rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            rdclass = dns.rdataclass.IN
        # Type
        rdtype = dns.rdatatype.from_text(token.value)
        self.message.find_rrset(self.message.question, name,
                                rdclass, rdtype, create=True,
                                force_unique=True)
        if self.updating:
            self.zone_rdclass = rdclass
        self.tok.get_eol()

    def _rr_line(self, section):
        """Process one line from the text format answer, authority, or
        additional data sections.
        """

        deleting = None
        # Name
        token = self.tok.get(want_leading=True)
        if not token.is_whitespace():
            self.last_name = dns.name.from_text(token.value, None)
        name = self.last_name
        token = self.tok.get()
        if not token.is_identifier():
            raise dns.exception.SyntaxError
        # TTL
        try:
            ttl = int(token.value, 0)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            ttl = 0
        # Class
        try:
            rdclass = dns.rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
            if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
                deleting = rdclass
                rdclass = self.zone_rdclass
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            rdclass = dns.rdataclass.IN
        # Type
        rdtype = dns.rdatatype.from_text(token.value)
        token = self.tok.get()
        if not token.is_eol_or_eof():
            self.tok.unget(token)
            rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
            covers = rd.covers()
        else:
            rd = None
            covers = dns.rdatatype.NONE
        rrset = self.message.find_rrset(section, name,
                                        rdclass, rdtype, covers,
                                        deleting, True, self.updating)
        if rd is not None:
            rrset.add(rd, ttl)

    def read(self):
        """Read a text format DNS message and build a dns.message.Message
        object."""

        line_method = self._header_line
        section = None
        while 1:
            token = self.tok.get(True, True)
            if token.is_eol_or_eof():
                break
            if token.is_comment():
                u = token.value.upper()
                if u == 'HEADER':
                    line_method = self._header_line
                elif u == 'QUESTION' or u == 'ZONE':
                    line_method = self._question_line
                    section = self.message.question
                elif u == 'ANSWER' or u == 'PREREQ':
                    line_method = self._rr_line
                    section = self.message.answer
                elif u == 'AUTHORITY' or u == 'UPDATE':
                    line_method = self._rr_line
                    section = self.message.authority
                elif u == 'ADDITIONAL':
                    line_method = self._rr_line
                    section = self.message.additional
                self.tok.get_eol()
                continue
            self.tok.unget(token)
            line_method(section)


def from_text(text):
    """Convert the text format message into a message object.

    @param text: The text format message.
    @type text: string
    @raises UnknownHeaderField:
    @raises dns.exception.SyntaxError:
    @rtype: dns.message.Message object"""

    # 'text' can also be a file, but we don't publish that fact
    # since it's an implementation detail.  The official file
    # interface is from_file().

    m = Message()

    reader = _TextReader(text, m)
    reader.read()

    return m


def from_file(f):
    """Read the next text format message from the specified file.

    @param f: file or string.  If I{f} is a string, it is treated
    as the name of a file to open.
    @raises UnknownHeaderField:
    @raises dns.exception.SyntaxError:
    @rtype: dns.message.Message object"""

    str_type = string_types
    opts = 'rU'

    if isinstance(f, str_type):
        f = open(f, opts)
        want_close = True
    else:
        want_close = False

    try:
        m = from_text(f)
    finally:
        if want_close:
            f.close()
    return m


def make_query(qname, rdtype, rdclass=dns.rdataclass.IN, use_edns=None,
               want_dnssec=False, ednsflags=None, payload=None,
               request_payload=None, options=None):
    """Make a query message.

    The query name, type, and class may all be specified either
    as objects of the appropriate type, or as strings.

    The query will have a randomly chosen query id, and its DNS flags
    will be set to dns.flags.RD.

    @param qname: The query name.
    @type qname: dns.name.Name object or string
    @param rdtype: The desired rdata type.
    @type rdtype: int
    @param rdclass: The desired rdata class; the default is class IN.
    @type rdclass: int
    @param use_edns: The EDNS level to use; the default is None (no EDNS).
    See the description of dns.message.Message.use_edns() for the possible
    values for use_edns and their meanings.
    @type use_edns: int or bool or None
    @param want_dnssec: Should the query indicate that DNSSEC is desired?
    @type want_dnssec: bool
    @param ednsflags: EDNS flag values.
    @type ednsflags: int
    @param payload: The EDNS sender's payload field, which is the maximum
    size of UDP datagram the sender can handle.
    @type payload: int
    @param request_payload: The EDNS payload size to use when sending
    this message.  If not specified, defaults to the value of payload.
    @type request_payload: int or None
    @param options: The EDNS options
    @type options: None or list of dns.edns.Option objects
    @see: RFC 2671
    @rtype: dns.message.Message object"""

    if isinstance(qname, string_types):
        qname = dns.name.from_text(qname)
    if isinstance(rdtype, string_types):
        rdtype = dns.rdatatype.from_text(rdtype)
    if isinstance(rdclass, string_types):
        rdclass = dns.rdataclass.from_text(rdclass)
    m = Message()
    m.flags |= dns.flags.RD
    m.find_rrset(m.question, qname, rdclass, rdtype, create=True,
                 force_unique=True)
    # only pass keywords on to use_edns if they have been set to a
    # non-None value.  Setting a field will turn EDNS on if it hasn't
    # been configured.
    kwargs = {}
    if ednsflags is not None:
        kwargs['ednsflags'] = ednsflags
        if use_edns is None:
            use_edns = 0
    if payload is not None:
        kwargs['payload'] = payload
        if use_edns is None:
            use_edns = 0
    if request_payload is not None:
        kwargs['request_payload'] = request_payload
        if use_edns is None:
            use_edns = 0
    if options is not None:
        kwargs['options'] = options
        if use_edns is None:
            use_edns = 0
    kwargs['edns'] = use_edns
    m.use_edns(**kwargs)
    m.want_dnssec(want_dnssec)
    return m


def make_response(query, recursion_available=False, our_payload=8192,
                  fudge=300):
    """Make a message which is a response for the specified query.
    The message returned is really a response skeleton; it has all
    of the infrastructure required of a response, but none of the
    content.

    The response's question section is a shallow copy of the query's
    question section, so the query's question RRsets should not be
    changed.

    @param query: the query to respond to
    @type query: dns.message.Message object
    @param recursion_available: should RA be set in the response?
    @type recursion_available: bool
    @param our_payload: payload size to advertise in EDNS responses; default
    is 8192.
    @type our_payload: int
    @param fudge: TSIG time fudge; default is 300 seconds.
    @type fudge: int
    @rtype: dns.message.Message object"""

    if query.flags & dns.flags.QR:
        raise dns.exception.FormError('specified query message is not a query')
    response = dns.message.Message(query.id)
    response.flags = dns.flags.QR | (query.flags & dns.flags.RD)
    if recursion_available:
        response.flags |= dns.flags.RA
    response.set_opcode(query.opcode())
    response.question = list(query.question)
    if query.edns >= 0:
        response.use_edns(0, 0, our_payload, query.payload)
    if query.had_tsig:
        response.use_tsig(query.keyring, query.keyname, fudge, None, 0, '',
                          query.keyalgorithm)
        response.request_mac = query.mac
    return response
PKk�\��EGexception.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Common DNS Exceptions."""


class DNSException(Exception):

    """Abstract base class shared by all dnspython exceptions.

    It supports two basic modes of operation:

    a) Old/compatible mode is used if __init__ was called with
    empty **kwargs.
    In compatible mode all *args are passed to standard Python Exception class
    as before and all *args are printed by standard __str__ implementation.
    Class variable msg (or doc string if msg is None) is returned from str()
    if *args is empty.

    b) New/parametrized mode is used if __init__ was called with
    non-empty **kwargs.
    In the new mode *args has to be empty and all kwargs has to exactly match
    set in class variable self.supp_kwargs. All kwargs are stored inside
    self.kwargs and used in new __str__ implementation to construct
    formatted message based on self.fmt string.

    In the simplest case it is enough to override supp_kwargs and fmt
    class variables to get nice parametrized messages.
    """
    msg = None  # non-parametrized message
    supp_kwargs = set()  # accepted parameters for _fmt_kwargs (sanity check)
    fmt = None  # message parametrized with results from _fmt_kwargs

    def __init__(self, *args, **kwargs):
        self._check_params(*args, **kwargs)
        if kwargs:
            self.kwargs = self._check_kwargs(**kwargs)
            self.msg = str(self)
        else:
            self.kwargs = dict()  # defined but empty for old mode exceptions
        if self.msg is None:
            # doc string is better implicit message than empty string
            self.msg = self.__doc__
        if args:
            super(DNSException, self).__init__(*args)
        else:
            super(DNSException, self).__init__(self.msg)

    def _check_params(self, *args, **kwargs):
        """Old exceptions supported only args and not kwargs.

        For sanity we do not allow to mix old and new behavior."""
        if args or kwargs:
            assert bool(args) != bool(kwargs), \
                'keyword arguments are mutually exclusive with positional args'

    def _check_kwargs(self, **kwargs):
        if kwargs:
            assert set(kwargs.keys()) == self.supp_kwargs, \
                'following set of keyword args is required: %s' % (
                    self.supp_kwargs)
        return kwargs

    def _fmt_kwargs(self, **kwargs):
        """Format kwargs before printing them.

        Resulting dictionary has to have keys necessary for str.format call
        on fmt class variable.
        """
        fmtargs = {}
        for kw, data in kwargs.items():
            if isinstance(data, (list, set)):
                # convert list of <someobj> to list of str(<someobj>)
                fmtargs[kw] = list(map(str, data))
                if len(fmtargs[kw]) == 1:
                    # remove list brackets [] from single-item lists
                    fmtargs[kw] = fmtargs[kw].pop()
            else:
                fmtargs[kw] = data
        return fmtargs

    def __str__(self):
        if self.kwargs and self.fmt:
            # provide custom message constructed from keyword arguments
            fmtargs = self._fmt_kwargs(**self.kwargs)
            return self.fmt.format(**fmtargs)
        else:
            # print *args directly in the same way as old DNSException
            return super(DNSException, self).__str__()


class FormError(DNSException):

    """DNS message is malformed."""


class SyntaxError(DNSException):

    """Text input is malformed."""


class UnexpectedEnd(SyntaxError):

    """Text input ended unexpectedly."""


class TooBig(DNSException):

    """The DNS message is too big."""


class Timeout(DNSException):

    """The DNS operation timed out."""
    supp_kwargs = set(['timeout'])
    fmt = "The DNS operation timed out after {timeout} seconds"
PKk�\��V��ipv6.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""IPv6 helper functions."""

import re
import binascii

import dns.exception
import dns.ipv4
from ._compat import xrange, binary_type, maybe_decode

_leading_zero = re.compile(b'0+([0-9a-f]+)')

def inet_ntoa(address):
    """Convert a network format IPv6 address into text.

    @param address: the binary address
    @type address: string
    @rtype: string
    @raises ValueError: the address isn't 16 bytes long
    """

    if len(address) != 16:
        raise ValueError("IPv6 addresses are 16 bytes long")
    hex = binascii.hexlify(address)
    chunks = []
    i = 0
    l = len(hex)
    while i < l:
        chunk = hex[i : i + 4]
        # strip leading zeros.  we do this with an re instead of
        # with lstrip() because lstrip() didn't support chars until
        # python 2.2.2
        m = _leading_zero.match(chunk)
        if not m is None:
            chunk = m.group(1)
        chunks.append(chunk)
        i += 4
    #
    # Compress the longest subsequence of 0-value chunks to ::
    #
    best_start = 0
    best_len = 0
    start = -1
    last_was_zero = False
    for i in xrange(8):
        if chunks[i] != b'0':
            if last_was_zero:
                end = i
                current_len = end - start
                if current_len > best_len:
                    best_start = start
                    best_len = current_len
                last_was_zero = False
        elif not last_was_zero:
            start = i
            last_was_zero = True
    if last_was_zero:
        end = 8
        current_len = end - start
        if current_len > best_len:
            best_start = start
            best_len = current_len
    if best_len > 1:
        if best_start == 0 and \
           (best_len == 6 or
            best_len == 5 and chunks[5] == b'ffff'):
            # We have an embedded IPv4 address
            if best_len == 6:
                prefix = b'::'
            else:
                prefix = b'::ffff:'
            hex = prefix + dns.ipv4.inet_ntoa(address[12:])
        else:
            hex = b':'.join(chunks[:best_start]) + b'::' + \
                  b':'.join(chunks[best_start + best_len:])
    else:
        hex = b':'.join(chunks)
    return maybe_decode(hex)

_v4_ending = re.compile(b'(.*):(\d+\.\d+\.\d+\.\d+)$')
_colon_colon_start = re.compile(b'::.*')
_colon_colon_end = re.compile(b'.*::$')

def inet_aton(text):
    """Convert a text format IPv6 address into network format.

    @param text: the textual address
    @type text: string
    @rtype: string
    @raises dns.exception.SyntaxError: the text was not properly formatted
    """

    #
    # Our aim here is not something fast; we just want something that works.
    #
    if not isinstance(text, binary_type):
        text = text.encode()

    if text == b'::':
        text = b'0::'
    #
    # Get rid of the icky dot-quad syntax if we have it.
    #
    m = _v4_ending.match(text)
    if not m is None:
        b = bytearray(dns.ipv4.inet_aton(m.group(2)))
        text = (u"%s:%02x%02x:%02x%02x" % (m.group(1).decode(), b[0], b[1],
                                           b[2], b[3])).encode()
    #
    # Try to turn '::<whatever>' into ':<whatever>'; if no match try to
    # turn '<whatever>::' into '<whatever>:'
    #
    m = _colon_colon_start.match(text)
    if not m is None:
        text = text[1:]
    else:
        m = _colon_colon_end.match(text)
        if not m is None:
            text = text[:-1]
    #
    # Now canonicalize into 8 chunks of 4 hex digits each
    #
    chunks = text.split(b':')
    l = len(chunks)
    if l > 8:
        raise dns.exception.SyntaxError
    seen_empty = False
    canonical = []
    for c in chunks:
        if c == b'':
            if seen_empty:
                raise dns.exception.SyntaxError
            seen_empty = True
            for i in xrange(0, 8 - l + 1):
                canonical.append(b'0000')
        else:
            lc = len(c)
            if lc > 4:
                raise dns.exception.SyntaxError
            if lc != 4:
                c = (b'0' * (4 - lc)) + c
            canonical.append(c)
    if l < 8 and not seen_empty:
        raise dns.exception.SyntaxError
    text = b''.join(canonical)

    #
    # Finally we can go to binary.
    #
    try:
        return binascii.unhexlify(text)
    except (binascii.Error, TypeError):
        raise dns.exception.SyntaxError

_mapped_prefix = b'\x00' * 10 + b'\xff\xff'

def is_mapped(address):
    return address.startswith(_mapped_prefix)
PKk�\4V�f��
version.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""dnspython release version information."""

MAJOR = 1
MINOR = 15
MICRO = 0
RELEASELEVEL = 0x0f
SERIAL = 0

if RELEASELEVEL == 0x0f:
    version = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
elif RELEASELEVEL == 0x00:
    version = '%d.%d.%dx%d' % \
              (MAJOR, MINOR, MICRO, SERIAL)
else:
    version = '%d.%d.%d%x%d' % \
              (MAJOR, MINOR, MICRO, RELEASELEVEL, SERIAL)

hexversion = MAJOR << 24 | MINOR << 16 | MICRO << 8 | RELEASELEVEL << 4 | \
    SERIAL
PKk�\�5�t��wiredata.pynu�[���# Copyright (C) 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Wire Data Helper"""

import sys

import dns.exception
from ._compat import binary_type, string_types

# Figure out what constant python passes for an unspecified slice bound.
# It's supposed to be sys.maxint, yet on 64-bit windows sys.maxint is 2^31 - 1
# but Python uses 2^63 - 1 as the constant.  Rather than making pointless
# extra comparisons, duplicating code, or weakening WireData, we just figure
# out what constant Python will use.


class _SliceUnspecifiedBound(binary_type):

    def __getitem__(self, key):
        return key.stop

    if sys.version_info < (3,):
        def __getslice__(self, i, j):  # pylint: disable=getslice-method
            return self.__getitem__(slice(i, j))

_unspecified_bound = _SliceUnspecifiedBound()[1:]


class WireData(binary_type):
    # WireData is a string with stricter slicing

    def __getitem__(self, key):
        try:
            if isinstance(key, slice):
                # make sure we are not going outside of valid ranges,
                # do stricter control of boundaries than python does
                # by default
                start = key.start
                stop = key.stop

                if sys.version_info < (3,):
                    if stop == _unspecified_bound:
                        # handle the case where the right bound is unspecified
                        stop = len(self)

                    if start < 0 or stop < 0:
                        raise dns.exception.FormError
                    # If it's not an empty slice, access left and right bounds
                    # to make sure they're valid
                    if start != stop:
                        super(WireData, self).__getitem__(start)
                        super(WireData, self).__getitem__(stop - 1)
                else:
                    for index in (start, stop):
                        if index is None:
                            continue
                        elif abs(index) > len(self):
                            raise dns.exception.FormError

                return WireData(super(WireData, self).__getitem__(
                    slice(start, stop)))
            return bytearray(self.unwrap())[key]
        except IndexError:
            raise dns.exception.FormError

    if sys.version_info < (3,):
        def __getslice__(self, i, j):  # pylint: disable=getslice-method
            return self.__getitem__(slice(i, j))

    def __iter__(self):
        i = 0
        while 1:
            try:
                yield self[i]
                i += 1
            except dns.exception.FormError:
                raise StopIteration

    def unwrap(self):
        return binary_type(self)


def maybe_wrap(wire):
    if isinstance(wire, WireData):
        return wire
    elif isinstance(wire, binary_type):
        return WireData(wire)
    elif isinstance(wire, string_types):
        return WireData(wire.encode())
    raise ValueError("unhandled type %s" % type(wire))
PKk�\�H>��rdatatype.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Rdata Types.

@var _by_text: The rdata type textual name to value mapping
@type _by_text: dict
@var _by_value: The rdata type value to textual name mapping
@type _by_value: dict
@var _metatypes: If an rdatatype is a metatype, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _metatypes: dict
@var _singletons: If an rdatatype is a singleton, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _singletons: dict"""

import re

import dns.exception

NONE = 0
A = 1
NS = 2
MD = 3
MF = 4
CNAME = 5
SOA = 6
MB = 7
MG = 8
MR = 9
NULL = 10
WKS = 11
PTR = 12
HINFO = 13
MINFO = 14
MX = 15
TXT = 16
RP = 17
AFSDB = 18
X25 = 19
ISDN = 20
RT = 21
NSAP = 22
NSAP_PTR = 23
SIG = 24
KEY = 25
PX = 26
GPOS = 27
AAAA = 28
LOC = 29
NXT = 30
SRV = 33
NAPTR = 35
KX = 36
CERT = 37
A6 = 38
DNAME = 39
OPT = 41
APL = 42
DS = 43
SSHFP = 44
IPSECKEY = 45
RRSIG = 46
NSEC = 47
DNSKEY = 48
DHCID = 49
NSEC3 = 50
NSEC3PARAM = 51
TLSA = 52
HIP = 55
CDS = 59
CDNSKEY = 60
CSYNC = 62
SPF = 99
UNSPEC = 103
EUI48 = 108
EUI64 = 109
TKEY = 249
TSIG = 250
IXFR = 251
AXFR = 252
MAILB = 253
MAILA = 254
ANY = 255
URI = 256
CAA = 257
AVC = 258
TA = 32768
DLV = 32769

_by_text = {
    'NONE': NONE,
    'A': A,
    'NS': NS,
    'MD': MD,
    'MF': MF,
    'CNAME': CNAME,
    'SOA': SOA,
    'MB': MB,
    'MG': MG,
    'MR': MR,
    'NULL': NULL,
    'WKS': WKS,
    'PTR': PTR,
    'HINFO': HINFO,
    'MINFO': MINFO,
    'MX': MX,
    'TXT': TXT,
    'RP': RP,
    'AFSDB': AFSDB,
    'X25': X25,
    'ISDN': ISDN,
    'RT': RT,
    'NSAP': NSAP,
    'NSAP-PTR': NSAP_PTR,
    'SIG': SIG,
    'KEY': KEY,
    'PX': PX,
    'GPOS': GPOS,
    'AAAA': AAAA,
    'LOC': LOC,
    'NXT': NXT,
    'SRV': SRV,
    'NAPTR': NAPTR,
    'KX': KX,
    'CERT': CERT,
    'A6': A6,
    'DNAME': DNAME,
    'OPT': OPT,
    'APL': APL,
    'DS': DS,
    'SSHFP': SSHFP,
    'IPSECKEY': IPSECKEY,
    'RRSIG': RRSIG,
    'NSEC': NSEC,
    'DNSKEY': DNSKEY,
    'DHCID': DHCID,
    'NSEC3': NSEC3,
    'NSEC3PARAM': NSEC3PARAM,
    'TLSA': TLSA,
    'HIP': HIP,
    'CDS': CDS,
    'CDNSKEY': CDNSKEY,
    'CSYNC': CSYNC,
    'SPF': SPF,
    'UNSPEC': UNSPEC,
    'EUI48': EUI48,
    'EUI64': EUI64,
    'TKEY': TKEY,
    'TSIG': TSIG,
    'IXFR': IXFR,
    'AXFR': AXFR,
    'MAILB': MAILB,
    'MAILA': MAILA,
    'ANY': ANY,
    'URI': URI,
    'CAA': CAA,
    'AVC': AVC,
    'TA': TA,
    'DLV': DLV,
}

# We construct the inverse mapping programmatically to ensure that we
# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
# would cause the mapping not to be true inverse.

_by_value = dict((y, x) for x, y in _by_text.items())


_metatypes = {
    OPT: True
}

_singletons = {
    SOA: True,
    NXT: True,
    DNAME: True,
    NSEC: True,
    # CNAME is technically a singleton, but we allow multiple CNAMEs.
}

_unknown_type_pattern = re.compile('TYPE([0-9]+)$', re.I)


class UnknownRdatatype(dns.exception.DNSException):

    """DNS resource record type is unknown."""


def from_text(text):
    """Convert text into a DNS rdata type value.
    @param text: the text
    @type text: string
    @raises dns.rdatatype.UnknownRdatatype: the type is unknown
    @raises ValueError: the rdata type value is not >= 0 and <= 65535
    @rtype: int"""

    value = _by_text.get(text.upper())
    if value is None:
        match = _unknown_type_pattern.match(text)
        if match is None:
            raise UnknownRdatatype
        value = int(match.group(1))
        if value < 0 or value > 65535:
            raise ValueError("type must be between >= 0 and <= 65535")
    return value


def to_text(value):
    """Convert a DNS rdata type to text.
    @param value: the rdata type value
    @type value: int
    @raises ValueError: the rdata type value is not >= 0 and <= 65535
    @rtype: string"""

    if value < 0 or value > 65535:
        raise ValueError("type must be between >= 0 and <= 65535")
    text = _by_value.get(value)
    if text is None:
        text = 'TYPE' + repr(value)
    return text


def is_metatype(rdtype):
    """True if the type is a metatype.
    @param rdtype: the type
    @type rdtype: int
    @rtype: bool"""

    if rdtype >= TKEY and rdtype <= ANY or rdtype in _metatypes:
        return True
    return False


def is_singleton(rdtype):
    """True if the type is a singleton.
    @param rdtype: the type
    @type rdtype: int
    @rtype: bool"""

    if rdtype in _singletons:
        return True
    return False
PKk�\�޻$-$-rdataset.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS rdatasets (an rdataset is a set of rdatas of a given type and class)"""

import random
from io import StringIO
import struct

import dns.exception
import dns.rdatatype
import dns.rdataclass
import dns.rdata
import dns.set
from ._compat import string_types

# define SimpleSet here for backwards compatibility
SimpleSet = dns.set.Set


class DifferingCovers(dns.exception.DNSException):

    """An attempt was made to add a DNS SIG/RRSIG whose covered type
    is not the same as that of the other rdatas in the rdataset."""


class IncompatibleTypes(dns.exception.DNSException):

    """An attempt was made to add DNS RR data of an incompatible type."""


class Rdataset(dns.set.Set):

    """A DNS rdataset.

    @ivar rdclass: The class of the rdataset
    @type rdclass: int
    @ivar rdtype: The type of the rdataset
    @type rdtype: int
    @ivar covers: The covered type.  Usually this value is
    dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
    dns.rdatatype.RRSIG, then the covers value will be the rdata
    type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
    types as if they were a family of
    types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
    easier to work with than if RRSIGs covering different rdata
    types were aggregated into a single RRSIG rdataset.
    @type covers: int
    @ivar ttl: The DNS TTL (Time To Live) value
    @type ttl: int
    """

    __slots__ = ['rdclass', 'rdtype', 'covers', 'ttl']

    def __init__(self, rdclass, rdtype, covers=dns.rdatatype.NONE):
        """Create a new rdataset of the specified class and type.

        @see: the description of the class instance variables for the
        meaning of I{rdclass} and I{rdtype}"""

        super(Rdataset, self).__init__()
        self.rdclass = rdclass
        self.rdtype = rdtype
        self.covers = covers
        self.ttl = 0

    def _clone(self):
        obj = super(Rdataset, self)._clone()
        obj.rdclass = self.rdclass
        obj.rdtype = self.rdtype
        obj.covers = self.covers
        obj.ttl = self.ttl
        return obj

    def update_ttl(self, ttl):
        """Set the TTL of the rdataset to be the lesser of the set's current
        TTL or the specified TTL.  If the set contains no rdatas, set the TTL
        to the specified TTL.
        @param ttl: The TTL
        @type ttl: int"""

        if len(self) == 0:
            self.ttl = ttl
        elif ttl < self.ttl:
            self.ttl = ttl

    def add(self, rd, ttl=None):
        """Add the specified rdata to the rdataset.

        If the optional I{ttl} parameter is supplied, then
        self.update_ttl(ttl) will be called prior to adding the rdata.

        @param rd: The rdata
        @type rd: dns.rdata.Rdata object
        @param ttl: The TTL
        @type ttl: int"""

        #
        # If we're adding a signature, do some special handling to
        # check that the signature covers the same type as the
        # other rdatas in this rdataset.  If this is the first rdata
        # in the set, initialize the covers field.
        #
        if self.rdclass != rd.rdclass or self.rdtype != rd.rdtype:
            raise IncompatibleTypes
        if ttl is not None:
            self.update_ttl(ttl)
        if self.rdtype == dns.rdatatype.RRSIG or \
           self.rdtype == dns.rdatatype.SIG:
            covers = rd.covers()
            if len(self) == 0 and self.covers == dns.rdatatype.NONE:
                self.covers = covers
            elif self.covers != covers:
                raise DifferingCovers
        if dns.rdatatype.is_singleton(rd.rdtype) and len(self) > 0:
            self.clear()
        super(Rdataset, self).add(rd)

    def union_update(self, other):
        self.update_ttl(other.ttl)
        super(Rdataset, self).union_update(other)

    def intersection_update(self, other):
        self.update_ttl(other.ttl)
        super(Rdataset, self).intersection_update(other)

    def update(self, other):
        """Add all rdatas in other to self.

        @param other: The rdataset from which to update
        @type other: dns.rdataset.Rdataset object"""

        self.update_ttl(other.ttl)
        super(Rdataset, self).update(other)

    def __repr__(self):
        if self.covers == 0:
            ctext = ''
        else:
            ctext = '(' + dns.rdatatype.to_text(self.covers) + ')'
        return '<DNS ' + dns.rdataclass.to_text(self.rdclass) + ' ' + \
               dns.rdatatype.to_text(self.rdtype) + ctext + ' rdataset>'

    def __str__(self):
        return self.to_text()

    def __eq__(self, other):
        """Two rdatasets are equal if they have the same class, type, and
        covers, and contain the same rdata.
        @rtype: bool"""

        if not isinstance(other, Rdataset):
            return False
        if self.rdclass != other.rdclass or \
           self.rdtype != other.rdtype or \
           self.covers != other.covers:
            return False
        return super(Rdataset, self).__eq__(other)

    def __ne__(self, other):
        return not self.__eq__(other)

    def to_text(self, name=None, origin=None, relativize=True,
                override_rdclass=None, **kw):
        """Convert the rdataset into DNS master file format.

        @see: L{dns.name.Name.choose_relativity} for more information
        on how I{origin} and I{relativize} determine the way names
        are emitted.

        Any additional keyword arguments are passed on to the rdata
        to_text() method.

        @param name: If name is not None, emit a RRs with I{name} as
        the owner name.
        @type name: dns.name.Name object
        @param origin: The origin for relative names, or None.
        @type origin: dns.name.Name object
        @param relativize: True if names should names be relativized
        @type relativize: bool"""
        if name is not None:
            name = name.choose_relativity(origin, relativize)
            ntext = str(name)
            pad = ' '
        else:
            ntext = ''
            pad = ''
        s = StringIO()
        if override_rdclass is not None:
            rdclass = override_rdclass
        else:
            rdclass = self.rdclass
        if len(self) == 0:
            #
            # Empty rdatasets are used for the question section, and in
            # some dynamic updates, so we don't need to print out the TTL
            # (which is meaningless anyway).
            #
            s.write(u'%s%s%s %s\n' % (ntext, pad,
                                      dns.rdataclass.to_text(rdclass),
                                      dns.rdatatype.to_text(self.rdtype)))
        else:
            for rd in self:
                s.write(u'%s%s%d %s %s %s\n' %
                        (ntext, pad, self.ttl, dns.rdataclass.to_text(rdclass),
                         dns.rdatatype.to_text(self.rdtype),
                         rd.to_text(origin=origin, relativize=relativize,
                         **kw)))
        #
        # We strip off the final \n for the caller's convenience in printing
        #
        return s.getvalue()[:-1]

    def to_wire(self, name, file, compress=None, origin=None,
                override_rdclass=None, want_shuffle=True):
        """Convert the rdataset to wire format.

        @param name: The owner name of the RRset that will be emitted
        @type name: dns.name.Name object
        @param file: The file to which the wire format data will be appended
        @type file: file
        @param compress: The compression table to use; the default is None.
        @type compress: dict
        @param origin: The origin to be appended to any relative names when
        they are emitted.  The default is None.
        @returns: the number of records emitted
        @rtype: int
        """

        if override_rdclass is not None:
            rdclass = override_rdclass
            want_shuffle = False
        else:
            rdclass = self.rdclass
        file.seek(0, 2)
        if len(self) == 0:
            name.to_wire(file, compress, origin)
            stuff = struct.pack("!HHIH", self.rdtype, rdclass, 0, 0)
            file.write(stuff)
            return 1
        else:
            if want_shuffle:
                l = list(self)
                random.shuffle(l)
            else:
                l = self
            for rd in l:
                name.to_wire(file, compress, origin)
                stuff = struct.pack("!HHIH", self.rdtype, rdclass,
                                    self.ttl, 0)
                file.write(stuff)
                start = file.tell()
                rd.to_wire(file, compress, origin)
                end = file.tell()
                assert end - start < 65536
                file.seek(start - 2)
                stuff = struct.pack("!H", end - start)
                file.write(stuff)
                file.seek(0, 2)
            return len(self)

    def match(self, rdclass, rdtype, covers):
        """Returns True if this rdataset matches the specified class, type,
        and covers"""
        if self.rdclass == rdclass and \
           self.rdtype == rdtype and \
           self.covers == covers:
            return True
        return False


def from_text_list(rdclass, rdtype, ttl, text_rdatas):
    """Create an rdataset with the specified class, type, and TTL, and with
    the specified list of rdatas in text format.

    @rtype: dns.rdataset.Rdataset object
    """

    if isinstance(rdclass, string_types):
        rdclass = dns.rdataclass.from_text(rdclass)
    if isinstance(rdtype, string_types):
        rdtype = dns.rdatatype.from_text(rdtype)
    r = Rdataset(rdclass, rdtype)
    r.update_ttl(ttl)
    for t in text_rdatas:
        rd = dns.rdata.from_text(r.rdclass, r.rdtype, t)
        r.add(rd)
    return r


def from_text(rdclass, rdtype, ttl, *text_rdatas):
    """Create an rdataset with the specified class, type, and TTL, and with
    the specified rdatas in text format.

    @rtype: dns.rdataset.Rdataset object
    """

    return from_text_list(rdclass, rdtype, ttl, text_rdatas)


def from_rdata_list(ttl, rdatas):
    """Create an rdataset with the specified TTL, and with
    the specified list of rdata objects.

    @rtype: dns.rdataset.Rdataset object
    """

    if len(rdatas) == 0:
        raise ValueError("rdata list must not be empty")
    r = None
    for rd in rdatas:
        if r is None:
            r = Rdataset(rd.rdclass, rd.rdtype)
            r.update_ttl(ttl)
        r.add(rd)
    return r


def from_rdata(ttl, *rdatas):
    """Create an rdataset with the specified TTL, and with
    the specified rdata objects.

    @rtype: dns.rdataset.Rdataset object
    """

    return from_rdata_list(ttl, rdatas)
PKk�\�/�L�Lquery.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Talk to a DNS server."""

from __future__ import generators

import errno
import select
import socket
import struct
import sys
import time

import dns.exception
import dns.inet
import dns.name
import dns.message
import dns.rdataclass
import dns.rdatatype
from ._compat import long, string_types

if sys.version_info > (3,):
    select_error = OSError
else:
    select_error = select.error

# Function used to create a socket.  Can be overridden if needed in special
# situations.
socket_factory = socket.socket

class UnexpectedSource(dns.exception.DNSException):

    """A DNS query response came from an unexpected address or port."""


class BadResponse(dns.exception.FormError):

    """A DNS query response does not respond to the question asked."""


def _compute_expiration(timeout):
    if timeout is None:
        return None
    else:
        return time.time() + timeout


def _poll_for(fd, readable, writable, error, timeout):
    """Poll polling backend.
    @param fd: File descriptor
    @type fd: int
    @param readable: Whether to wait for readability
    @type readable: bool
    @param writable: Whether to wait for writability
    @type writable: bool
    @param timeout: Deadline timeout (expiration time, in seconds)
    @type timeout: float
    @return True on success, False on timeout
    """
    event_mask = 0
    if readable:
        event_mask |= select.POLLIN
    if writable:
        event_mask |= select.POLLOUT
    if error:
        event_mask |= select.POLLERR

    pollable = select.poll()
    pollable.register(fd, event_mask)

    if timeout:
        event_list = pollable.poll(long(timeout * 1000))
    else:
        event_list = pollable.poll()

    return bool(event_list)


def _select_for(fd, readable, writable, error, timeout):
    """Select polling backend.
    @param fd: File descriptor
    @type fd: int
    @param readable: Whether to wait for readability
    @type readable: bool
    @param writable: Whether to wait for writability
    @type writable: bool
    @param timeout: Deadline timeout (expiration time, in seconds)
    @type timeout: float
    @return True on success, False on timeout
    """
    rset, wset, xset = [], [], []

    if readable:
        rset = [fd]
    if writable:
        wset = [fd]
    if error:
        xset = [fd]

    if timeout is None:
        (rcount, wcount, xcount) = select.select(rset, wset, xset)
    else:
        (rcount, wcount, xcount) = select.select(rset, wset, xset, timeout)

    return bool((rcount or wcount or xcount))


def _wait_for(fd, readable, writable, error, expiration):
    done = False
    while not done:
        if expiration is None:
            timeout = None
        else:
            timeout = expiration - time.time()
            if timeout <= 0.0:
                raise dns.exception.Timeout
        try:
            if not _polling_backend(fd, readable, writable, error, timeout):
                raise dns.exception.Timeout
        except select_error as e:
            if e.args[0] != errno.EINTR:
                raise e
        done = True


def _set_polling_backend(fn):
    """
    Internal API. Do not use.
    """
    global _polling_backend

    _polling_backend = fn

if hasattr(select, 'poll'):
    # Prefer poll() on platforms that support it because it has no
    # limits on the maximum value of a file descriptor (plus it will
    # be more efficient for high values).
    _polling_backend = _poll_for
else:
    _polling_backend = _select_for


def _wait_for_readable(s, expiration):
    _wait_for(s, True, False, True, expiration)


def _wait_for_writable(s, expiration):
    _wait_for(s, False, True, True, expiration)


def _addresses_equal(af, a1, a2):
    # Convert the first value of the tuple, which is a textual format
    # address into binary form, so that we are not confused by different
    # textual representations of the same address
    n1 = dns.inet.inet_pton(af, a1[0])
    n2 = dns.inet.inet_pton(af, a2[0])
    return n1 == n2 and a1[1:] == a2[1:]


def _matches_destination(af, from_address, destination, ignore_unexpected):
    # Check that from_address is appropriate for a response to a query
    # sent to destination.
    if not destination:
        return True
    if _addresses_equal(af, from_address, destination) or (
        dns.inet.is_multicast(destination[0]) and from_address[1:] == destination[1:]
    ):
        return True
    elif ignore_unexpected:
        return False
    raise UnexpectedSource(
        f"got a response from {from_address} instead of " f"{destination}"
    )


def _destination_and_source(af, where, port, source, source_port):
    # Apply defaults and compute destination and source tuples
    # suitable for use in connect(), sendto(), or bind().
    if af is None:
        try:
            af = dns.inet.af_for_address(where)
        except Exception:
            af = dns.inet.AF_INET
    if af == dns.inet.AF_INET:
        destination = (where, port)
        if source is not None or source_port != 0:
            if source is None:
                source = '0.0.0.0'
            source = (source, source_port)
    elif af == dns.inet.AF_INET6:
        destination = (where, port, 0, 0)
        if source is not None or source_port != 0:
            if source is None:
                source = '::'
            source = (source, source_port, 0, 0)
    return (af, destination, source)


def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
        ignore_unexpected=False, one_rr_per_rrset=False, ignore_errors=False):
    """Return the response obtained after sending a query via UDP.

    @param q: the query
    @type q: dns.message.Message
    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param timeout: The number of seconds to wait before the query times out.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @rtype: dns.message.Message object
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param ignore_unexpected: If True, ignore responses from unexpected
    sources.  The default is False.
    @type ignore_unexpected: bool
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    """

    wire = q.to_wire()
    (af, destination, source) = _destination_and_source(af, where, port,
                                                        source, source_port)
    s = socket_factory(af, socket.SOCK_DGRAM, 0)
    begin_time = None
    try:
        expiration = _compute_expiration(timeout)
        s.setblocking(0)
        if source is not None:
            s.bind(source)
        _wait_for_writable(s, expiration)
        begin_time = time.time()
        s.sendto(wire, destination)
        while 1:
            _wait_for_readable(s, expiration)
            (wire, from_address) = s.recvfrom(65535)
            if not _matches_destination(
                s.family, from_address, destination, ignore_unexpected
            ):
                continue

            response_time = time.time() - begin_time

            try:
                r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
                                  one_rr_per_rrset=one_rr_per_rrset)
                r.time = response_time
            except Exception:
                if ignore_errors:
                    continue
                else:
                    raise

            if q.is_response(r):
                return r
            else:
                if ignore_errors:
                    continue
                else:
                    raise BadResponse
    finally:
        s.close()


def _net_read(sock, count, expiration):
    """Read the specified number of bytes from sock.  Keep trying until we
    either get the desired amount, or we hit EOF.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    """
    s = b''
    while count > 0:
        _wait_for_readable(sock, expiration)
        n = sock.recv(count)
        if n == b'':
            raise EOFError
        count = count - len(n)
        s = s + n
    return s


def _net_write(sock, data, expiration):
    """Write the specified data to the socket.
    A Timeout exception will be raised if the operation is not completed
    by the expiration time.
    """
    current = 0
    l = len(data)
    while current < l:
        _wait_for_writable(sock, expiration)
        current += sock.send(data[current:])


def _connect(s, address):
    try:
        s.connect(address)
    except socket.error:
        (ty, v) = sys.exc_info()[:2]

        if hasattr(v, 'errno'):
            v_err = v.errno
        else:
            v_err = v[0]
        if v_err not in [errno.EINPROGRESS, errno.EWOULDBLOCK, errno.EALREADY]:
            raise v


def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
        one_rr_per_rrset=False):
    """Return the response obtained after sending a query via TCP.

    @param q: the query
    @type q: dns.message.Message object
    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param timeout: The number of seconds to wait before the query times out.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @rtype: dns.message.Message object
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param one_rr_per_rrset: Put each RR into its own RRset
    @type one_rr_per_rrset: bool
    """

    wire = q.to_wire()
    (af, destination, source) = _destination_and_source(af, where, port,
                                                        source, source_port)
    s = socket_factory(af, socket.SOCK_STREAM, 0)
    begin_time = None
    try:
        expiration = _compute_expiration(timeout)
        s.setblocking(0)
        begin_time = time.time()
        if source is not None:
            s.bind(source)
        _connect(s, destination)

        l = len(wire)

        # copying the wire into tcpmsg is inefficient, but lets us
        # avoid writev() or doing a short write that would get pushed
        # onto the net
        tcpmsg = struct.pack("!H", l) + wire
        _net_write(s, tcpmsg, expiration)
        ldata = _net_read(s, 2, expiration)
        (l,) = struct.unpack("!H", ldata)
        wire = _net_read(s, l, expiration)
    finally:
        if begin_time is None:
            response_time = 0
        else:
            response_time = time.time() - begin_time
        s.close()
    r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
                              one_rr_per_rrset=one_rr_per_rrset)
    r.time = response_time
    if not q.is_response(r):
        raise BadResponse
    return r


def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
        timeout=None, port=53, keyring=None, keyname=None, relativize=True,
        af=None, lifetime=None, source=None, source_port=0, serial=0,
        use_udp=False, keyalgorithm=dns.tsig.default_algorithm):
    """Return a generator for the responses to a zone transfer.

    @param where: where to send the message
    @type where: string containing an IPv4 or IPv6 address
    @param zone: The name of the zone to transfer
    @type zone: dns.name.Name object or string
    @param rdtype: The type of zone transfer.  The default is
    dns.rdatatype.AXFR.
    @type rdtype: int or string
    @param rdclass: The class of the zone transfer.  The default is
    dns.rdataclass.IN.
    @type rdclass: int or string
    @param timeout: The number of seconds to wait for each response message.
    If None, the default, wait forever.
    @type timeout: float
    @param port: The port to which to send the message.  The default is 53.
    @type port: int
    @param keyring: The TSIG keyring to use
    @type keyring: dict
    @param keyname: The name of the TSIG key to use
    @type keyname: dns.name.Name object or string
    @param relativize: If True, all names in the zone will be relativized to
    the zone origin.  It is essential that the relativize setting matches
    the one specified to dns.zone.from_xfr().
    @type relativize: bool
    @param af: the address family to use.  The default is None, which
    causes the address family to use to be inferred from the form of where.
    If the inference attempt fails, AF_INET is used.
    @type af: int
    @param lifetime: The total number of seconds to spend doing the transfer.
    If None, the default, then there is no limit on the time the transfer may
    take.
    @type lifetime: float
    @rtype: generator of dns.message.Message objects.
    @param source: source address.  The default is the wildcard address.
    @type source: string
    @param source_port: The port from which to send the message.
    The default is 0.
    @type source_port: int
    @param serial: The SOA serial number to use as the base for an IXFR diff
    sequence (only meaningful if rdtype == dns.rdatatype.IXFR).
    @type serial: int
    @param use_udp: Use UDP (only meaningful for IXFR)
    @type use_udp: bool
    @param keyalgorithm: The TSIG algorithm to use; defaults to
    dns.tsig.default_algorithm
    @type keyalgorithm: string
    """

    if isinstance(zone, string_types):
        zone = dns.name.from_text(zone)
    if isinstance(rdtype, string_types):
        rdtype = dns.rdatatype.from_text(rdtype)
    q = dns.message.make_query(zone, rdtype, rdclass)
    if rdtype == dns.rdatatype.IXFR:
        rrset = dns.rrset.from_text(zone, 0, 'IN', 'SOA',
                                    '. . %u 0 0 0 0' % serial)
        q.authority.append(rrset)
    if keyring is not None:
        q.use_tsig(keyring, keyname, algorithm=keyalgorithm)
    wire = q.to_wire()
    (af, destination, source) = _destination_and_source(af, where, port,
                                                        source, source_port)
    if use_udp:
        if rdtype != dns.rdatatype.IXFR:
            raise ValueError('cannot do a UDP AXFR')
        s = socket_factory(af, socket.SOCK_DGRAM, 0)
    else:
        s = socket_factory(af, socket.SOCK_STREAM, 0)
    s.setblocking(0)
    if source is not None:
        s.bind(source)
    expiration = _compute_expiration(lifetime)
    _connect(s, destination)
    l = len(wire)
    if use_udp:
        _wait_for_writable(s, expiration)
        s.send(wire)
    else:
        tcpmsg = struct.pack("!H", l) + wire
        _net_write(s, tcpmsg, expiration)
    done = False
    delete_mode = True
    expecting_SOA = False
    soa_rrset = None
    if relativize:
        origin = zone
        oname = dns.name.empty
    else:
        origin = None
        oname = zone
    tsig_ctx = None
    first = True
    while not done:
        mexpiration = _compute_expiration(timeout)
        if mexpiration is None or \
           (expiration is not None and mexpiration > expiration):
            mexpiration = expiration
        if use_udp:
            _wait_for_readable(s, expiration)
            (wire, from_address) = s.recvfrom(65535)
        else:
            ldata = _net_read(s, 2, mexpiration)
            (l,) = struct.unpack("!H", ldata)
            wire = _net_read(s, l, mexpiration)
        is_ixfr = (rdtype == dns.rdatatype.IXFR)
        r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
                                  xfr=True, origin=origin, tsig_ctx=tsig_ctx,
                                  multi=True, first=first,
                                  one_rr_per_rrset=is_ixfr)
        tsig_ctx = r.tsig_ctx
        first = False
        answer_index = 0
        if soa_rrset is None:
            if not r.answer or r.answer[0].name != oname:
                raise dns.exception.FormError(
                    "No answer or RRset not for qname")
            rrset = r.answer[0]
            if rrset.rdtype != dns.rdatatype.SOA:
                raise dns.exception.FormError("first RRset is not an SOA")
            answer_index = 1
            soa_rrset = rrset.copy()
            if rdtype == dns.rdatatype.IXFR:
                if soa_rrset[0].serial <= serial:
                    #
                    # We're already up-to-date.
                    #
                    done = True
                else:
                    expecting_SOA = True
        #
        # Process SOAs in the answer section (other than the initial
        # SOA in the first message).
        #
        for rrset in r.answer[answer_index:]:
            if done:
                raise dns.exception.FormError("answers after final SOA")
            if rrset.rdtype == dns.rdatatype.SOA and rrset.name == oname:
                if expecting_SOA:
                    if rrset[0].serial != serial:
                        raise dns.exception.FormError(
                            "IXFR base serial mismatch")
                    expecting_SOA = False
                elif rdtype == dns.rdatatype.IXFR:
                    delete_mode = not delete_mode
                #
                # If this SOA RRset is equal to the first we saw then we're
                # finished. If this is an IXFR we also check that we're seeing
                # the record in the expected part of the response.
                #
                if rrset == soa_rrset and \
                        (rdtype == dns.rdatatype.AXFR or
                         (rdtype == dns.rdatatype.IXFR and delete_mode)):
                    done = True
            elif expecting_SOA:
                #
                # We made an IXFR request and are expecting another
                # SOA RR, but saw something else, so this must be an
                # AXFR response.
                #
                rdtype = dns.rdatatype.AXFR
                expecting_SOA = False
        if done and q.keyring and not r.had_tsig:
            raise dns.exception.FormError("missing TSIG")
        yield r
    s.close()
PKk�\˸����ipv4.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""IPv4 helper functions."""

import struct

import dns.exception
from ._compat import binary_type

def inet_ntoa(address):
    """Convert an IPv4 address in network form to text form.

    @param address: The IPv4 address
    @type address: string
    @returns: string
    """
    if len(address) != 4:
        raise dns.exception.SyntaxError
    if not isinstance(address, bytearray):
        address = bytearray(address)
    return (u'%u.%u.%u.%u' % (address[0], address[1],
                              address[2], address[3])).encode()

def inet_aton(text):
    """Convert an IPv4 address in text form to network form.

    @param text: The IPv4 address
    @type text: string
    @returns: string
    """
    if not isinstance(text, binary_type):
        text = text.encode()
    parts = text.split(b'.')
    if len(parts) != 4:
        raise dns.exception.SyntaxError
    for part in parts:
        if not part.isdigit():
            raise dns.exception.SyntaxError
        if len(part) > 1 and part[0] == '0':
            # No leading zeros
            raise dns.exception.SyntaxError
    try:
        bytes = [int(part) for part in parts]
        return struct.pack('BBBB', *bytes)
    except:
        raise dns.exception.SyntaxError
PKk�\Cy�x  edns.pynu�[���# Copyright (C) 2009, 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""EDNS Options"""

NSID = 3


class Option(object):

    """Base class for all EDNS option types.
    """

    def __init__(self, otype):
        """Initialize an option.
        @param otype: The rdata type
        @type otype: int
        """
        self.otype = otype

    def to_wire(self, file):
        """Convert an option to wire format.
        """
        raise NotImplementedError

    @classmethod
    def from_wire(cls, otype, wire, current, olen):
        """Build an EDNS option object from wire format

        @param otype: The option type
        @type otype: int
        @param wire: The wire-format message
        @type wire: string
        @param current: The offset in wire of the beginning of the rdata.
        @type current: int
        @param olen: The length of the wire-format option data
        @type olen: int
        @rtype: dns.edns.Option instance"""
        raise NotImplementedError

    def _cmp(self, other):
        """Compare an EDNS option with another option of the same type.
        Return < 0 if self < other, 0 if self == other,
        and > 0 if self > other.
        """
        raise NotImplementedError

    def __eq__(self, other):
        if not isinstance(other, Option):
            return False
        if self.otype != other.otype:
            return False
        return self._cmp(other) == 0

    def __ne__(self, other):
        if not isinstance(other, Option):
            return False
        if self.otype != other.otype:
            return False
        return self._cmp(other) != 0

    def __lt__(self, other):
        if not isinstance(other, Option) or \
                self.otype != other.otype:
            return NotImplemented
        return self._cmp(other) < 0

    def __le__(self, other):
        if not isinstance(other, Option) or \
                self.otype != other.otype:
            return NotImplemented
        return self._cmp(other) <= 0

    def __ge__(self, other):
        if not isinstance(other, Option) or \
                self.otype != other.otype:
            return NotImplemented
        return self._cmp(other) >= 0

    def __gt__(self, other):
        if not isinstance(other, Option) or \
                self.otype != other.otype:
            return NotImplemented
        return self._cmp(other) > 0


class GenericOption(Option):

    """Generate Rdata Class

    This class is used for EDNS option types for which we have no better
    implementation.
    """

    def __init__(self, otype, data):
        super(GenericOption, self).__init__(otype)
        self.data = data

    def to_wire(self, file):
        file.write(self.data)

    @classmethod
    def from_wire(cls, otype, wire, current, olen):
        return cls(otype, wire[current: current + olen])

    def _cmp(self, other):
        if self.data == other.data:
            return 0
        if self.data > other.data:
            return 1
        return -1

_type_to_class = {
}


def get_option_class(otype):
    cls = _type_to_class.get(otype)
    if cls is None:
        cls = GenericOption
    return cls


def option_from_wire(otype, wire, current, olen):
    """Build an EDNS option object from wire format

    @param otype: The option type
    @type otype: int
    @param wire: The wire-format message
    @type wire: string
    @param current: The offset in wire of the beginning of the rdata.
    @type current: int
    @param olen: The length of the wire-format option data
    @type olen: int
    @rtype: dns.edns.Option instance"""

    cls = get_option_class(otype)
    return cls.from_wire(otype, wire, current, olen)
PKk�\/XO��node.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS nodes.  A node is a set of rdatasets."""

from io import StringIO

import dns.rdataset
import dns.rdatatype
import dns.renderer


class Node(object):

    """A DNS node.

    A node is a set of rdatasets

    @ivar rdatasets: the node's rdatasets
    @type rdatasets: list of dns.rdataset.Rdataset objects"""

    __slots__ = ['rdatasets']

    def __init__(self):
        """Initialize a DNS node.
        """

        self.rdatasets = []

    def to_text(self, name, **kw):
        """Convert a node to text format.

        Each rdataset at the node is printed.  Any keyword arguments
        to this method are passed on to the rdataset's to_text() method.
        @param name: the owner name of the rdatasets
        @type name: dns.name.Name object
        @rtype: string
        """

        s = StringIO()
        for rds in self.rdatasets:
            if len(rds) > 0:
                s.write(rds.to_text(name, **kw))
                s.write(u'\n')
        return s.getvalue()[:-1]

    def __repr__(self):
        return '<DNS node ' + str(id(self)) + '>'

    def __eq__(self, other):
        """Two nodes are equal if they have the same rdatasets.

        @rtype: bool
        """
        #
        # This is inefficient.  Good thing we don't need to do it much.
        #
        for rd in self.rdatasets:
            if rd not in other.rdatasets:
                return False
        for rd in other.rdatasets:
            if rd not in self.rdatasets:
                return False
        return True

    def __ne__(self, other):
        return not self.__eq__(other)

    def __len__(self):
        return len(self.rdatasets)

    def __iter__(self):
        return iter(self.rdatasets)

    def find_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE,
                      create=False):
        """Find an rdataset matching the specified properties in the
        current node.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.  Usually this value is
        dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
        dns.rdatatype.RRSIG, then the covers value will be the rdata
        type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
        types as if they were a family of
        types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
        easier to work with than if RRSIGs covering different rdata
        types were aggregated into a single RRSIG rdataset.
        @type covers: int
        @param create: If True, create the rdataset if it is not found.
        @type create: bool
        @raises KeyError: An rdataset of the desired type and class does
        not exist and I{create} is not True.
        @rtype: dns.rdataset.Rdataset object
        """

        for rds in self.rdatasets:
            if rds.match(rdclass, rdtype, covers):
                return rds
        if not create:
            raise KeyError
        rds = dns.rdataset.Rdataset(rdclass, rdtype)
        self.rdatasets.append(rds)
        return rds

    def get_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE,
                     create=False):
        """Get an rdataset matching the specified properties in the
        current node.

        None is returned if an rdataset of the specified type and
        class does not exist and I{create} is not True.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.
        @type covers: int
        @param create: If True, create the rdataset if it is not found.
        @type create: bool
        @rtype: dns.rdataset.Rdataset object or None
        """

        try:
            rds = self.find_rdataset(rdclass, rdtype, covers, create)
        except KeyError:
            rds = None
        return rds

    def delete_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE):
        """Delete the rdataset matching the specified properties in the
        current node.

        If a matching rdataset does not exist, it is not an error.

        @param rdclass: The class of the rdataset
        @type rdclass: int
        @param rdtype: The type of the rdataset
        @type rdtype: int
        @param covers: The covered type.
        @type covers: int
        """

        rds = self.get_rdataset(rdclass, rdtype, covers)
        if rds is not None:
            self.rdatasets.remove(rds)

    def replace_rdataset(self, replacement):
        """Replace an rdataset.

        It is not an error if there is no rdataset matching I{replacement}.

        Ownership of the I{replacement} object is transferred to the node;
        in other words, this method does not store a copy of I{replacement}
        at the node, it stores I{replacement} itself.
        """

        if not isinstance(replacement, dns.rdataset.Rdataset):
            raise ValueError('replacement is not an rdataset')
        self.delete_rdataset(replacement.rdclass, replacement.rdtype,
                             replacement.covers)
        self.rdatasets.append(replacement)
PKk�\���kkrrset.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS RRsets (an RRset is a named rdataset)"""


import dns.name
import dns.rdataset
import dns.rdataclass
import dns.renderer
from ._compat import string_types


class RRset(dns.rdataset.Rdataset):

    """A DNS RRset (named rdataset).

    RRset inherits from Rdataset, and RRsets can be treated as
    Rdatasets in most cases.  There are, however, a few notable
    exceptions.  RRsets have different to_wire() and to_text() method
    arguments, reflecting the fact that RRsets always have an owner
    name.
    """

    __slots__ = ['name', 'deleting']

    def __init__(self, name, rdclass, rdtype, covers=dns.rdatatype.NONE,
                 deleting=None):
        """Create a new RRset."""

        super(RRset, self).__init__(rdclass, rdtype, covers)
        self.name = name
        self.deleting = deleting

    def _clone(self):
        obj = super(RRset, self)._clone()
        obj.name = self.name
        obj.deleting = self.deleting
        return obj

    def __repr__(self):
        if self.covers == 0:
            ctext = ''
        else:
            ctext = '(' + dns.rdatatype.to_text(self.covers) + ')'
        if self.deleting is not None:
            dtext = ' delete=' + dns.rdataclass.to_text(self.deleting)
        else:
            dtext = ''
        return '<DNS ' + str(self.name) + ' ' + \
               dns.rdataclass.to_text(self.rdclass) + ' ' + \
               dns.rdatatype.to_text(self.rdtype) + ctext + dtext + ' RRset>'

    def __str__(self):
        return self.to_text()

    def __eq__(self, other):
        """Two RRsets are equal if they have the same name and the same
        rdataset

        @rtype: bool"""
        if not isinstance(other, RRset):
            return False
        if self.name != other.name:
            return False
        return super(RRset, self).__eq__(other)

    def match(self, name, rdclass, rdtype, covers, deleting=None):
        """Returns True if this rrset matches the specified class, type,
        covers, and deletion state."""

        if not super(RRset, self).match(rdclass, rdtype, covers):
            return False
        if self.name != name or self.deleting != deleting:
            return False
        return True

    def to_text(self, origin=None, relativize=True, **kw):
        """Convert the RRset into DNS master file format.

        @see: L{dns.name.Name.choose_relativity} for more information
        on how I{origin} and I{relativize} determine the way names
        are emitted.

        Any additional keyword arguments are passed on to the rdata
        to_text() method.

        @param origin: The origin for relative names, or None.
        @type origin: dns.name.Name object
        @param relativize: True if names should names be relativized
        @type relativize: bool"""

        return super(RRset, self).to_text(self.name, origin, relativize,
                                          self.deleting, **kw)

    def to_wire(self, file, compress=None, origin=None, **kw):
        """Convert the RRset to wire format."""

        return super(RRset, self).to_wire(self.name, file, compress, origin,
                                          self.deleting, **kw)

    def to_rdataset(self):
        """Convert an RRset into an Rdataset.

        @rtype: dns.rdataset.Rdataset object
        """
        return dns.rdataset.from_rdata_list(self.ttl, list(self))


def from_text_list(name, ttl, rdclass, rdtype, text_rdatas,
                   idna_codec=None):
    """Create an RRset with the specified name, TTL, class, and type, and with
    the specified list of rdatas in text format.

    @rtype: dns.rrset.RRset object
    """

    if isinstance(name, string_types):
        name = dns.name.from_text(name, None, idna_codec=idna_codec)
    if isinstance(rdclass, string_types):
        rdclass = dns.rdataclass.from_text(rdclass)
    if isinstance(rdtype, string_types):
        rdtype = dns.rdatatype.from_text(rdtype)
    r = RRset(name, rdclass, rdtype)
    r.update_ttl(ttl)
    for t in text_rdatas:
        rd = dns.rdata.from_text(r.rdclass, r.rdtype, t)
        r.add(rd)
    return r


def from_text(name, ttl, rdclass, rdtype, *text_rdatas):
    """Create an RRset with the specified name, TTL, class, and type and with
    the specified rdatas in text format.

    @rtype: dns.rrset.RRset object
    """

    return from_text_list(name, ttl, rdclass, rdtype, text_rdatas)


def from_rdata_list(name, ttl, rdatas, idna_codec=None):
    """Create an RRset with the specified name and TTL, and with
    the specified list of rdata objects.

    @rtype: dns.rrset.RRset object
    """

    if isinstance(name, string_types):
        name = dns.name.from_text(name, None, idna_codec=idna_codec)

    if len(rdatas) == 0:
        raise ValueError("rdata list must not be empty")
    r = None
    for rd in rdatas:
        if r is None:
            r = RRset(name, rd.rdclass, rd.rdtype)
            r.update_ttl(ttl)
        r.add(rd)
    return r


def from_rdata(name, ttl, *rdatas):
    """Create an RRset with the specified name and TTL, and with
    the specified rdata objects.

    @rtype: dns.rrset.RRset object
    """

    return from_rdata_list(name, ttl, rdatas)
PKk�\7�D�r�rname.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Names.

@var root: The DNS root name.
@type root: dns.name.Name object
@var empty: The empty DNS name.
@type empty: dns.name.Name object
"""

from io import BytesIO
import struct
import sys
import copy
import encodings.idna
try:
    import idna
    have_idna_2008 = True
except ImportError:
    have_idna_2008 = False

import dns.exception
import dns.wiredata

from ._compat import long, binary_type, text_type, unichr, maybe_decode

try:
    maxint = sys.maxint
except AttributeError:
    maxint = (1 << (8 * struct.calcsize("P"))) // 2 - 1

NAMERELN_NONE = 0
NAMERELN_SUPERDOMAIN = 1
NAMERELN_SUBDOMAIN = 2
NAMERELN_EQUAL = 3
NAMERELN_COMMONANCESTOR = 4


class EmptyLabel(dns.exception.SyntaxError):

    """A DNS label is empty."""


class BadEscape(dns.exception.SyntaxError):

    """An escaped code in a text format of DNS name is invalid."""


class BadPointer(dns.exception.FormError):

    """A DNS compression pointer points forward instead of backward."""


class BadLabelType(dns.exception.FormError):

    """The label type in DNS name wire format is unknown."""


class NeedAbsoluteNameOrOrigin(dns.exception.DNSException):

    """An attempt was made to convert a non-absolute name to
    wire when there was also a non-absolute (or missing) origin."""


class NameTooLong(dns.exception.FormError):

    """A DNS name is > 255 octets long."""


class LabelTooLong(dns.exception.SyntaxError):

    """A DNS label is > 63 octets long."""


class AbsoluteConcatenation(dns.exception.DNSException):

    """An attempt was made to append anything other than the
    empty name to an absolute DNS name."""


class NoParent(dns.exception.DNSException):

    """An attempt was made to get the parent of the root name
    or the empty name."""

class NoIDNA2008(dns.exception.DNSException):

    """IDNA 2008 processing was requested but the idna module is not
    available."""


class IDNAException(dns.exception.DNSException):

    """IDNA processing raised an exception."""

    supp_kwargs = set(['idna_exception'])
    fmt = "IDNA processing exception: {idna_exception}"

class IDNACodec(object):

    """Abstract base class for IDNA encoder/decoders."""

    def __init__(self):
        pass

    def is_idna(self, label):
        return label.lower().startswith(b'xn--')

    def is_all_ascii(self, label):
        for c in label:
            if ord(c) > 0x7f:
                return False
        return True

    def encode(self, label):
        raise NotImplementedError

    def decode(self, label):
        # We do not apply any IDNA policy on decode.
        if self.is_idna(label):
            try:
                label = label[4:].decode('punycode')
            except Exception as e:
                raise IDNAException(idna_exception=e)
        else:
            label = maybe_decode(label)
        return _escapify(label)

class IDNA2003Codec(IDNACodec):

    """IDNA 2003 encoder/decoder."""

    def __init__(self, strict_decode=False):
        """Initialize the IDNA 2003 encoder/decoder.
        @param strict_decode: If True, then IDNA2003 checking is done when
        decoding.  This can cause failures if the name was encoded with
        IDNA2008.  The default is False.
        @type strict_decode: bool
        """
        super(IDNA2003Codec, self).__init__()
        self.strict_decode = strict_decode

    def encode(self, label):
        if label == '':
            return b''
        try:
            return encodings.idna.ToASCII(label)
        except UnicodeError:
            raise LabelTooLong

    def decode(self, label):
        if not self.strict_decode:
            return super(IDNA2003Codec, self).decode(label)
        if label == b'':
            return u''
        try:
            return _escapify(encodings.idna.ToUnicode(label))
        except Exception as e:
            raise IDNAException(idna_exception=e)

class IDNA2008Codec(IDNACodec):

    """IDNA 2008 encoder/decoder."""

    def __init__(self, uts_46=False, transitional=False,
                 allow_pure_ascii=False, strict_decode=False):
        """Initialize the IDNA 2008 encoder/decoder.
        @param uts_46: If True, apply Unicode IDNA compatibility processing
        as described in Unicode Technical Standard #46
        (U{http://unicode.org/reports/tr46/}).  This parameter is only
        meaningful if IDNA 2008 is in use.  If False, do not apply
        the mapping.  The default is False
        @type uts_46: bool
        @param transitional: If True, use the "transitional" mode described
        in Unicode Technical Standard #46.  This parameter is only
        meaningful if IDNA 2008 is in use.  The default is False.
        @type transitional: bool
        @param allow_pure_ascii: If True, then a label which
        consists of only ASCII characters is allowed.  This is less strict
        than regular IDNA 2008, but is also necessary for mixed names,
        e.g. a name with starting with "_sip._tcp." and ending in an IDN
        suffixm which would otherwise be disallowed.  The default is False
        @type allow_pure_ascii: bool
        @param strict_decode: If True, then IDNA2008 checking is done when
        decoding.  This can cause failures if the name was encoded with
        IDNA2003.  The default is False.
        @type strict_decode: bool
        """
        super(IDNA2008Codec, self).__init__()
        self.uts_46 = uts_46
        self.transitional = transitional
        self.allow_pure_ascii = allow_pure_ascii
        self.strict_decode = strict_decode

    def encode(self, label):
        if label == '':
            return b''
        if self.allow_pure_ascii and self.is_all_ascii(label):
            return label.encode('ascii')
        if not have_idna_2008:
            raise NoIDNA2008
        try:
            if self.uts_46:
                label = idna.uts46_remap(label, False, self.transitional)
            return idna.alabel(label)
        except idna.IDNAError as e:
            raise IDNAException(idna_exception=e)

    def decode(self, label):
        if not self.strict_decode:
            return super(IDNA2008Codec, self).decode(label)
        if label == b'':
            return u''
        if not have_idna_2008:
            raise NoIDNA2008
        try:
            if self.uts_46:
                label = idna.uts46_remap(label, False, False)
            return _escapify(idna.ulabel(label))
        except idna.IDNAError as e:
            raise IDNAException(idna_exception=e)

_escaped = bytearray(b'"().;\\@$')
_escaped_text = '"().;\\@$'

IDNA_2003_Practical = IDNA2003Codec(False)
IDNA_2003_Strict = IDNA2003Codec(True)
IDNA_2003 = IDNA_2003_Practical
IDNA_2008_Practical = IDNA2008Codec(True, False, True, False)
IDNA_2008_UTS_46 = IDNA2008Codec(True, False, False, False)
IDNA_2008_Strict = IDNA2008Codec(False, False, False, True)
IDNA_2008_Transitional = IDNA2008Codec(True, True, False, False)
IDNA_2008 = IDNA_2008_Practical

def _escapify(label):
    """Escape the characters in label which need it.
    @returns: the escaped string
    @rtype: string"""
    if isinstance(label, bytes):
        # Ordinary DNS label mode.  Escape special characters and values
        # < 0x20 or > 0x7f.
        text = ''
        if isinstance(label, text_type):
            label = label.encode()
        for c in bytearray(label):
            if c in _escaped:
                text += '\\' + chr(c)
            elif c > 0x20 and c < 0x7F:
                text += chr(c)
            else:
                text += '\\%03d' % c
        return text

    # Unicode label mode.  Escape only special characters and values < 0x20
    text = u''
    for c in label:
        if c in _escaped_text:
            text += '\\' + c
        elif c <= '\x20':
            text += '\\%03d' % ord(c)
        else:
            text += c
    return text

def _validate_labels(labels):
    """Check for empty labels in the middle of a label sequence,
    labels that are too long, and for too many labels.
    @raises NameTooLong: the name as a whole is too long
    @raises EmptyLabel: a label is empty (i.e. the root label) and appears
    in a position other than the end of the label sequence"""

    l = len(labels)
    total = 0
    i = -1
    j = 0
    for label in labels:
        ll = len(label)
        total += ll + 1
        if ll > 63:
            raise LabelTooLong
        if i < 0 and label == b'':
            i = j
        j += 1
    if total > 255:
        raise NameTooLong
    if i >= 0 and i != l - 1:
        raise EmptyLabel


def _ensure_bytes(label):
    if isinstance(label, binary_type):
        return label
    if isinstance(label, text_type):
        return label.encode()
    raise ValueError


class Name(object):

    """A DNS name.

    The dns.name.Name class represents a DNS name as a tuple of labels.
    Instances of the class are immutable.

    @ivar labels: The tuple of labels in the name. Each label is a string of
    up to 63 octets."""

    __slots__ = ['labels']

    def __init__(self, labels):
        """Initialize a domain name from a list of labels.
        @param labels: the labels
        @type labels: any iterable whose values are strings
        """
        labels = [_ensure_bytes(x) for x in labels]
        super(Name, self).__setattr__('labels', tuple(labels))
        _validate_labels(self.labels)

    def __setattr__(self, name, value):
        raise TypeError("object doesn't support attribute assignment")

    def __copy__(self):
        return Name(self.labels)

    def __deepcopy__(self, memo):
        return Name(copy.deepcopy(self.labels, memo))

    def __getstate__(self):
        return {'labels': self.labels}

    def __setstate__(self, state):
        super(Name, self).__setattr__('labels', state['labels'])
        _validate_labels(self.labels)

    def is_absolute(self):
        """Is the most significant label of this name the root label?
        @rtype: bool
        """

        return len(self.labels) > 0 and self.labels[-1] == b''

    def is_wild(self):
        """Is this name wild?  (I.e. Is the least significant label '*'?)
        @rtype: bool
        """

        return len(self.labels) > 0 and self.labels[0] == b'*'

    def __hash__(self):
        """Return a case-insensitive hash of the name.
        @rtype: int
        """

        h = long(0)
        for label in self.labels:
            for c in bytearray(label.lower()):
                h += (h << 3) + c
        return int(h % maxint)

    def fullcompare(self, other):
        """Compare two names, returning a 3-tuple (relation, order, nlabels).

        I{relation} describes the relation ship between the names,
        and is one of: dns.name.NAMERELN_NONE,
        dns.name.NAMERELN_SUPERDOMAIN, dns.name.NAMERELN_SUBDOMAIN,
        dns.name.NAMERELN_EQUAL, or dns.name.NAMERELN_COMMONANCESTOR

        I{order} is < 0 if self < other, > 0 if self > other, and ==
        0 if self == other.  A relative name is always less than an
        absolute name.  If both names have the same relativity, then
        the DNSSEC order relation is used to order them.

        I{nlabels} is the number of significant labels that the two names
        have in common.
        """

        sabs = self.is_absolute()
        oabs = other.is_absolute()
        if sabs != oabs:
            if sabs:
                return (NAMERELN_NONE, 1, 0)
            else:
                return (NAMERELN_NONE, -1, 0)
        l1 = len(self.labels)
        l2 = len(other.labels)
        ldiff = l1 - l2
        if ldiff < 0:
            l = l1
        else:
            l = l2

        order = 0
        nlabels = 0
        namereln = NAMERELN_NONE
        while l > 0:
            l -= 1
            l1 -= 1
            l2 -= 1
            label1 = self.labels[l1].lower()
            label2 = other.labels[l2].lower()
            if label1 < label2:
                order = -1
                if nlabels > 0:
                    namereln = NAMERELN_COMMONANCESTOR
                return (namereln, order, nlabels)
            elif label1 > label2:
                order = 1
                if nlabels > 0:
                    namereln = NAMERELN_COMMONANCESTOR
                return (namereln, order, nlabels)
            nlabels += 1
        order = ldiff
        if ldiff < 0:
            namereln = NAMERELN_SUPERDOMAIN
        elif ldiff > 0:
            namereln = NAMERELN_SUBDOMAIN
        else:
            namereln = NAMERELN_EQUAL
        return (namereln, order, nlabels)

    def is_subdomain(self, other):
        """Is self a subdomain of other?

        The notion of subdomain includes equality.
        @rtype: bool
        """

        (nr, o, nl) = self.fullcompare(other)
        if nr == NAMERELN_SUBDOMAIN or nr == NAMERELN_EQUAL:
            return True
        return False

    def is_superdomain(self, other):
        """Is self a superdomain of other?

        The notion of subdomain includes equality.
        @rtype: bool
        """

        (nr, o, nl) = self.fullcompare(other)
        if nr == NAMERELN_SUPERDOMAIN or nr == NAMERELN_EQUAL:
            return True
        return False

    def canonicalize(self):
        """Return a name which is equal to the current name, but is in
        DNSSEC canonical form.
        @rtype: dns.name.Name object
        """

        return Name([x.lower() for x in self.labels])

    def __eq__(self, other):
        if isinstance(other, Name):
            return self.fullcompare(other)[1] == 0
        else:
            return False

    def __ne__(self, other):
        if isinstance(other, Name):
            return self.fullcompare(other)[1] != 0
        else:
            return True

    def __lt__(self, other):
        if isinstance(other, Name):
            return self.fullcompare(other)[1] < 0
        else:
            return NotImplemented

    def __le__(self, other):
        if isinstance(other, Name):
            return self.fullcompare(other)[1] <= 0
        else:
            return NotImplemented

    def __ge__(self, other):
        if isinstance(other, Name):
            return self.fullcompare(other)[1] >= 0
        else:
            return NotImplemented

    def __gt__(self, other):
        if isinstance(other, Name):
            return self.fullcompare(other)[1] > 0
        else:
            return NotImplemented

    def __repr__(self):
        return '<DNS name ' + self.__str__() + '>'

    def __str__(self):
        return self.to_text(False)

    def to_text(self, omit_final_dot=False):
        """Convert name to text format.
        @param omit_final_dot: If True, don't emit the final dot (denoting the
        root label) for absolute names.  The default is False.
        @rtype: string
        """

        if len(self.labels) == 0:
            return maybe_decode(b'@')
        if len(self.labels) == 1 and self.labels[0] == b'':
            return maybe_decode(b'.')
        if omit_final_dot and self.is_absolute():
            l = self.labels[:-1]
        else:
            l = self.labels
        s = '.'.join(map(_escapify, l))
        return s

    def to_unicode(self, omit_final_dot=False, idna_codec=None):
        """Convert name to Unicode text format.

        IDN ACE labels are converted to Unicode.

        @param omit_final_dot: If True, don't emit the final dot (denoting the
        root label) for absolute names.  The default is False.
        @type omit_final_dot: bool
        @param idna_codec: IDNA encoder/decoder.  If None, the
        IDNA_2003_Practical encoder/decoder is used.  The IDNA_2003_Practical
        decoder does not impose any policy, it just decodes punycode, so if
        you don't want checking for compliance, you can use this decoder for
        IDNA2008 as well.
        @type idna_codec: dns.name.IDNA
        @rtype: string
        """

        if len(self.labels) == 0:
            return u'@'
        if len(self.labels) == 1 and self.labels[0] == b'':
            return u'.'
        if omit_final_dot and self.is_absolute():
            l = self.labels[:-1]
        else:
            l = self.labels
        if idna_codec is None:
            idna_codec = IDNA_2003_Practical
        return u'.'.join([idna_codec.decode(x) for x in l])

    def to_digestable(self, origin=None):
        """Convert name to a format suitable for digesting in hashes.

        The name is canonicalized and converted to uncompressed wire format.

        @param origin: If the name is relative and origin is not None, then
        origin will be appended to it.
        @type origin: dns.name.Name object
        @raises NeedAbsoluteNameOrOrigin: All names in wire format are
        absolute.  If self is a relative name, then an origin must be supplied;
        if it is missing, then this exception is raised
        @rtype: string
        """

        if not self.is_absolute():
            if origin is None or not origin.is_absolute():
                raise NeedAbsoluteNameOrOrigin
            labels = list(self.labels)
            labels.extend(list(origin.labels))
        else:
            labels = self.labels
        dlabels = [struct.pack('!B%ds' % len(x), len(x), x.lower())
                   for x in labels]
        return b''.join(dlabels)

    def to_wire(self, file=None, compress=None, origin=None):
        """Convert name to wire format, possibly compressing it.

        @param file: the file where the name is emitted (typically
        a BytesIO file).  If None, a string containing the wire name
        will be returned.
        @type file: file or None
        @param compress: The compression table.  If None (the default) names
        will not be compressed.
        @type compress: dict
        @param origin: If the name is relative and origin is not None, then
        origin will be appended to it.
        @type origin: dns.name.Name object
        @raises NeedAbsoluteNameOrOrigin: All names in wire format are
        absolute.  If self is a relative name, then an origin must be supplied;
        if it is missing, then this exception is raised
        """

        if file is None:
            file = BytesIO()
            want_return = True
        else:
            want_return = False

        if not self.is_absolute():
            if origin is None or not origin.is_absolute():
                raise NeedAbsoluteNameOrOrigin
            labels = list(self.labels)
            labels.extend(list(origin.labels))
        else:
            labels = self.labels
        i = 0
        for label in labels:
            n = Name(labels[i:])
            i += 1
            if compress is not None:
                pos = compress.get(n)
            else:
                pos = None
            if pos is not None:
                value = 0xc000 + pos
                s = struct.pack('!H', value)
                file.write(s)
                break
            else:
                if compress is not None and len(n) > 1:
                    pos = file.tell()
                    if pos <= 0x3fff:
                        compress[n] = pos
                l = len(label)
                file.write(struct.pack('!B', l))
                if l > 0:
                    file.write(label)
        if want_return:
            return file.getvalue()

    def __len__(self):
        """The length of the name (in labels).
        @rtype: int
        """

        return len(self.labels)

    def __getitem__(self, index):
        return self.labels[index]

    def __add__(self, other):
        return self.concatenate(other)

    def __sub__(self, other):
        return self.relativize(other)

    def split(self, depth):
        """Split a name into a prefix and suffix at depth.

        @param depth: the number of labels in the suffix
        @type depth: int
        @raises ValueError: the depth was not >= 0 and <= the length of the
        name.
        @returns: the tuple (prefix, suffix)
        @rtype: tuple
        """

        l = len(self.labels)
        if depth == 0:
            return (self, dns.name.empty)
        elif depth == l:
            return (dns.name.empty, self)
        elif depth < 0 or depth > l:
            raise ValueError(
                'depth must be >= 0 and <= the length of the name')
        return (Name(self[: -depth]), Name(self[-depth:]))

    def concatenate(self, other):
        """Return a new name which is the concatenation of self and other.
        @rtype: dns.name.Name object
        @raises AbsoluteConcatenation: self is absolute and other is
        not the empty name
        """

        if self.is_absolute() and len(other) > 0:
            raise AbsoluteConcatenation
        labels = list(self.labels)
        labels.extend(list(other.labels))
        return Name(labels)

    def relativize(self, origin):
        """If self is a subdomain of origin, return a new name which is self
        relative to origin.  Otherwise return self.
        @rtype: dns.name.Name object
        """

        if origin is not None and self.is_subdomain(origin):
            return Name(self[: -len(origin)])
        else:
            return self

    def derelativize(self, origin):
        """If self is a relative name, return a new name which is the
        concatenation of self and origin.  Otherwise return self.
        @rtype: dns.name.Name object
        """

        if not self.is_absolute():
            return self.concatenate(origin)
        else:
            return self

    def choose_relativity(self, origin=None, relativize=True):
        """Return a name with the relativity desired by the caller.  If
        origin is None, then self is returned.  Otherwise, if
        relativize is true the name is relativized, and if relativize is
        false the name is derelativized.
        @rtype: dns.name.Name object
        """

        if origin:
            if relativize:
                return self.relativize(origin)
            else:
                return self.derelativize(origin)
        else:
            return self

    def parent(self):
        """Return the parent of the name.
        @rtype: dns.name.Name object
        @raises NoParent: the name is either the root name or the empty name,
        and thus has no parent.
        """
        if self == root or self == empty:
            raise NoParent
        return Name(self.labels[1:])

root = Name([b''])
empty = Name([])


def from_unicode(text, origin=root, idna_codec=None):
    """Convert unicode text into a Name object.

    Labels are encoded in IDN ACE form.

    @param text: The text to convert into a name.
    @type text: Unicode string
    @param origin: The origin to append to non-absolute names.
    @type origin: dns.name.Name
    @param idna_codec: IDNA encoder/decoder.  If None, the default IDNA 2003
    encoder/decoder is used.
    @type idna_codec: dns.name.IDNA
    @rtype: dns.name.Name object
    """

    if not isinstance(text, text_type):
        raise ValueError("input to from_unicode() must be a unicode string")
    if not (origin is None or isinstance(origin, Name)):
        raise ValueError("origin must be a Name or None")
    labels = []
    label = u''
    escaping = False
    edigits = 0
    total = 0
    if idna_codec is None:
        idna_codec = IDNA_2003
    if text == u'@':
        text = u''
    if text:
        if text == u'.':
            return Name([b''])        # no Unicode "u" on this constant!
        for c in text:
            if escaping:
                if edigits == 0:
                    if c.isdigit():
                        total = int(c)
                        edigits += 1
                    else:
                        label += c
                        escaping = False
                else:
                    if not c.isdigit():
                        raise BadEscape
                    total *= 10
                    total += int(c)
                    edigits += 1
                    if edigits == 3:
                        escaping = False
                        label += unichr(total)
            elif c in [u'.', u'\u3002', u'\uff0e', u'\uff61']:
                if len(label) == 0:
                    raise EmptyLabel
                labels.append(idna_codec.encode(label))
                label = u''
            elif c == u'\\':
                escaping = True
                edigits = 0
                total = 0
            else:
                label += c
        if escaping:
            raise BadEscape
        if len(label) > 0:
            labels.append(idna_codec.encode(label))
        else:
            labels.append(b'')

    if (len(labels) == 0 or labels[-1] != b'') and origin is not None:
        labels.extend(list(origin.labels))
    return Name(labels)


def from_text(text, origin=root, idna_codec=None):
    """Convert text into a Name object.

    @param text: The text to convert into a name.
    @type text: string
    @param origin: The origin to append to non-absolute names.
    @type origin: dns.name.Name
    @param idna_codec: IDNA encoder/decoder.  If None, the default IDNA 2003
    encoder/decoder is used.
    @type idna_codec: dns.name.IDNA
    @rtype: dns.name.Name object
    """

    if isinstance(text, text_type):
        return from_unicode(text, origin, idna_codec)
    if not isinstance(text, binary_type):
        raise ValueError("input to from_text() must be a string")
    if not (origin is None or isinstance(origin, Name)):
        raise ValueError("origin must be a Name or None")
    labels = []
    label = b''
    escaping = False
    edigits = 0
    total = 0
    if text == b'@':
        text = b''
    if text:
        if text == b'.':
            return Name([b''])
        for c in bytearray(text):
            byte_ = struct.pack('!B', c)
            if escaping:
                if edigits == 0:
                    if byte_.isdigit():
                        total = int(byte_)
                        edigits += 1
                    else:
                        label += byte_
                        escaping = False
                else:
                    if not byte_.isdigit():
                        raise BadEscape
                    total *= 10
                    total += int(byte_)
                    edigits += 1
                    if edigits == 3:
                        escaping = False
                        label += struct.pack('!B', total)
            elif byte_ == b'.':
                if len(label) == 0:
                    raise EmptyLabel
                labels.append(label)
                label = b''
            elif byte_ == b'\\':
                escaping = True
                edigits = 0
                total = 0
            else:
                label += byte_
        if escaping:
            raise BadEscape
        if len(label) > 0:
            labels.append(label)
        else:
            labels.append(b'')
    if (len(labels) == 0 or labels[-1] != b'') and origin is not None:
        labels.extend(list(origin.labels))
    return Name(labels)


def from_wire(message, current):
    """Convert possibly compressed wire format into a Name.
    @param message: the entire DNS message
    @type message: string
    @param current: the offset of the beginning of the name from the start
    of the message
    @type current: int
    @raises dns.name.BadPointer: a compression pointer did not point backwards
    in the message
    @raises dns.name.BadLabelType: an invalid label type was encountered.
    @returns: a tuple consisting of the name that was read and the number
    of bytes of the wire format message which were consumed reading it
    @rtype: (dns.name.Name object, int) tuple
    """

    if not isinstance(message, binary_type):
        raise ValueError("input to from_wire() must be a byte string")
    message = dns.wiredata.maybe_wrap(message)
    labels = []
    biggest_pointer = current
    hops = 0
    count = message[current]
    current += 1
    cused = 1
    while count != 0:
        if count < 64:
            labels.append(message[current: current + count].unwrap())
            current += count
            if hops == 0:
                cused += count
        elif count >= 192:
            current = (count & 0x3f) * 256 + message[current]
            if hops == 0:
                cused += 1
            if current >= biggest_pointer:
                raise BadPointer
            biggest_pointer = current
            hops += 1
        else:
            raise BadLabelType
        count = message[current]
        current += 1
        if hops == 0:
            cused += 1
    labels.append('')
    return (Name(labels), cused)
PKk�\�X2��reversename.pynu�[���# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Reverse Map Names.

@var ipv4_reverse_domain: The DNS IPv4 reverse-map domain, in-addr.arpa.
@type ipv4_reverse_domain: dns.name.Name object
@var ipv6_reverse_domain: The DNS IPv6 reverse-map domain, ip6.arpa.
@type ipv6_reverse_domain: dns.name.Name object
"""

import binascii
import sys

import dns.name
import dns.ipv6
import dns.ipv4

ipv4_reverse_domain = dns.name.from_text('in-addr.arpa.')
ipv6_reverse_domain = dns.name.from_text('ip6.arpa.')


def from_address(text):
    """Convert an IPv4 or IPv6 address in textual form into a Name object whose
    value is the reverse-map domain name of the address.
    @param text: an IPv4 or IPv6 address in textual form (e.g. '127.0.0.1',
    '::1')
    @type text: str
    @rtype: dns.name.Name object
    """
    try:
        v6 = dns.ipv6.inet_aton(text)
        if dns.ipv6.is_mapped(v6):
            if sys.version_info >= (3,):
                parts = ['%d' % byte for byte in v6[12:]]
            else:
                parts = ['%d' % ord(byte) for byte in v6[12:]]
            origin = ipv4_reverse_domain
        else:
            parts = [x for x in str(binascii.hexlify(v6).decode())]
            origin = ipv6_reverse_domain
    except Exception:
        parts = ['%d' %
                 byte for byte in bytearray(dns.ipv4.inet_aton(text))]
        origin = ipv4_reverse_domain
    parts.reverse()
    return dns.name.from_text('.'.join(parts), origin=origin)


def to_address(name):
    """Convert a reverse map domain name into textual address form.
    @param name: an IPv4 or IPv6 address in reverse-map form.
    @type name: dns.name.Name object
    @rtype: str
    """
    if name.is_subdomain(ipv4_reverse_domain):
        name = name.relativize(ipv4_reverse_domain)
        labels = list(name.labels)
        labels.reverse()
        text = b'.'.join(labels)
        # run through inet_aton() to check syntax and make pretty.
        return dns.ipv4.inet_ntoa(dns.ipv4.inet_aton(text))
    elif name.is_subdomain(ipv6_reverse_domain):
        name = name.relativize(ipv6_reverse_domain)
        labels = list(name.labels)
        labels.reverse()
        parts = []
        i = 0
        l = len(labels)
        while i < l:
            parts.append(b''.join(labels[i:i + 4]))
            i += 4
        text = b':'.join(parts)
        # run through inet_aton() to check syntax and make pretty.
        return dns.ipv6.inet_ntoa(dns.ipv6.inet_aton(text))
    else:
        raise dns.exception.SyntaxError('unknown reverse-map address family')
PKk�\ų4�h
h
flags.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Message Flags."""

# Standard DNS flags

QR = 0x8000
AA = 0x0400
TC = 0x0200
RD = 0x0100
RA = 0x0080
AD = 0x0020
CD = 0x0010

# EDNS flags

DO = 0x8000

_by_text = {
    'QR': QR,
    'AA': AA,
    'TC': TC,
    'RD': RD,
    'RA': RA,
    'AD': AD,
    'CD': CD
}

_edns_by_text = {
    'DO': DO
}


# We construct the inverse mappings programmatically to ensure that we
# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
# would cause the mappings not to be true inverses.

_by_value = dict((y, x) for x, y in _by_text.items())

_edns_by_value = dict((y, x) for x, y in _edns_by_text.items())


def _order_flags(table):
    order = list(table.items())
    order.sort()
    order.reverse()
    return order

_flags_order = _order_flags(_by_value)

_edns_flags_order = _order_flags(_edns_by_value)


def _from_text(text, table):
    flags = 0
    tokens = text.split()
    for t in tokens:
        flags = flags | table[t.upper()]
    return flags


def _to_text(flags, table, order):
    text_flags = []
    for k, v in order:
        if flags & k != 0:
            text_flags.append(v)
    return ' '.join(text_flags)


def from_text(text):
    """Convert a space-separated list of flag text values into a flags
    value.
    @rtype: int"""

    return _from_text(text, _by_text)


def to_text(flags):
    """Convert a flags value into a space-separated list of flag text
    values.
    @rtype: string"""

    return _to_text(flags, _by_value, _flags_order)


def edns_from_text(text):
    """Convert a space-separated list of EDNS flag text values into a EDNS
    flags value.
    @rtype: int"""

    return _from_text(text, _edns_by_text)


def edns_to_text(flags):
    """Convert an EDNS flags value into a space-separated list of EDNS flag
    text values.
    @rtype: string"""

    return _to_text(flags, _edns_by_value, _edns_flags_order)
PKk�\������
rdataclass.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Rdata Classes.

@var _by_text: The rdata class textual name to value mapping
@type _by_text: dict
@var _by_value: The rdata class value to textual name mapping
@type _by_value: dict
@var _metaclasses: If an rdataclass is a metaclass, there will be a mapping
whose key is the rdatatype value and whose value is True in this dictionary.
@type _metaclasses: dict"""

import re

import dns.exception

RESERVED0 = 0
IN = 1
CH = 3
HS = 4
NONE = 254
ANY = 255

_by_text = {
    'RESERVED0': RESERVED0,
    'IN': IN,
    'CH': CH,
    'HS': HS,
    'NONE': NONE,
    'ANY': ANY
}

# We construct the inverse mapping programmatically to ensure that we
# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
# would cause the mapping not to be true inverse.

_by_value = dict((y, x) for x, y in _by_text.items())

# Now that we've built the inverse map, we can add class aliases to
# the _by_text mapping.

_by_text.update({
    'INTERNET': IN,
    'CHAOS': CH,
    'HESIOD': HS
})

_metaclasses = {
    NONE: True,
    ANY: True
}

_unknown_class_pattern = re.compile('CLASS([0-9]+)$', re.I)


class UnknownRdataclass(dns.exception.DNSException):

    """A DNS class is unknown."""


def from_text(text):
    """Convert text into a DNS rdata class value.
    @param text: the text
    @type text: string
    @rtype: int
    @raises dns.rdataclass.UnknownRdataclass: the class is unknown
    @raises ValueError: the rdata class value is not >= 0 and <= 65535
    """

    value = _by_text.get(text.upper())
    if value is None:
        match = _unknown_class_pattern.match(text)
        if match is None:
            raise UnknownRdataclass
        value = int(match.group(1))
        if value < 0 or value > 65535:
            raise ValueError("class must be between >= 0 and <= 65535")
    return value


def to_text(value):
    """Convert a DNS rdata class to text.
    @param value: the rdata class value
    @type value: int
    @rtype: string
    @raises ValueError: the rdata class value is not >= 0 and <= 65535
    """

    if value < 0 or value > 65535:
        raise ValueError("class must be between >= 0 and <= 65535")
    text = _by_value.get(value)
    if text is None:
        text = 'CLASS' + repr(value)
    return text


def is_metaclass(rdclass):
    """True if the class is a metaclass.
    @param rdclass: the rdata class
    @type rdclass: int
    @rtype: bool"""

    if rdclass in _metaclasses:
        return True
    return False
PKk�\D��|Z�Z�zone.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Zones."""

from __future__ import generators

import sys
import re
import os
from io import BytesIO

import dns.exception
import dns.name
import dns.node
import dns.rdataclass
import dns.rdatatype
import dns.rdata
import dns.rrset
import dns.tokenizer
import dns.ttl
import dns.grange
from ._compat import string_types, text_type


_py3 = sys.version_info > (3,)


class BadZone(dns.exception.DNSException):

    """The DNS zone is malformed."""


class NoSOA(BadZone):

    """The DNS zone has no SOA RR at its origin."""


class NoNS(BadZone):

    """The DNS zone has no NS RRset at its origin."""


class UnknownOrigin(BadZone):

    """The DNS zone's origin is unknown."""


class Zone(object):

    """A DNS zone.

    A Zone is a mapping from names to nodes.  The zone object may be
    treated like a Python dictionary, e.g. zone[name] will retrieve
    the node associated with that name.  The I{name} may be a
    dns.name.Name object, or it may be a string.  In the either case,
    if the name is relative it is treated as relative to the origin of
    the zone.

    @ivar rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @ivar origin: The origin of the zone.
    @type origin: dns.name.Name object
    @ivar nodes: A dictionary mapping the names of nodes in the zone to the
    nodes themselves.
    @type nodes: dict
    @ivar relativize: should names in the zone be relativized?
    @type relativize: bool
    @cvar node_factory: the factory used to create a new node
    @type node_factory: class or callable
    """

    node_factory = dns.node.Node

    __slots__ = ['rdclass', 'origin', 'nodes', 'relativize']

    def __init__(self, origin, rdclass=dns.rdataclass.IN, relativize=True):
        """Initialize a zone object.

        @param origin: The origin of the zone.
        @type origin: dns.name.Name object
        @param rdclass: The zone's rdata class; the default is class IN.
        @type rdclass: int"""

        if origin is not None:
            if isinstance(origin, string_types):
                origin = dns.name.from_text(origin)
            elif not isinstance(origin, dns.name.Name):
                raise ValueError("origin parameter must be convertible to a "
                                 "DNS name")
            if not origin.is_absolute():
                raise ValueError("origin parameter must be an absolute name")
        self.origin = origin
        self.rdclass = rdclass
        self.nodes = {}
        self.relativize = relativize

    def __eq__(self, other):
        """Two zones are equal if they have the same origin, class, and
        nodes.
        @rtype: bool
        """

        if not isinstance(other, Zone):
            return False
        if self.rdclass != other.rdclass or \
           self.origin != other.origin or \
           self.nodes != other.nodes:
            return False
        return True

    def __ne__(self, other):
        """Are two zones not equal?
        @rtype: bool
        """

        return not self.__eq__(other)

    def _validate_name(self, name):
        if isinstance(name, string_types):
            name = dns.name.from_text(name, None)
        elif not isinstance(name, dns.name.Name):
            raise KeyError("name parameter must be convertible to a DNS name")
        if name.is_absolute():
            if not name.is_subdomain(self.origin):
                raise KeyError(
                    "name parameter must be a subdomain of the zone origin")
            if self.relativize:
                name = name.relativize(self.origin)
        return name

    def __getitem__(self, key):
        key = self._validate_name(key)
        return self.nodes[key]

    def __setitem__(self, key, value):
        key = self._validate_name(key)
        self.nodes[key] = value

    def __delitem__(self, key):
        key = self._validate_name(key)
        del self.nodes[key]

    def __iter__(self):
        return self.nodes.__iter__()

    def iterkeys(self):
        if _py3:
            return self.nodes.keys()
        else:
            return self.nodes.iterkeys()  # pylint: disable=dict-iter-method

    def keys(self):
        return self.nodes.keys()

    def itervalues(self):
        if _py3:
            return self.nodes.values()
        else:
            return self.nodes.itervalues()  # pylint: disable=dict-iter-method

    def values(self):
        return self.nodes.values()

    def items(self):
        return self.nodes.items()

    iteritems = items

    def get(self, key):
        key = self._validate_name(key)
        return self.nodes.get(key)

    def __contains__(self, other):
        return other in self.nodes

    def find_node(self, name, create=False):
        """Find a node in the zone, possibly creating it.

        @param name: the name of the node to find
        @type name: dns.name.Name object or string
        @param create: should the node be created if it doesn't exist?
        @type create: bool
        @raises KeyError: the name is not known and create was not specified.
        @rtype: dns.node.Node object
        """

        name = self._validate_name(name)
        node = self.nodes.get(name)
        if node is None:
            if not create:
                raise KeyError
            node = self.node_factory()
            self.nodes[name] = node
        return node

    def get_node(self, name, create=False):
        """Get a node in the zone, possibly creating it.

        This method is like L{find_node}, except it returns None instead
        of raising an exception if the node does not exist and creation
        has not been requested.

        @param name: the name of the node to find
        @type name: dns.name.Name object or string
        @param create: should the node be created if it doesn't exist?
        @type create: bool
        @rtype: dns.node.Node object or None
        """

        try:
            node = self.find_node(name, create)
        except KeyError:
            node = None
        return node

    def delete_node(self, name):
        """Delete the specified node if it exists.

        It is not an error if the node does not exist.
        """

        name = self._validate_name(name)
        if name in self.nodes:
            del self.nodes[name]

    def find_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE,
                      create=False):
        """Look for rdata with the specified name and type in the zone,
        and return an rdataset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        The rdataset returned is not a copy; changes to it will change
        the zone.

        KeyError is raised if the name or type are not found.
        Use L{get_rdataset} if you want to have None returned instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @param create: should the node and rdataset be created if they do not
        exist?
        @type create: bool
        @raises KeyError: the node or rdata could not be found
        @rtype: dns.rrset.RRset object
        """

        name = self._validate_name(name)
        if isinstance(rdtype, string_types):
            rdtype = dns.rdatatype.from_text(rdtype)
        if isinstance(covers, string_types):
            covers = dns.rdatatype.from_text(covers)
        node = self.find_node(name, create)
        return node.find_rdataset(self.rdclass, rdtype, covers, create)

    def get_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE,
                     create=False):
        """Look for rdata with the specified name and type in the zone,
        and return an rdataset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        The rdataset returned is not a copy; changes to it will change
        the zone.

        None is returned if the name or type are not found.
        Use L{find_rdataset} if you want to have KeyError raised instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @param create: should the node and rdataset be created if they do not
        exist?
        @type create: bool
        @rtype: dns.rrset.RRset object
        """

        try:
            rdataset = self.find_rdataset(name, rdtype, covers, create)
        except KeyError:
            rdataset = None
        return rdataset

    def delete_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE):
        """Delete the rdataset matching I{rdtype} and I{covers}, if it
        exists at the node specified by I{name}.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        It is not an error if the node does not exist, or if there is no
        matching rdataset at the node.

        If the node has no rdatasets after the deletion, it will itself
        be deleted.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        """

        name = self._validate_name(name)
        if isinstance(rdtype, string_types):
            rdtype = dns.rdatatype.from_text(rdtype)
        if isinstance(covers, string_types):
            covers = dns.rdatatype.from_text(covers)
        node = self.get_node(name)
        if node is not None:
            node.delete_rdataset(self.rdclass, rdtype, covers)
            if len(node) == 0:
                self.delete_node(name)

    def replace_rdataset(self, name, replacement):
        """Replace an rdataset at name.

        It is not an error if there is no rdataset matching I{replacement}.

        Ownership of the I{replacement} object is transferred to the zone;
        in other words, this method does not store a copy of I{replacement}
        at the node, it stores I{replacement} itself.

        If the I{name} node does not exist, it is created.

        @param name: the owner name
        @type name: DNS.name.Name object or string
        @param replacement: the replacement rdataset
        @type replacement: dns.rdataset.Rdataset
        """

        if replacement.rdclass != self.rdclass:
            raise ValueError('replacement.rdclass != zone.rdclass')
        node = self.find_node(name, True)
        node.replace_rdataset(replacement)

    def find_rrset(self, name, rdtype, covers=dns.rdatatype.NONE):
        """Look for rdata with the specified name and type in the zone,
        and return an RRset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        This method is less efficient than the similar
        L{find_rdataset} because it creates an RRset instead of
        returning the matching rdataset.  It may be more convenient
        for some uses since it returns an object which binds the owner
        name to the rdata.

        This method may not be used to create new nodes or rdatasets;
        use L{find_rdataset} instead.

        KeyError is raised if the name or type are not found.
        Use L{get_rrset} if you want to have None returned instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @raises KeyError: the node or rdata could not be found
        @rtype: dns.rrset.RRset object
        """

        name = self._validate_name(name)
        if isinstance(rdtype, string_types):
            rdtype = dns.rdatatype.from_text(rdtype)
        if isinstance(covers, string_types):
            covers = dns.rdatatype.from_text(covers)
        rdataset = self.nodes[name].find_rdataset(self.rdclass, rdtype, covers)
        rrset = dns.rrset.RRset(name, self.rdclass, rdtype, covers)
        rrset.update(rdataset)
        return rrset

    def get_rrset(self, name, rdtype, covers=dns.rdatatype.NONE):
        """Look for rdata with the specified name and type in the zone,
        and return an RRset encapsulating it.

        The I{name}, I{rdtype}, and I{covers} parameters may be
        strings, in which case they will be converted to their proper
        type.

        This method is less efficient than the similar L{get_rdataset}
        because it creates an RRset instead of returning the matching
        rdataset.  It may be more convenient for some uses since it
        returns an object which binds the owner name to the rdata.

        This method may not be used to create new nodes or rdatasets;
        use L{find_rdataset} instead.

        None is returned if the name or type are not found.
        Use L{find_rrset} if you want to have KeyError raised instead.

        @param name: the owner name to look for
        @type name: DNS.name.Name object or string
        @param rdtype: the rdata type desired
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        @rtype: dns.rrset.RRset object
        """

        try:
            rrset = self.find_rrset(name, rdtype, covers)
        except KeyError:
            rrset = None
        return rrset

    def iterate_rdatasets(self, rdtype=dns.rdatatype.ANY,
                          covers=dns.rdatatype.NONE):
        """Return a generator which yields (name, rdataset) tuples for
        all rdatasets in the zone which have the specified I{rdtype}
        and I{covers}.  If I{rdtype} is dns.rdatatype.ANY, the default,
        then all rdatasets will be matched.

        @param rdtype: int or string
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        """

        if isinstance(rdtype, string_types):
            rdtype = dns.rdatatype.from_text(rdtype)
        if isinstance(covers, string_types):
            covers = dns.rdatatype.from_text(covers)
        for (name, node) in self.iteritems():
            for rds in node:
                if rdtype == dns.rdatatype.ANY or \
                   (rds.rdtype == rdtype and rds.covers == covers):
                    yield (name, rds)

    def iterate_rdatas(self, rdtype=dns.rdatatype.ANY,
                       covers=dns.rdatatype.NONE):
        """Return a generator which yields (name, ttl, rdata) tuples for
        all rdatas in the zone which have the specified I{rdtype}
        and I{covers}.  If I{rdtype} is dns.rdatatype.ANY, the default,
        then all rdatas will be matched.

        @param rdtype: int or string
        @type rdtype: int or string
        @param covers: the covered type (defaults to None)
        @type covers: int or string
        """

        if isinstance(rdtype, string_types):
            rdtype = dns.rdatatype.from_text(rdtype)
        if isinstance(covers, string_types):
            covers = dns.rdatatype.from_text(covers)
        for (name, node) in self.iteritems():
            for rds in node:
                if rdtype == dns.rdatatype.ANY or \
                   (rds.rdtype == rdtype and rds.covers == covers):
                    for rdata in rds:
                        yield (name, rds.ttl, rdata)

    def to_file(self, f, sorted=True, relativize=True, nl=None):
        """Write a zone to a file.

        @param f: file or string.  If I{f} is a string, it is treated
        as the name of a file to open.
        @param sorted: if True, the file will be written with the
        names sorted in DNSSEC order from least to greatest.  Otherwise
        the names will be written in whatever order they happen to have
        in the zone's dictionary.
        @param relativize: if True, domain names in the output will be
        relativized to the zone's origin (if possible).
        @type relativize: bool
        @param nl: The end of line string.  If not specified, the
        output will use the platform's native end-of-line marker (i.e.
        LF on POSIX, CRLF on Windows, CR on Macintosh).
        @type nl: string or None
        """

        if isinstance(f, string_types):
            f = open(f, 'wb')
            want_close = True
        else:
            want_close = False

        # must be in this way, f.encoding may contain None, or even attribute
        # may not be there
        file_enc = getattr(f, 'encoding', None)
        if file_enc is None:
            file_enc = 'utf-8'

        if nl is None:
            nl_b = os.linesep.encode(file_enc)  # binary mode, '\n' is not enough
            nl = u'\n'
        elif isinstance(nl, string_types):
            nl_b = nl.encode(file_enc)
        else:
            nl_b = nl
            nl = nl.decode()

        try:
            if sorted:
                names = list(self.keys())
                names.sort()
            else:
                names = self.iterkeys()
            for n in names:
                l = self[n].to_text(n, origin=self.origin,
                                    relativize=relativize)
                if isinstance(l, text_type):
                    l_b = l.encode(file_enc)
                else:
                    l_b = l
                    l = l.decode()

                try:
                    f.write(l_b)
                    f.write(nl_b)
                except TypeError:  # textual mode
                    f.write(l)
                    f.write(nl)
        finally:
            if want_close:
                f.close()

    def to_text(self, sorted=True, relativize=True, nl=None):
        """Return a zone's text as though it were written to a file.

        @param sorted: if True, the file will be written with the
        names sorted in DNSSEC order from least to greatest.  Otherwise
        the names will be written in whatever order they happen to have
        in the zone's dictionary.
        @param relativize: if True, domain names in the output will be
        relativized to the zone's origin (if possible).
        @type relativize: bool
        @param nl: The end of line string.  If not specified, the
        output will use the platform's native end-of-line marker (i.e.
        LF on POSIX, CRLF on Windows, CR on Macintosh).
        @type nl: string or None
        """
        temp_buffer = BytesIO()
        self.to_file(temp_buffer, sorted, relativize, nl)
        return_value = temp_buffer.getvalue()
        temp_buffer.close()
        return return_value

    def check_origin(self):
        """Do some simple checking of the zone's origin.

        @raises dns.zone.NoSOA: there is no SOA RR
        @raises dns.zone.NoNS: there is no NS RRset
        @raises KeyError: there is no origin node
        """
        if self.relativize:
            name = dns.name.empty
        else:
            name = self.origin
        if self.get_rdataset(name, dns.rdatatype.SOA) is None:
            raise NoSOA
        if self.get_rdataset(name, dns.rdatatype.NS) is None:
            raise NoNS


class _MasterReader(object):

    """Read a DNS master file

    @ivar tok: The tokenizer
    @type tok: dns.tokenizer.Tokenizer object
    @ivar ttl: The default TTL
    @type ttl: int
    @ivar last_name: The last name read
    @type last_name: dns.name.Name object
    @ivar current_origin: The current origin
    @type current_origin: dns.name.Name object
    @ivar relativize: should names in the zone be relativized?
    @type relativize: bool
    @ivar zone: the zone
    @type zone: dns.zone.Zone object
    @ivar saved_state: saved reader state (used when processing $INCLUDE)
    @type saved_state: list of (tokenizer, current_origin, last_name, file)
    tuples.
    @ivar current_file: the file object of the $INCLUDed file being parsed
    (None if no $INCLUDE is active).
    @ivar allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @ivar check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    """

    def __init__(self, tok, origin, rdclass, relativize, zone_factory=Zone,
                 allow_include=False, check_origin=True):
        if isinstance(origin, string_types):
            origin = dns.name.from_text(origin)
        self.tok = tok
        self.current_origin = origin
        self.relativize = relativize
        self.ttl = 0
        self.last_name = self.current_origin
        self.zone = zone_factory(origin, rdclass, relativize=relativize)
        self.saved_state = []
        self.current_file = None
        self.allow_include = allow_include
        self.check_origin = check_origin

    def _eat_line(self):
        while 1:
            token = self.tok.get()
            if token.is_eol_or_eof():
                break

    def _rr_line(self):
        """Process one line from a DNS master file."""
        # Name
        if self.current_origin is None:
            raise UnknownOrigin
        token = self.tok.get(want_leading=True)
        if not token.is_whitespace():
            self.last_name = dns.name.from_text(
                token.value, self.current_origin)
        else:
            token = self.tok.get()
            if token.is_eol_or_eof():
                # treat leading WS followed by EOL/EOF as if they were EOL/EOF.
                return
            self.tok.unget(token)
        name = self.last_name
        if not name.is_subdomain(self.zone.origin):
            self._eat_line()
            return
        if self.relativize:
            name = name.relativize(self.zone.origin)
        token = self.tok.get()
        if not token.is_identifier():
            raise dns.exception.SyntaxError
        # TTL
        try:
            ttl = dns.ttl.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.ttl.BadTTL:
            ttl = self.ttl
        # Class
        try:
            rdclass = dns.rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            rdclass = self.zone.rdclass
        if rdclass != self.zone.rdclass:
            raise dns.exception.SyntaxError("RR class is not zone's class")
        # Type
        try:
            rdtype = dns.rdatatype.from_text(token.value)
        except:
            raise dns.exception.SyntaxError(
                "unknown rdatatype '%s'" % token.value)
        n = self.zone.nodes.get(name)
        if n is None:
            n = self.zone.node_factory()
            self.zone.nodes[name] = n
        try:
            rd = dns.rdata.from_text(rdclass, rdtype, self.tok,
                                     self.current_origin, False)
        except dns.exception.SyntaxError:
            # Catch and reraise.
            (ty, va) = sys.exc_info()[:2]
            raise va
        except:
            # All exceptions that occur in the processing of rdata
            # are treated as syntax errors.  This is not strictly
            # correct, but it is correct almost all of the time.
            # We convert them to syntax errors so that we can emit
            # helpful filename:line info.
            (ty, va) = sys.exc_info()[:2]
            raise dns.exception.SyntaxError(
                "caught exception %s: %s" % (str(ty), str(va)))

        rd.choose_relativity(self.zone.origin, self.relativize)
        covers = rd.covers()
        rds = n.find_rdataset(rdclass, rdtype, covers, True)
        rds.add(rd, ttl)

    def _parse_modify(self, side):
        # Here we catch everything in '{' '}' in a group so we can replace it
        # with ''.
        is_generate1 = re.compile("^.*\$({(\+|-?)(\d+),(\d+),(.)}).*$")
        is_generate2 = re.compile("^.*\$({(\+|-?)(\d+)}).*$")
        is_generate3 = re.compile("^.*\$({(\+|-?)(\d+),(\d+)}).*$")
        # Sometimes there are modifiers in the hostname. These come after
        # the dollar sign. They are in the form: ${offset[,width[,base]]}.
        # Make names
        g1 = is_generate1.match(side)
        if g1:
            mod, sign, offset, width, base = g1.groups()
            if sign == '':
                sign = '+'
        g2 = is_generate2.match(side)
        if g2:
            mod, sign, offset = g2.groups()
            if sign == '':
                sign = '+'
            width = 0
            base = 'd'
        g3 = is_generate3.match(side)
        if g3:
            mod, sign, offset, width = g1.groups()
            if sign == '':
                sign = '+'
            width = g1.groups()[2]
            base = 'd'

        if not (g1 or g2 or g3):
            mod = ''
            sign = '+'
            offset = 0
            width = 0
            base = 'd'

        if base != 'd':
            raise NotImplementedError()

        return mod, sign, offset, width, base

    def _generate_line(self):
        # range lhs [ttl] [class] type rhs [ comment ]
        """Process one line containing the GENERATE statement from a DNS
        master file."""
        if self.current_origin is None:
            raise UnknownOrigin

        token = self.tok.get()
        # Range (required)
        try:
            start, stop, step = dns.grange.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except:
            raise dns.exception.SyntaxError

        # lhs (required)
        try:
            lhs = token.value
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except:
            raise dns.exception.SyntaxError

        # TTL
        try:
            ttl = dns.ttl.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.ttl.BadTTL:
            ttl = self.ttl
        # Class
        try:
            rdclass = dns.rdataclass.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except dns.exception.SyntaxError:
            raise dns.exception.SyntaxError
        except Exception:
            rdclass = self.zone.rdclass
        if rdclass != self.zone.rdclass:
            raise dns.exception.SyntaxError("RR class is not zone's class")
        # Type
        try:
            rdtype = dns.rdatatype.from_text(token.value)
            token = self.tok.get()
            if not token.is_identifier():
                raise dns.exception.SyntaxError
        except Exception:
            raise dns.exception.SyntaxError("unknown rdatatype '%s'" %
                                            token.value)

        # lhs (required)
        try:
            rhs = token.value
        except:
            raise dns.exception.SyntaxError

        lmod, lsign, loffset, lwidth, lbase = self._parse_modify(lhs)
        rmod, rsign, roffset, rwidth, rbase = self._parse_modify(rhs)
        for i in range(start, stop + 1, step):
            # +1 because bind is inclusive and python is exclusive

            if lsign == u'+':
                lindex = i + int(loffset)
            elif lsign == u'-':
                lindex = i - int(loffset)

            if rsign == u'-':
                rindex = i - int(roffset)
            elif rsign == u'+':
                rindex = i + int(roffset)

            lzfindex = str(lindex).zfill(int(lwidth))
            rzfindex = str(rindex).zfill(int(rwidth))

            name = lhs.replace(u'$%s' % (lmod), lzfindex)
            rdata = rhs.replace(u'$%s' % (rmod), rzfindex)

            self.last_name = dns.name.from_text(name, self.current_origin)
            name = self.last_name
            if not name.is_subdomain(self.zone.origin):
                self._eat_line()
                return
            if self.relativize:
                name = name.relativize(self.zone.origin)

            n = self.zone.nodes.get(name)
            if n is None:
                n = self.zone.node_factory()
                self.zone.nodes[name] = n
            try:
                rd = dns.rdata.from_text(rdclass, rdtype, rdata,
                                         self.current_origin, False)
            except dns.exception.SyntaxError:
                # Catch and reraise.
                (ty, va) = sys.exc_info()[:2]
                raise va
            except:
                # All exceptions that occur in the processing of rdata
                # are treated as syntax errors.  This is not strictly
                # correct, but it is correct almost all of the time.
                # We convert them to syntax errors so that we can emit
                # helpful filename:line info.
                (ty, va) = sys.exc_info()[:2]
                raise dns.exception.SyntaxError("caught exception %s: %s" %
                                                (str(ty), str(va)))

            rd.choose_relativity(self.zone.origin, self.relativize)
            covers = rd.covers()
            rds = n.find_rdataset(rdclass, rdtype, covers, True)
            rds.add(rd, ttl)

    def read(self):
        """Read a DNS master file and build a zone object.

        @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
        @raises dns.zone.NoNS: No NS RRset was found at the zone origin
        """

        try:
            while 1:
                token = self.tok.get(True, True)
                if token.is_eof():
                    if self.current_file is not None:
                        self.current_file.close()
                    if len(self.saved_state) > 0:
                        (self.tok,
                         self.current_origin,
                         self.last_name,
                         self.current_file,
                         self.ttl) = self.saved_state.pop(-1)
                        continue
                    break
                elif token.is_eol():
                    continue
                elif token.is_comment():
                    self.tok.get_eol()
                    continue
                elif token.value[0] == u'$':
                    c = token.value.upper()
                    if c == u'$TTL':
                        token = self.tok.get()
                        if not token.is_identifier():
                            raise dns.exception.SyntaxError("bad $TTL")
                        self.ttl = dns.ttl.from_text(token.value)
                        self.tok.get_eol()
                    elif c == u'$ORIGIN':
                        self.current_origin = self.tok.get_name()
                        self.tok.get_eol()
                        if self.zone.origin is None:
                            self.zone.origin = self.current_origin
                    elif c == u'$INCLUDE' and self.allow_include:
                        token = self.tok.get()
                        filename = token.value
                        token = self.tok.get()
                        if token.is_identifier():
                            new_origin =\
                                dns.name.from_text(token.value,
                                                   self.current_origin)
                            self.tok.get_eol()
                        elif not token.is_eol_or_eof():
                            raise dns.exception.SyntaxError(
                                "bad origin in $INCLUDE")
                        else:
                            new_origin = self.current_origin
                        self.saved_state.append((self.tok,
                                                 self.current_origin,
                                                 self.last_name,
                                                 self.current_file,
                                                 self.ttl))
                        self.current_file = open(filename, 'r')
                        self.tok = dns.tokenizer.Tokenizer(self.current_file,
                                                           filename)
                        self.current_origin = new_origin
                    elif c == u'$GENERATE':
                        self._generate_line()
                    else:
                        raise dns.exception.SyntaxError(
                            "Unknown master file directive '" + c + "'")
                    continue
                self.tok.unget(token)
                self._rr_line()
        except dns.exception.SyntaxError as detail:
            (filename, line_number) = self.tok.where()
            if detail is None:
                detail = "syntax error"
            raise dns.exception.SyntaxError(
                "%s:%d: %s" % (filename, line_number, detail))

        # Now that we're done reading, do some basic checking of the zone.
        if self.check_origin:
            self.zone.check_origin()


def from_text(text, origin=None, rdclass=dns.rdataclass.IN,
              relativize=True, zone_factory=Zone, filename=None,
              allow_include=False, check_origin=True):
    """Build a zone object from a master file format string.

    @param text: the master file format input
    @type text: string.
    @param origin: The origin of the zone; if not specified, the first
    $ORIGIN statement in the master file will determine the origin of the
    zone.
    @type origin: dns.name.Name object or string
    @param rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @param relativize: should names be relativized?  The default is True
    @type relativize: bool
    @param zone_factory: The zone factory to use
    @type zone_factory: function returning a Zone
    @param filename: The filename to emit when describing where an error
    occurred; the default is '<string>'.
    @type filename: string
    @param allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    """

    # 'text' can also be a file, but we don't publish that fact
    # since it's an implementation detail.  The official file
    # interface is from_file().

    if filename is None:
        filename = '<string>'
    tok = dns.tokenizer.Tokenizer(text, filename)
    reader = _MasterReader(tok, origin, rdclass, relativize, zone_factory,
                           allow_include=allow_include,
                           check_origin=check_origin)
    reader.read()
    return reader.zone


def from_file(f, origin=None, rdclass=dns.rdataclass.IN,
              relativize=True, zone_factory=Zone, filename=None,
              allow_include=True, check_origin=True):
    """Read a master file and build a zone object.

    @param f: file or string.  If I{f} is a string, it is treated
    as the name of a file to open.
    @param origin: The origin of the zone; if not specified, the first
    $ORIGIN statement in the master file will determine the origin of the
    zone.
    @type origin: dns.name.Name object or string
    @param rdclass: The zone's rdata class; the default is class IN.
    @type rdclass: int
    @param relativize: should names be relativized?  The default is True
    @type relativize: bool
    @param zone_factory: The zone factory to use
    @type zone_factory: function returning a Zone
    @param filename: The filename to emit when describing where an error
    occurred; the default is '<file>', or the value of I{f} if I{f} is a
    string.
    @type filename: string
    @param allow_include: is $INCLUDE allowed?
    @type allow_include: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    """

    str_type = string_types
    opts = 'rU'

    if isinstance(f, str_type):
        if filename is None:
            filename = f
        f = open(f, opts)
        want_close = True
    else:
        if filename is None:
            filename = '<file>'
        want_close = False

    try:
        z = from_text(f, origin, rdclass, relativize, zone_factory,
                      filename, allow_include, check_origin)
    finally:
        if want_close:
            f.close()
    return z


def from_xfr(xfr, zone_factory=Zone, relativize=True, check_origin=True):
    """Convert the output of a zone transfer generator into a zone object.

    @param xfr: The xfr generator
    @type xfr: generator of dns.message.Message objects
    @param relativize: should names be relativized?  The default is True.
    It is essential that the relativize setting matches the one specified
    to dns.query.xfr().
    @type relativize: bool
    @param check_origin: should sanity checks of the origin node be done?
    The default is True.
    @type check_origin: bool
    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
    @rtype: dns.zone.Zone object
    """

    z = None
    for r in xfr:
        if z is None:
            if relativize:
                origin = r.origin
            else:
                origin = r.answer[0].name
            rdclass = r.answer[0].rdclass
            z = zone_factory(origin, rdclass, relativize=relativize)
        for rrset in r.answer:
            znode = z.nodes.get(rrset.name)
            if not znode:
                znode = z.node_factory()
                z.nodes[rrset.name] = znode
            zrds = znode.find_rdataset(rrset.rdclass, rrset.rdtype,
                                       rrset.covers, True)
            zrds.update_ttl(rrset.ttl)
            for rd in rrset:
                rd.choose_relativity(z.origin, relativize)
                zrds.add(rd)
    if check_origin:
        z.check_origin()
    return z
PKk�\�j�i]]namedict.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
# Copyright (C) 2016 Coresec Systems AB
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND CORESEC SYSTEMS AB DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CORESEC
# SYSTEMS AB BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS name dictionary"""

import collections
import dns.name
from ._compat import xrange


class NameDict(collections.MutableMapping):

    """A dictionary whose keys are dns.name.Name objects.
    @ivar max_depth: the maximum depth of the keys that have ever been
    added to the dictionary.
    @type max_depth: int
    @ivar max_depth_items: the number of items of maximum depth
    @type max_depth_items: int
    """

    __slots__ = ["max_depth", "max_depth_items", "__store"]

    def __init__(self, *args, **kwargs):
        self.__store = dict()
        self.max_depth = 0
        self.max_depth_items = 0
        self.update(dict(*args, **kwargs))

    def __update_max_depth(self, key):
        if len(key) == self.max_depth:
            self.max_depth_items = self.max_depth_items + 1
        elif len(key) > self.max_depth:
            self.max_depth = len(key)
            self.max_depth_items = 1

    def __getitem__(self, key):
        return self.__store[key]

    def __setitem__(self, key, value):
        if not isinstance(key, dns.name.Name):
            raise ValueError('NameDict key must be a name')
        self.__store[key] = value
        self.__update_max_depth(key)

    def __delitem__(self, key):
        value = self.__store.pop(key)
        if len(value) == self.max_depth:
            self.max_depth_items = self.max_depth_items - 1
        if self.max_depth_items == 0:
            self.max_depth = 0
            for k in self.__store:
                self.__update_max_depth(k)

    def __iter__(self):
        return iter(self.__store)

    def __len__(self):
        return len(self.__store)

    def has_key(self, key):
        return key in self.__store

    def get_deepest_match(self, name):
        """Find the deepest match to I{name} in the dictionary.

        The deepest match is the longest name in the dictionary which is
        a superdomain of I{name}.

        @param name: the name
        @type name: dns.name.Name object
        @rtype: (key, value) tuple
        """

        depth = len(name)
        if depth > self.max_depth:
            depth = self.max_depth
        for i in xrange(-depth, 0):
            n = dns.name.Name(name[i:])
            if n in self:
                return (n, self[n])
        v = self[dns.name.empty]
        return (dns.name.empty, v)
PKk�\���3  rcode.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS Result Codes."""

import dns.exception
from ._compat import long


NOERROR = 0
FORMERR = 1
SERVFAIL = 2
NXDOMAIN = 3
NOTIMP = 4
REFUSED = 5
YXDOMAIN = 6
YXRRSET = 7
NXRRSET = 8
NOTAUTH = 9
NOTZONE = 10
BADVERS = 16

_by_text = {
    'NOERROR': NOERROR,
    'FORMERR': FORMERR,
    'SERVFAIL': SERVFAIL,
    'NXDOMAIN': NXDOMAIN,
    'NOTIMP': NOTIMP,
    'REFUSED': REFUSED,
    'YXDOMAIN': YXDOMAIN,
    'YXRRSET': YXRRSET,
    'NXRRSET': NXRRSET,
    'NOTAUTH': NOTAUTH,
    'NOTZONE': NOTZONE,
    'BADVERS': BADVERS
}

# We construct the inverse mapping programmatically to ensure that we
# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
# would cause the mapping not to be a true inverse.

_by_value = dict((y, x) for x, y in _by_text.items())


class UnknownRcode(dns.exception.DNSException):

    """A DNS rcode is unknown."""


def from_text(text):
    """Convert text into an rcode.

    @param text: the textual rcode
    @type text: string
    @raises UnknownRcode: the rcode is unknown
    @rtype: int
    """

    if text.isdigit():
        v = int(text)
        if v >= 0 and v <= 4095:
            return v
    v = _by_text.get(text.upper())
    if v is None:
        raise UnknownRcode
    return v


def from_flags(flags, ednsflags):
    """Return the rcode value encoded by flags and ednsflags.

    @param flags: the DNS flags
    @type flags: int
    @param ednsflags: the EDNS flags
    @type ednsflags: int
    @raises ValueError: rcode is < 0 or > 4095
    @rtype: int
    """

    value = (flags & 0x000f) | ((ednsflags >> 20) & 0xff0)
    if value < 0 or value > 4095:
        raise ValueError('rcode must be >= 0 and <= 4095')
    return value


def to_flags(value):
    """Return a (flags, ednsflags) tuple which encodes the rcode.

    @param value: the rcode
    @type value: int
    @raises ValueError: rcode is < 0 or > 4095
    @rtype: (int, int) tuple
    """

    if value < 0 or value > 4095:
        raise ValueError('rcode must be >= 0 and <= 4095')
    v = value & 0xf
    ev = long(value & 0xff0) << 20
    return (v, ev)


def to_text(value):
    """Convert rcode into text.

    @param value: the rcode
    @type value: int
    @rtype: string
    """

    text = _by_value.get(value)
    if text is None:
        text = str(value)
    return text
PKk�\�����)rdtypes/IN/__pycache__/SRV.cpython-36.pycnu�[���3

�b�W��@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsfeZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
ddd�Z�ZS)�SRVaSRV record

    @ivar priority: the priority
    @type priority: int
    @ivar weight: the weight
    @type weight: int
    @ivar port: the port of the service
    @type port: int
    @ivar target: the target host
    @type target: dns.name.Name object
    @see: RFC 2782�priority�weight�port�targetcs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__��/usr/lib/python3.6/SRV.pyr's
zSRV.__init__NTcKs$|jj||�}d|j|j|j|fS)Nz%d %d %d %s)r�choose_relativityrrr)r	�origin�
relativize�kwrr
r
r�to_text.szSRV.to_textc
CsH|j�}|j�}|j�}|jd�}	|	j||�}	|j�|||||||	�S)N)Z
get_uint16Zget_namerZget_eol)
�clsr
r�tokrrrrrrr
r
r�	from_text3s
z
SRV.from_textcCs4tjd|j|j|j�}|j|�|jj|||�dS)Nz!HHH)�struct�packrrr�writer�to_wire)r	�file�compressrZ
three_intsr
r
rr=s
zSRV.to_wirecCs�tjd|||d��\}}}	|d7}|d8}tjj|d||�|�\}
}||kr\tjj�|dk	rn|
j|�}
||||||	|
�S)Nz!HHH�)r�unpack�dns�name�	from_wireZ	exceptionZ	FormErrorr)rr
rZwireZcurrentZrdlenrrrrrZcusedr
r
rr!Bs

z
SRV.from_wirecCs|jj||�|_dS)N)rr)r	rrr
r
rrPszSRV.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr!r�
__classcell__r
r
)rrrs
	

r)rZ
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarr
r
r
r�<module>sPKk�\T���``.rdtypes/IN/__pycache__/KX.cpython-36.opt-1.pycnu�[���3

�b�Wq�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�KXz	KX recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/KX.pyrsr)Zdns.rdtypes.mxbaseZdnsZrdtypesZmxbaseZUncompressedMXrrrrr�<module>sPKk�\\m9Mrr.rdtypes/IN/__pycache__/NSAP_PTR.cpython-36.pycnu�[���3

�b�W}�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�NSAP_PTRzNSAP-PTR recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/NSAP_PTR.pyrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZUncompressedNSrrrrr�<module>sPKk�\6�Pb.rdtypes/IN/__pycache__/IPSECKEY.cpython-36.pycnu�[���3

�b�W1�@s@ddlZddlZddlZddlZddlZGdd�dejj�ZdS)�Ncs^eZdZdZdddddgZ�fdd�Zddd�Zedd
d��Zddd�Z	eddd��Z
�ZS)�IPSECKEYa�IPSECKEY record

    @ivar precedence: the precedence for this key data
    @type precedence: int
    @ivar gateway_type: the gateway type
    @type gateway_type: int
    @ivar algorithm: the algorithm to use
    @type algorithm: int
    @ivar gateway: the public key
    @type gateway: None, IPv4 address, IPV6 address, or domain name
    @ivar key: the public key
    @type key: string
    @see: RFC 4025�
precedence�gateway_type�	algorithm�gateway�keycs�tt|�j||�|dkr8|dkr2|dk	r2td��d}nN|dkrTtjjtjj|�n2|dkrptjjtjj|�n|dkrzntd|��||_	||_
||_||_||_
dS)Nr�.z"invalid gateway for gateway type 0���z!invalid IPSECKEY gateway type: %d)�superr�__init__�SyntaxError�dns�inet�	inet_pton�AF_INET�AF_INET6rrrrr)�self�rdclass�rdtyperrrrr)�	__class__��/usr/lib/python3.6/IPSECKEY.pyr
*s$
zIPSECKEY.__init__NTcKs||jdkrd}nJ|jdkr"|j}n8|jdkr4|j}n&|jdkrRt|jj||��}ntd��d|j|j|j|tjj	|j
�fS)Nrrr	r
rzinvalid gateway typez%d %d %d %s %s)rr�str�choose_relativity�
ValueErrorrrr�rdataZ
_base64ifyr)r�origin�
relativize�kwrrrr�to_textBs




zIPSECKEY.to_textcCs�|j�}|j�}|j�}|dkr2|j�j||�}	n|j�}	g}
x:|j�j�}|j�rVP|j�sftj	j
�|
j|jj
��q@Wdj|
�}tj|�}
|||||||	|
�S)Nr�)Z	get_uint8Zget_namerZ
get_string�getZunescapeZ
is_eol_or_eofZ
is_identifierr�	exceptionr�append�value�encode�join�base64Z	b64decode)�clsrr�tokrrrrrrZchunks�tZb64rrrr�	from_textQs$

zIPSECKEY.from_textcCs�tjd|j|j|j�}|j|�|jdkr,np|jdkrR|jtjjtjj	|j
��nJ|jdkrx|jtjjtjj|j
��n$|jdkr�|j
j|d|�nt
d��|j|j�dS)Nz!BBBrr	r
rzinvalid gateway type)�struct�packrrr�writerrrrrr�to_wirerr)r�file�compressr�headerrrrr1gs




zIPSECKEY.to_wirecCs2|dkrtjj�tjd|||d��}|d}|d7}|d8}|dkrNd}	n�|dkr�tjjtjj|||d��}	|d7}|d8}n||dkr�tjjtjj|||d��}	|d7}|d8}nD|dkr�tj	j
|d||�|�\}	}
||
7}||
8}ntjjd��||||�j�}||||d||d|	|�S)	Nrz!BBBr	r�r
�zinvalid IPSECKEY gateway type)rr$Z	FormErrorr.�unpackrZ	inet_ntoprr�name�	from_wireZunwrap)r*rrZwireZcurrentZrdlenrr4rrZcusedrrrrr9ws6



zIPSECKEY.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r
r!�classmethodr-r1r9�
__classcell__rr)rrrs

r)	r.r)Z
dns.exceptionrZdns.inetZdns.namerZRdatarrrrr�<module>s
PKk�\�����/rdtypes/IN/__pycache__/APL.cpython-36.opt-1.pycnu�[���3

�b�Wt�@sdddlZddlZddlZddlZddlZddlZddlmZGdd�de	�Z
Gdd�dejj�Z
dS)�N)�xrangec@s4eZdZdZddddgZdd�Zdd	�Zd
d�ZdS)
�APLItema'An APL list item.

    @ivar family: the address family (IANA address family registry)
    @type family: int
    @ivar negation: is this item negated?
    @type negation: bool
    @ivar address: the address
    @type address: string
    @ivar prefix: the prefix length
    @type prefix: int
    �family�negation�address�prefixcCs||_||_||_||_dS)N)rrrr)�selfrrrr�r	�/usr/lib/python3.6/APL.py�__init__*szAPLItem.__init__cCs2|jrd|j|j|jfSd|j|j|jfSdS)Nz	!%d:%s/%sz%d:%s/%s)rrrr)rr	r	r
�__str__0szAPLItem.__str__cCs�|jdkr tjjtjj|j�}n,|jdkr@tjjtjj|j�}ntj|j�}d}x6t	t
|�ddd�D]}||td�krf|d}PqfW|d|�}t
|�}|jr�|dO}t
jd|j|j|�}|j|�|j|�dS)N��r�z!HBB���r)r�dns�inetZ	inet_pton�AF_INETr�AF_INET6�binasciiZ	unhexlifyr�len�chrr�struct�packr�write)r�filerZlast�i�l�headerr	r	r
�to_wire6s"


zAPLItem.to_wireN)�__name__�
__module__�__qualname__�__doc__�	__slots__rrrr	r	r	r
rs
rcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�APLzfAPL record.

    @ivar items: a list of APL items
    @type items: list of APL_Item
    @see: RFC 3123�itemscstt|�j||�||_dS)N)�superr%rr&)r�rdclass�rdtyper&)�	__class__r	r
rYszAPL.__init__NTcKsdjtt|j��S)N� )�join�map�strr&)r�origin�
relativize�kwr	r	r
�to_text]szAPL.to_textcCs�g}x�|j�j�}|j�rP|j}|ddkr@d}	|dd�}nd}	|jdd�\}
}t|
�}
|jdd�\}}
t|
�}
t|
|	||
�}|j|�qW||||�S)Nr�!Tr
F�:�/)�getZunescapeZ
is_eol_or_eof�value�split�intr�append)�clsr(r)�tokr/r0r&�token�itemrr�restrrr	r	r
�	from_text`s"z
APL.from_textcCsx|jD]}|j|�qWdS)N)r&r)rr�compressr/r>r	r	r
rvszAPL.to_wirecCsTg}�x@|dkrP|dkr"tjj�tjd|||d��}|d}	|	dkrXd}
|	d8}	nd}
|d7}|d8}||	kr|tjj�||||	�j�}t|�}|dd	kr�|dkr�|d
d|7}tjjtjj	|�}nD|ddk�r
|dkr�|d
d|7}tjjtjj
|�}n
|jd�}||	7}||	8}t|d|
||d	�}
|j
|
�qW||||�S)
Nr�z!HBBr�TrFr
���	hex_codec)rZ	exceptionZ	FormErrorr�unpackZunwraprrZ	inet_ntoprr�encoderr:)r;r(r)ZwireZcurrentZrdlenr/r&rZafdlenrrrr>r	r	r
�	from_wirezs@

z
APL.from_wire)NT)NT)NN)N)r r!r"r#r$rr2�classmethodr@rrI�
__classcell__r	r	)r*r
r%Os

r%)rrZ
dns.exceptionrZdns.inetZ	dns.rdataZ
dns.tokenizerZdns._compatr�objectrZrdataZRdatar%r	r	r	r
�<module>s5PKk�\������+rdtypes/IN/__pycache__/NAPTR.cpython-36.pycnu�[���3

�b�Wv�@sXddlZddlZddlZddlZddlmZmZdd�Zdd�Z	Gdd�dej
j�ZdS)	�N)�xrange�	text_typecCs4t|�}|dkst�|jtjd|��|j|�dS)N�z!B)�len�AssertionError�write�struct�pack)�file�s�l�r
�/usr/lib/python3.6/NAPTR.py�
_write_stringsrcCst|t�r|j�S|S)N)�
isinstancer�encode)�valuer
r
r�	_sanitizes
rcsjeZdZdZddddddgZ�fdd	�Zddd
�Zeddd��Zddd�Z	eddd��Z
ddd�Z�ZS)�NAPTRa}NAPTR record

    @ivar order: order
    @type order: int
    @ivar preference: preference
    @type preference: int
    @ivar flags: flags
    @type flags: string
    @ivar service: service
    @type service: string
    @ivar regexp: regular expression
    @type regexp: string
    @ivar replacement: replacement name
    @type replacement: dns.name.Name object
    @see: RFC 3403�order�
preference�flags�service�regexp�replacementc		sFtt|�j||�t|�|_t|�|_t|�|_||_||_||_	dS)N)
�superr�__init__rrrrrrr)	�self�rdclass�rdtyperrrrrr)�	__class__r
rr:s


zNAPTR.__init__NTcKsD|jj||�}d|j|jtjj|j�tjj|j�tjj|j	�|fS)Nz%d %d "%s" "%s" "%s" %s)
r�choose_relativityrr�dns�rdataZ	_escapifyrrr)r�origin�
relativize�kwrr
r
r�to_textDsz
NAPTR.to_textc	CsZ|j�}|j�}|j�}|j�}	|j�}
|j�}|j||�}|j�|||||||	|
|�S)N)Z
get_uint16Z
get_stringZget_namer!Zget_eol)�clsrr�tokr$r%rrrrrrr
r
r�	from_textMszNAPTR.from_textcCsTtjd|j|j�}|j|�t||j�t||j�t||j�|j	j
|||�dS)Nz!HH)rr	rrrrrrrr�to_wire)rr
�compressr$Ztwo_intsr
r
rr+Zs
z
NAPTR.to_wirec	Cstjd|||d��\}}|d7}|d8}g}	xntd�D]b}
||}|d7}|d8}||ksf|dkrntjj�||||�j�}||7}||8}|	j|�q:Wtjj	|d||�|�\}
}||kr�tjj�|dk	r�|
j
|�}
||||||	d|	d|	d|
�S)Nz!HH���r�)r�unpackrr"Z	exceptionZ	FormErrorZunwrap�append�name�	from_wirer%)r(rrZwireZcurrentZrdlenr$rrZstrings�irrrZcusedr
r
rr4bs,

zNAPTR.from_wirecCs|jj||�|_dS)N)rr!)rr$r%r
r
rr!{szNAPTR.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr'�classmethodr*r+r4r!�
__classcell__r
r
)r rr%s


	
r)
rZ
dns.exceptionr"Zdns.nameZ	dns.rdataZdns._compatrrrrr#ZRdatarr
r
r
r�<module>sPKk�\=����1rdtypes/IN/__pycache__/DHCID.cpython-36.opt-1.pycnu�[���3

�b�W��@s(ddlZddlZGdd�dejj�ZdS)�NcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�DHCIDz�DHCID record

    @ivar data: the data (the content of the RR is opaque as far as the
    DNS is concerned)
    @type data: string
    @see: RFC 4701�datacstt|�j||�||_dS)N)�superr�__init__r)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/DHCID.pyr szDHCID.__init__NTcKstjj|j�S)N)�dns�rdataZ
_base64ifyr)r�origin�
relativize�kwr
r
r�to_text$sz
DHCID.to_textc
Cs`g}x:|j�j�}|j�rP|j�s,tjj�|j|jj	��qWdj
|�}tj|�}	||||	�S)N�)
�getZunescapeZ
is_eol_or_eofZ
is_identifierrZ	exception�SyntaxError�append�value�encode�join�base64Z	b64decode)
�clsrr�tokrrZchunks�tZb64rr
r
r�	from_text's

zDHCID.from_textcCs|j|j�dS)N)�writer)r�file�compressrr
r
r�to_wire5sz
DHCID.to_wirecCs ||||�j�}||||�S)N)Zunwrap)rrrZwireZcurrentZrdlenrrr
r
r�	from_wire8szDHCID.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr!r"�
__classcell__r
r
)r	rrs

r)rZ
dns.exceptionrr
ZRdatarr
r
r
r�<module>sPKk�\٣��0rdtypes/IN/__pycache__/AAAA.cpython-36.opt-1.pycnu�[���3

�b�W��@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�AAAAzhAAAA record.

    @ivar address: an IPv6 address
    @type address: string (in the standard IPv6 format)�addresscs.tt|�j||�tjjtjj|�||_dS)N)�superr�__init__�dns�inet�	inet_pton�AF_INET6r)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/AAAA.pyrsz
AAAA.__init__NTcKs|jS)N)r)r
�origin�
relativize�kwrrr�to_text%szAAAA.to_textcCs|j�}|j�||||�S)N)Zget_identifierZget_eol)�clsrr�tokrrrrrr�	from_text(szAAAA.from_textcCs|jtjjtjj|j��dS)N)�writerrrr	r)r
�file�compressrrrr�to_wire.szAAAA.to_wirecCs*tjjtjj||||��}||||�S)N)rrZ	inet_ntopr	)rrrZwireZcurrentZrdlenrrrrr�	from_wire1szAAAA.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr�
__classcell__rr)r
rrs

r)Z
dns.exceptionrZdns.inetZ	dns.rdataZ
dns.tokenizerZrdataZRdatarrrrr�<module>sPKk�\T���``(rdtypes/IN/__pycache__/KX.cpython-36.pycnu�[���3

�b�Wq�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�KXz	KX recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/KX.pyrsr)Zdns.rdtypes.mxbaseZdnsZrdtypesZmxbaseZUncompressedMXrrrrr�<module>sPKk�\S
�.rdtypes/IN/__pycache__/__init__.cpython-36.pycnu�[���3

�b�W��@s"dZddddddddd	d
dgZdS)
zClass IN rdata type classes.�AZAAAAZAPLZDHCIDZKXZNAPTRZNSAPZNSAP_PTRZPXZSRVZWKSN)�__doc__�__all__�rr�/usr/lib/python3.6/__init__.py�<module>sPKk�\g���0rdtypes/IN/__pycache__/NSAP.cpython-36.opt-1.pycnu�[���3

�b�W�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�NSAPzTNSAP record.

    @ivar address: a NASP
    @type address: string
    @see: RFC 1706�addresscstt|�j||�||_dS)N)�superr�__init__r)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/NSAP.pyr!sz
NSAP.__init__NTcKsdtj|j�j�S)Nz0x%s)�binasciiZhexlifyr�decode)r�origin�
relativize�kwr
r
r�to_text%szNSAP.to_textcCsv|j�}|j�|dd�dkr,tjjd��|dd�jdd�}t|�ddkr\tjjd��tj|j	��}||||�S)Nr�Z0xzstring does not start with 0x�.�zhexstring has odd length)
Z
get_stringZget_eol�dnsZ	exception�SyntaxError�replace�lenrZ	unhexlify�encode)�clsrr�tokrrrr
r
r�	from_text(szNSAP.from_textcCs|j|j�dS)N)�writer)r�file�compressrr
r
r�to_wire4szNSAP.to_wirecCs ||||�j�}||||�S)N)Zunwrap)rrrZwireZcurrentZrdlenrrr
r
r�	from_wire7szNSAP.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr r!�
__classcell__r
r
)r	rrs

r)rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZrdataZRdatarr
r
r
r�<module>sPKk�\�r�O��1rdtypes/IN/__pycache__/NAPTR.cpython-36.opt-1.pycnu�[���3

�b�Wv�@sXddlZddlZddlZddlZddlmZmZdd�Zdd�Z	Gdd�dej
j�ZdS)	�N)�xrange�	text_typecCs(t|�}|jtjd|��|j|�dS)Nz!B)�len�write�struct�pack)�file�s�l�r�/usr/lib/python3.6/NAPTR.py�
_write_stringsr
cCst|t�r|j�S|S)N)�
isinstancer�encode)�valuerrr�	_sanitizes
rcsjeZdZdZddddddgZ�fdd	�Zddd
�Zeddd��Zddd�Z	eddd��Z
ddd�Z�ZS)�NAPTRa}NAPTR record

    @ivar order: order
    @type order: int
    @ivar preference: preference
    @type preference: int
    @ivar flags: flags
    @type flags: string
    @ivar service: service
    @type service: string
    @ivar regexp: regular expression
    @type regexp: string
    @ivar replacement: replacement name
    @type replacement: dns.name.Name object
    @see: RFC 3403�order�
preference�flags�service�regexp�replacementc		sFtt|�j||�t|�|_t|�|_t|�|_||_||_||_	dS)N)
�superr�__init__rrrrrrr)	�self�rdclass�rdtyperrrrrr)�	__class__rrr:s


zNAPTR.__init__NTcKsD|jj||�}d|j|jtjj|j�tjj|j�tjj|j	�|fS)Nz%d %d "%s" "%s" "%s" %s)
r�choose_relativityrr�dns�rdataZ	_escapifyrrr)r�origin�
relativize�kwrrrr�to_textDsz
NAPTR.to_textc	CsZ|j�}|j�}|j�}|j�}	|j�}
|j�}|j||�}|j�|||||||	|
|�S)N)Z
get_uint16Z
get_stringZget_namerZget_eol)�clsrr�tokr"r#rrrrrrrrr�	from_textMszNAPTR.from_textcCsTtjd|j|j�}|j|�t||j�t||j�t||j�|j	j
|||�dS)Nz!HH)rrrrrr
rrrr�to_wire)rr�compressr"Ztwo_intsrrrr)Zs
z
NAPTR.to_wirec	Cstjd|||d��\}}|d7}|d8}g}	xntd�D]b}
||}|d7}|d8}||ksf|dkrntjj�||||�j�}||7}||8}|	j|�q:Wtjj	|d||�|�\}
}||kr�tjj�|dk	r�|
j
|�}
||||||	d|	d|	d|
�S)Nz!HH���r�)r�unpackrr Z	exceptionZ	FormErrorZunwrap�append�name�	from_wirer#)r&rrZwireZcurrentZrdlenr"rrZstrings�ir
r	rZcusedrrrr2bs,

zNAPTR.from_wirecCs|jj||�|_dS)N)rr)rr"r#rrrr{szNAPTR.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr%�classmethodr(r)r2r�
__classcell__rr)rrr%s


	
r)
rZ
dns.exceptionr Zdns.nameZ	dns.rdataZdns._compatrrr
rr!ZRdatarrrrr�<module>sPKk�\6�Pb4rdtypes/IN/__pycache__/IPSECKEY.cpython-36.opt-1.pycnu�[���3

�b�W1�@s@ddlZddlZddlZddlZddlZGdd�dejj�ZdS)�Ncs^eZdZdZdddddgZ�fdd�Zddd�Zedd
d��Zddd�Z	eddd��Z
�ZS)�IPSECKEYa�IPSECKEY record

    @ivar precedence: the precedence for this key data
    @type precedence: int
    @ivar gateway_type: the gateway type
    @type gateway_type: int
    @ivar algorithm: the algorithm to use
    @type algorithm: int
    @ivar gateway: the public key
    @type gateway: None, IPv4 address, IPV6 address, or domain name
    @ivar key: the public key
    @type key: string
    @see: RFC 4025�
precedence�gateway_type�	algorithm�gateway�keycs�tt|�j||�|dkr8|dkr2|dk	r2td��d}nN|dkrTtjjtjj|�n2|dkrptjjtjj|�n|dkrzntd|��||_	||_
||_||_||_
dS)Nr�.z"invalid gateway for gateway type 0���z!invalid IPSECKEY gateway type: %d)�superr�__init__�SyntaxError�dns�inet�	inet_pton�AF_INET�AF_INET6rrrrr)�self�rdclass�rdtyperrrrr)�	__class__��/usr/lib/python3.6/IPSECKEY.pyr
*s$
zIPSECKEY.__init__NTcKs||jdkrd}nJ|jdkr"|j}n8|jdkr4|j}n&|jdkrRt|jj||��}ntd��d|j|j|j|tjj	|j
�fS)Nrrr	r
rzinvalid gateway typez%d %d %d %s %s)rr�str�choose_relativity�
ValueErrorrrr�rdataZ
_base64ifyr)r�origin�
relativize�kwrrrr�to_textBs




zIPSECKEY.to_textcCs�|j�}|j�}|j�}|dkr2|j�j||�}	n|j�}	g}
x:|j�j�}|j�rVP|j�sftj	j
�|
j|jj
��q@Wdj|
�}tj|�}
|||||||	|
�S)Nr�)Z	get_uint8Zget_namerZ
get_string�getZunescapeZ
is_eol_or_eofZ
is_identifierr�	exceptionr�append�value�encode�join�base64Z	b64decode)�clsrr�tokrrrrrrZchunks�tZb64rrrr�	from_textQs$

zIPSECKEY.from_textcCs�tjd|j|j|j�}|j|�|jdkr,np|jdkrR|jtjjtjj	|j
��nJ|jdkrx|jtjjtjj|j
��n$|jdkr�|j
j|d|�nt
d��|j|j�dS)Nz!BBBrr	r
rzinvalid gateway type)�struct�packrrr�writerrrrrr�to_wirerr)r�file�compressr�headerrrrr1gs




zIPSECKEY.to_wirecCs2|dkrtjj�tjd|||d��}|d}|d7}|d8}|dkrNd}	n�|dkr�tjjtjj|||d��}	|d7}|d8}n||dkr�tjjtjj|||d��}	|d7}|d8}nD|dkr�tj	j
|d||�|�\}	}
||
7}||
8}ntjjd��||||�j�}||||d||d|	|�S)	Nrz!BBBr	r�r
�zinvalid IPSECKEY gateway type)rr$Z	FormErrorr.�unpackrZ	inet_ntoprr�name�	from_wireZunwrap)r*rrZwireZcurrentZrdlenrr4rrZcusedrrrrr9ws6



zIPSECKEY.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r
r!�classmethodr-r1r9�
__classcell__rr)rrrs

r)	r.r)Z
dns.exceptionrZdns.inetZdns.namerZRdatarrrrr�<module>s
PKk�\"����)rdtypes/IN/__pycache__/APL.cpython-36.pycnu�[���3

�b�Wt�@sdddlZddlZddlZddlZddlZddlZddlmZGdd�de	�Z
Gdd�dejj�Z
dS)�N)�xrangec@s4eZdZdZddddgZdd�Zdd	�Zd
d�ZdS)
�APLItema'An APL list item.

    @ivar family: the address family (IANA address family registry)
    @type family: int
    @ivar negation: is this item negated?
    @type negation: bool
    @ivar address: the address
    @type address: string
    @ivar prefix: the prefix length
    @type prefix: int
    �family�negation�address�prefixcCs||_||_||_||_dS)N)rrrr)�selfrrrr�r	�/usr/lib/python3.6/APL.py�__init__*szAPLItem.__init__cCs2|jrd|j|j|jfSd|j|j|jfSdS)Nz	!%d:%s/%sz%d:%s/%s)rrrr)rr	r	r
�__str__0szAPLItem.__str__cCs�|jdkr tjjtjj|j�}n,|jdkr@tjjtjj|j�}ntj|j�}d}x6t	t
|�ddd�D]}||td�krf|d}PqfW|d|�}t
|�}|dks�t�|j
r�|dO}tjd|j|j|�}|j|�|j|�dS)N��r�z!HBB���r)r�dns�inetZ	inet_pton�AF_INETr�AF_INET6�binasciiZ	unhexlifyr�len�chr�AssertionErrorr�struct�packr�write)r�filerZlast�i�l�headerr	r	r
�to_wire6s$


zAPLItem.to_wireN)�__name__�
__module__�__qualname__�__doc__�	__slots__rrr r	r	r	r
rs
rcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�APLzfAPL record.

    @ivar items: a list of APL items
    @type items: list of APL_Item
    @see: RFC 3123�itemscstt|�j||�||_dS)N)�superr&rr')r�rdclass�rdtyper')�	__class__r	r
rYszAPL.__init__NTcKsdjtt|j��S)N� )�join�map�strr')r�origin�
relativize�kwr	r	r
�to_text]szAPL.to_textcCs�g}x�|j�j�}|j�rP|j}|ddkr@d}	|dd�}nd}	|jdd�\}
}t|
�}
|jdd�\}}
t|
�}
t|
|	||
�}|j|�qW||||�S)Nr�!Tr
F�:�/)�getZunescapeZ
is_eol_or_eof�value�split�intr�append)�clsr)r*�tokr0r1r'�token�itemrr�restrrr	r	r
�	from_text`s"z
APL.from_textcCsx|jD]}|j|�qWdS)N)r'r )rr�compressr0r?r	r	r
r vszAPL.to_wirecCsTg}�x@|dkrP|dkr"tjj�tjd|||d��}|d}	|	dkrXd}
|	d8}	nd}
|d7}|d8}||	kr|tjj�||||	�j�}t|�}|dd	kr�|dkr�|d
d|7}tjjtjj	|�}nD|ddk�r
|dkr�|d
d|7}tjjtjj
|�}n
|jd�}||	7}||	8}t|d|
||d	�}
|j
|
�qW||||�S)
Nr�z!HBBr�TrFr
���	hex_codec)rZ	exceptionZ	FormErrorr�unpackZunwraprrZ	inet_ntoprr�encoderr;)r<r)r*ZwireZcurrentZrdlenr0r'rZafdlenrrrr?r	r	r
�	from_wirezs@

z
APL.from_wire)NT)NT)NN)N)r!r"r#r$r%rr3�classmethodrAr rJ�
__classcell__r	r	)r+r
r&Os

r&)rrZ
dns.exceptionrZdns.inetZ	dns.rdataZ
dns.tokenizerZdns._compatr�objectrZrdataZRdatar&r	r	r	r
�<module>s5PKl�\=����+rdtypes/IN/__pycache__/DHCID.cpython-36.pycnu�[���3

�b�W��@s(ddlZddlZGdd�dejj�ZdS)�NcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�DHCIDz�DHCID record

    @ivar data: the data (the content of the RR is opaque as far as the
    DNS is concerned)
    @type data: string
    @see: RFC 4701�datacstt|�j||�||_dS)N)�superr�__init__r)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/DHCID.pyr szDHCID.__init__NTcKstjj|j�S)N)�dns�rdataZ
_base64ifyr)r�origin�
relativize�kwr
r
r�to_text$sz
DHCID.to_textc
Cs`g}x:|j�j�}|j�rP|j�s,tjj�|j|jj	��qWdj
|�}tj|�}	||||	�S)N�)
�getZunescapeZ
is_eol_or_eofZ
is_identifierrZ	exception�SyntaxError�append�value�encode�join�base64Z	b64decode)
�clsrr�tokrrZchunks�tZb64rr
r
r�	from_text's

zDHCID.from_textcCs|j|j�dS)N)�writer)r�file�compressrr
r
r�to_wire5sz
DHCID.to_wirecCs ||||�j�}||||�S)N)Zunwrap)rrrZwireZcurrentZrdlenrrr
r
r�	from_wire8szDHCID.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr!r"�
__classcell__r
r
)r	rrs

r)rZ
dns.exceptionrr
ZRdatarr
r
r
r�<module>sPKl�\\m9Mrr4rdtypes/IN/__pycache__/NSAP_PTR.cpython-36.opt-1.pycnu�[���3

�b�W}�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�NSAP_PTRzNSAP-PTR recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/NSAP_PTR.pyrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZUncompressedNSrrrrr�<module>sPKl�\
����-rdtypes/IN/__pycache__/A.cpython-36.opt-1.pycnu�[���3

�b�W=�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�AznA record.

    @ivar address: an IPv4 address
    @type address: string (in the standard "dotted quad" format)�addresscs(tt|�j||�tjj|�||_dS)N)�superr�__init__�dns�ipv4�	inet_atonr)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/A.pyrsz
A.__init__NTcKs|jS)N)r)r	�origin�
relativize�kwr
r
r�to_text%sz	A.to_textcCs|j�}|j�||||�S)N)Zget_identifierZget_eol)�clsr
r�tokrrrr
r
r�	from_text(szA.from_textcCs|jtjj|j��dS)N)�writerrrr)r	�file�compressrr
r
r�to_wire.sz	A.to_wirecCs(tjj||||��j�}||||�S)N)rrZ	inet_ntoa�decode)rr
rZwireZcurrentZrdlenrrr
r
r�	from_wire1szA.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr�
__classcell__r
r
)rrrs

r)Z
dns.exceptionrZdns.ipv4Z	dns.rdataZ
dns.tokenizerZrdataZRdatarr
r
r
r�<module>sPKl�\S
�4rdtypes/IN/__pycache__/__init__.cpython-36.opt-1.pycnu�[���3

�b�W��@s"dZddddddddd	d
dgZdS)
zClass IN rdata type classes.�AZAAAAZAPLZDHCIDZKXZNAPTRZNSAPZNSAP_PTRZPXZSRVZWKSN)�__doc__�__all__�rr�/usr/lib/python3.6/__init__.py�<module>sPKl�\��g��
�
/rdtypes/IN/__pycache__/WKS.cpython-36.opt-1.pycnu�[���3

�b�W��@sXddlZddlZddlZddlZddlmZejd�Zejd�Z	Gdd�dej
j�ZdS)�N)�xrange�tcp�udpcsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�WKSz�WKS record

    @ivar address: the address
    @type address: string
    @ivar protocol: the protocol
    @type protocol: int
    @ivar bitmap: the bitmap
    @type bitmap: string
    @see: RFC 1035�address�protocol�bitmapcs>tt|�j||�||_||_t|t�s4t|�|_n||_dS)N)�superr�__init__rr�
isinstance�	bytearrayr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/WKS.pyr
)s
zWKS.__init__NTc	Kszg}xXtdt|j��D]D}|j|}x4tdd�D]&}|d|?@r0|jt|d|��q0WqWdj|�}d|j|j|fS)Nr��� z%s %d %s)r�lenr�append�str�joinrr)	r
�origin�
relativize�kw�bits�iZbyte�j�textrrr�to_text2s

zWKS.to_textcCs|j�}|j�}|j�r"t|�}n
tj|�}t�}x�|j�j�}	|	j�rJP|	j	j�r`t|	j	�}
n8|t
krx|tkrxtd��|t
kr�d}nd}tj
|	j	|�}
|
d}t|�}
|
|dkr�x t|
|d�D]}|jd�q�W||d|
d?B||<q4Wtjj|�}||||||�S)Nzprotocol must be TCP or UDPrrr�rr)Z
get_string�isdigit�int�socket�getprotobynamer�getZunescapeZ
is_eol_or_eof�value�
_proto_udp�
_proto_tcp�NotImplementedErrorZ
getservbynamerrr�dns�rdataZ_truncate_bitmap)�clsrr�tokrrrrr�tokenZservZ
protocol_textr�lrrrr�	from_text<s4


z
WKS.from_textcCs<|jtjj|j��tjd|j�}|j|�|j|j�dS)Nz!B)	�writer,�ipv4Z	inet_atonr�struct�packrr)r
�file�compressrrrrr�to_wire\s
zWKS.to_wirec
Csjtjj|||d��}tjd||d|d��\}|d7}|d8}||||�j�}	||||||	�S)N�z!B�)r,r4Z	inet_ntoar5�unpackZunwrap)
r.rrZwireZcurrentZrdlenrrrrrrr�	from_wirebsz
WKS.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r
r!�classmethodr2r9r=�
__classcell__rr)rrrs

	


r)
r%r5Zdns.ipv4r,Z	dns.rdataZdns._compatrr&r*r)r-ZRdatarrrrr�<module>s

PKl�\٣��*rdtypes/IN/__pycache__/AAAA.cpython-36.pycnu�[���3

�b�W��@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�AAAAzhAAAA record.

    @ivar address: an IPv6 address
    @type address: string (in the standard IPv6 format)�addresscs.tt|�j||�tjjtjj|�||_dS)N)�superr�__init__�dns�inet�	inet_pton�AF_INET6r)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/AAAA.pyrsz
AAAA.__init__NTcKs|jS)N)r)r
�origin�
relativize�kwrrr�to_text%szAAAA.to_textcCs|j�}|j�||||�S)N)Zget_identifierZget_eol)�clsrr�tokrrrrrr�	from_text(szAAAA.from_textcCs|jtjjtjj|j��dS)N)�writerrrr	r)r
�file�compressrrrr�to_wire.szAAAA.to_wirecCs*tjjtjj||||��}||||�S)N)rrZ	inet_ntopr	)rrrZwireZcurrentZrdlenrrrrr�	from_wire1szAAAA.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr�
__classcell__rr)r
rrs

r)Z
dns.exceptionrZdns.inetZ	dns.rdataZ
dns.tokenizerZrdataZRdatarrrrr�<module>sPKl�\��g��
�
)rdtypes/IN/__pycache__/WKS.cpython-36.pycnu�[���3

�b�W��@sXddlZddlZddlZddlZddlmZejd�Zejd�Z	Gdd�dej
j�ZdS)�N)�xrange�tcp�udpcsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�WKSz�WKS record

    @ivar address: the address
    @type address: string
    @ivar protocol: the protocol
    @type protocol: int
    @ivar bitmap: the bitmap
    @type bitmap: string
    @see: RFC 1035�address�protocol�bitmapcs>tt|�j||�||_||_t|t�s4t|�|_n||_dS)N)�superr�__init__rr�
isinstance�	bytearrayr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/WKS.pyr
)s
zWKS.__init__NTc	Kszg}xXtdt|j��D]D}|j|}x4tdd�D]&}|d|?@r0|jt|d|��q0WqWdj|�}d|j|j|fS)Nr��� z%s %d %s)r�lenr�append�str�joinrr)	r
�origin�
relativize�kw�bits�iZbyte�j�textrrr�to_text2s

zWKS.to_textcCs|j�}|j�}|j�r"t|�}n
tj|�}t�}x�|j�j�}	|	j�rJP|	j	j�r`t|	j	�}
n8|t
krx|tkrxtd��|t
kr�d}nd}tj
|	j	|�}
|
d}t|�}
|
|dkr�x t|
|d�D]}|jd�q�W||d|
d?B||<q4Wtjj|�}||||||�S)Nzprotocol must be TCP or UDPrrr�rr)Z
get_string�isdigit�int�socket�getprotobynamer�getZunescapeZ
is_eol_or_eof�value�
_proto_udp�
_proto_tcp�NotImplementedErrorZ
getservbynamerrr�dns�rdataZ_truncate_bitmap)�clsrr�tokrrrrr�tokenZservZ
protocol_textr�lrrrr�	from_text<s4


z
WKS.from_textcCs<|jtjj|j��tjd|j�}|j|�|j|j�dS)Nz!B)	�writer,�ipv4Z	inet_atonr�struct�packrr)r
�file�compressrrrrr�to_wire\s
zWKS.to_wirec
Csjtjj|||d��}tjd||d|d��\}|d7}|d8}||||�j�}	||||||	�S)N�z!B�)r,r4Z	inet_ntoar5�unpackZunwrap)
r.rrZwireZcurrentZrdlenrrrrrrr�	from_wirebsz
WKS.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r
r!�classmethodr2r9r=�
__classcell__rr)rrrs

	


r)
r%r5Zdns.ipv4r,Z	dns.rdataZdns._compatrr&r*r)r-ZRdatarrrrr�<module>s

PKl�\"�ݯ!	!	(rdtypes/IN/__pycache__/PX.cpython-36.pycnu�[���3

�b�WB
�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsdeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
ddd�Z�ZS)�PXz�PX record.

    @ivar preference: the preference value
    @type preference: int
    @ivar map822: the map822 name
    @type map822: dns.name.Name object
    @ivar mapx400: the mapx400 name
    @type mapx400: dns.name.Name object
    @see: RFC 2163�
preference�map822�mapx400cs(tt|�j||�||_||_||_dS)N)�superr�__init__rrr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/PX.pyr%szPX.__init__NTcKs,|jj||�}|jj||�}d|j||fS)Nz%d %s %s)r�choose_relativityrr)r�origin�
relativize�kwrrrrr
�to_text+sz
PX.to_textc	CsJ|j�}|j�}|j||�}|jd�}|j||�}|j�||||||�S)N)Z
get_uint16Zget_namerZget_eol)	�clsr	r
�tokrrrrrrrr
�	from_text0s
zPX.from_textcCs<tjd|j�}|j|�|jj|d|�|jj|d|�dS)Nz!H)�struct�packr�writer�to_wirer)r�file�compressrZprefrrr
r:s
z
PX.to_wirecCs�tjd|||d��\}|d7}|d8}tjj|d||�|�\}}	|	|krXtjj�||	7}||	8}|dk	rz|j|�}tjj|d||�|�\}
}	|	|kr�tjj�|dk	r�|
j|�}
||||||
�S)Nz!H�)r�unpack�dns�name�	from_wireZ	exceptionZ	FormErrorr)rr	r
ZwireZcurrentZrdlenrrrZcusedrrrr
r @s$



zPX.from_wirecCs$|jj||�|_|jj||�|_dS)N)rrr)rrrrrr
rUszPX.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr r�
__classcell__rr)rr
rs


	
r)rZ
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarrrrr
�<module>sPKl�\�����/rdtypes/IN/__pycache__/SRV.cpython-36.opt-1.pycnu�[���3

�b�W��@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsfeZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
ddd�Z�ZS)�SRVaSRV record

    @ivar priority: the priority
    @type priority: int
    @ivar weight: the weight
    @type weight: int
    @ivar port: the port of the service
    @type port: int
    @ivar target: the target host
    @type target: dns.name.Name object
    @see: RFC 2782�priority�weight�port�targetcs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__��/usr/lib/python3.6/SRV.pyr's
zSRV.__init__NTcKs$|jj||�}d|j|j|j|fS)Nz%d %d %d %s)r�choose_relativityrrr)r	�origin�
relativize�kwrr
r
r�to_text.szSRV.to_textc
CsH|j�}|j�}|j�}|jd�}	|	j||�}	|j�|||||||	�S)N)Z
get_uint16Zget_namerZget_eol)
�clsr
r�tokrrrrrrr
r
r�	from_text3s
z
SRV.from_textcCs4tjd|j|j|j�}|j|�|jj|||�dS)Nz!HHH)�struct�packrrr�writer�to_wire)r	�file�compressrZ
three_intsr
r
rr=s
zSRV.to_wirecCs�tjd|||d��\}}}	|d7}|d8}tjj|d||�|�\}
}||kr\tjj�|dk	rn|
j|�}
||||||	|
�S)Nz!HHH�)r�unpack�dns�name�	from_wireZ	exceptionZ	FormErrorr)rr
rZwireZcurrentZrdlenrrrrrZcusedr
r
rr!Bs

z
SRV.from_wirecCs|jj||�|_dS)N)rr)r	rrr
r
rrPszSRV.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr!r�
__classcell__r
r
)rrrs
	

r)rZ
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarr
r
r
r�<module>sPKl�\"�ݯ!	!	.rdtypes/IN/__pycache__/PX.cpython-36.opt-1.pycnu�[���3

�b�WB
�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsdeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
ddd�Z�ZS)�PXz�PX record.

    @ivar preference: the preference value
    @type preference: int
    @ivar map822: the map822 name
    @type map822: dns.name.Name object
    @ivar mapx400: the mapx400 name
    @type mapx400: dns.name.Name object
    @see: RFC 2163�
preference�map822�mapx400cs(tt|�j||�||_||_||_dS)N)�superr�__init__rrr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/PX.pyr%szPX.__init__NTcKs,|jj||�}|jj||�}d|j||fS)Nz%d %s %s)r�choose_relativityrr)r�origin�
relativize�kwrrrrr
�to_text+sz
PX.to_textc	CsJ|j�}|j�}|j||�}|jd�}|j||�}|j�||||||�S)N)Z
get_uint16Zget_namerZget_eol)	�clsr	r
�tokrrrrrrrr
�	from_text0s
zPX.from_textcCs<tjd|j�}|j|�|jj|d|�|jj|d|�dS)Nz!H)�struct�packr�writer�to_wirer)r�file�compressrZprefrrr
r:s
z
PX.to_wirecCs�tjd|||d��\}|d7}|d8}tjj|d||�|�\}}	|	|krXtjj�||	7}||	8}|dk	rz|j|�}tjj|d||�|�\}
}	|	|kr�tjj�|dk	r�|
j|�}
||||||
�S)Nz!H�)r�unpack�dns�name�	from_wireZ	exceptionZ	FormErrorr)rr	r
ZwireZcurrentZrdlenrrrZcusedrrrr
r @s$



zPX.from_wirecCs$|jj||�|_|jj||�|_dS)N)rrr)rrrrrr
rUszPX.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr r�
__classcell__rr)rr
rs


	
r)rZ
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarrrrr
�<module>sPKl�\g���*rdtypes/IN/__pycache__/NSAP.cpython-36.pycnu�[���3

�b�W�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�NSAPzTNSAP record.

    @ivar address: a NASP
    @type address: string
    @see: RFC 1706�addresscstt|�j||�||_dS)N)�superr�__init__r)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/NSAP.pyr!sz
NSAP.__init__NTcKsdtj|j�j�S)Nz0x%s)�binasciiZhexlifyr�decode)r�origin�
relativize�kwr
r
r�to_text%szNSAP.to_textcCsv|j�}|j�|dd�dkr,tjjd��|dd�jdd�}t|�ddkr\tjjd��tj|j	��}||||�S)Nr�Z0xzstring does not start with 0x�.�zhexstring has odd length)
Z
get_stringZget_eol�dnsZ	exception�SyntaxError�replace�lenrZ	unhexlify�encode)�clsrr�tokrrrr
r
r�	from_text(szNSAP.from_textcCs|j|j�dS)N)�writer)r�file�compressrr
r
r�to_wire4szNSAP.to_wirecCs ||||�j�}||||�S)N)Zunwrap)rrrZwireZcurrentZrdlenrrr
r
r�	from_wire7szNSAP.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr r!�
__classcell__r
r
)r	rrs

r)rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZrdataZRdatarr
r
r
r�<module>sPKl�\
����'rdtypes/IN/__pycache__/A.cpython-36.pycnu�[���3

�b�W=�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�AznA record.

    @ivar address: an IPv4 address
    @type address: string (in the standard "dotted quad" format)�addresscs(tt|�j||�tjj|�||_dS)N)�superr�__init__�dns�ipv4�	inet_atonr)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/A.pyrsz
A.__init__NTcKs|jS)N)r)r	�origin�
relativize�kwr
r
r�to_text%sz	A.to_textcCs|j�}|j�||||�S)N)Zget_identifierZget_eol)�clsr
r�tokrrrr
r
r�	from_text(szA.from_textcCs|jtjj|j��dS)N)�writerrrr)r	�file�compressrr
r
r�to_wire.sz	A.to_wirecCs(tjj||||��j�}||||�S)N)rrZ	inet_ntoa�decode)rr
rZwireZcurrentZrdlenrrr
r
r�	from_wire1szA.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr�
__classcell__r
r
)rrrs

r)Z
dns.exceptionrZdns.ipv4Z	dns.rdataZ
dns.tokenizerZrdataZRdatarr
r
r
r�<module>sPKl�\/"��ttrdtypes/IN/APL.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct
import binascii

import dns.exception
import dns.inet
import dns.rdata
import dns.tokenizer
from dns._compat import xrange


class APLItem(object):

    """An APL list item.

    @ivar family: the address family (IANA address family registry)
    @type family: int
    @ivar negation: is this item negated?
    @type negation: bool
    @ivar address: the address
    @type address: string
    @ivar prefix: the prefix length
    @type prefix: int
    """

    __slots__ = ['family', 'negation', 'address', 'prefix']

    def __init__(self, family, negation, address, prefix):
        self.family = family
        self.negation = negation
        self.address = address
        self.prefix = prefix

    def __str__(self):
        if self.negation:
            return "!%d:%s/%s" % (self.family, self.address, self.prefix)
        else:
            return "%d:%s/%s" % (self.family, self.address, self.prefix)

    def to_wire(self, file):
        if self.family == 1:
            address = dns.inet.inet_pton(dns.inet.AF_INET, self.address)
        elif self.family == 2:
            address = dns.inet.inet_pton(dns.inet.AF_INET6, self.address)
        else:
            address = binascii.unhexlify(self.address)
        #
        # Truncate least significant zero bytes.
        #
        last = 0
        for i in xrange(len(address) - 1, -1, -1):
            if address[i] != chr(0):
                last = i + 1
                break
        address = address[0: last]
        l = len(address)
        assert l < 128
        if self.negation:
            l |= 0x80
        header = struct.pack('!HBB', self.family, self.prefix, l)
        file.write(header)
        file.write(address)


class APL(dns.rdata.Rdata):

    """APL record.

    @ivar items: a list of APL items
    @type items: list of APL_Item
    @see: RFC 3123"""

    __slots__ = ['items']

    def __init__(self, rdclass, rdtype, items):
        super(APL, self).__init__(rdclass, rdtype)
        self.items = items

    def to_text(self, origin=None, relativize=True, **kw):
        return ' '.join(map(str, self.items))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        items = []
        while 1:
            token = tok.get().unescape()
            if token.is_eol_or_eof():
                break
            item = token.value
            if item[0] == '!':
                negation = True
                item = item[1:]
            else:
                negation = False
            (family, rest) = item.split(':', 1)
            family = int(family)
            (address, prefix) = rest.split('/', 1)
            prefix = int(prefix)
            item = APLItem(family, negation, address, prefix)
            items.append(item)

        return cls(rdclass, rdtype, items)

    def to_wire(self, file, compress=None, origin=None):
        for item in self.items:
            item.to_wire(file)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        items = []
        while 1:
            if rdlen == 0:
                break
            if rdlen < 4:
                raise dns.exception.FormError
            header = struct.unpack('!HBB', wire[current: current + 4])
            afdlen = header[2]
            if afdlen > 127:
                negation = True
                afdlen -= 128
            else:
                negation = False
            current += 4
            rdlen -= 4
            if rdlen < afdlen:
                raise dns.exception.FormError
            address = wire[current: current + afdlen].unwrap()
            l = len(address)
            if header[0] == 1:
                if l < 4:
                    address += '\x00' * (4 - l)
                address = dns.inet.inet_ntop(dns.inet.AF_INET, address)
            elif header[0] == 2:
                if l < 16:
                    address += '\x00' * (16 - l)
                address = dns.inet.inet_ntop(dns.inet.AF_INET6, address)
            else:
                #
                # This isn't really right according to the RFC, but it
                # seems better than throwing an exception
                #
                address = address.encode('hex_codec')
            current += afdlen
            rdlen -= afdlen
            item = APLItem(header[0], negation, address, header[1])
            items.append(item)
        return cls(rdclass, rdtype, items)
PKl�\RJ6r��rdtypes/IN/__init__.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Class IN rdata type classes."""

__all__ = [
    'A',
    'AAAA',
    'APL',
    'DHCID',
    'KX',
    'NAPTR',
    'NSAP',
    'NSAP_PTR',
    'PX',
    'SRV',
    'WKS',
]
PKl�\��2�11rdtypes/IN/IPSECKEY.pynu�[���# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct
import base64

import dns.exception
import dns.inet
import dns.name


class IPSECKEY(dns.rdata.Rdata):

    """IPSECKEY record

    @ivar precedence: the precedence for this key data
    @type precedence: int
    @ivar gateway_type: the gateway type
    @type gateway_type: int
    @ivar algorithm: the algorithm to use
    @type algorithm: int
    @ivar gateway: the public key
    @type gateway: None, IPv4 address, IPV6 address, or domain name
    @ivar key: the public key
    @type key: string
    @see: RFC 4025"""

    __slots__ = ['precedence', 'gateway_type', 'algorithm', 'gateway', 'key']

    def __init__(self, rdclass, rdtype, precedence, gateway_type, algorithm,
                 gateway, key):
        super(IPSECKEY, self).__init__(rdclass, rdtype)
        if gateway_type == 0:
            if gateway != '.' and gateway is not None:
                raise SyntaxError('invalid gateway for gateway type 0')
            gateway = None
        elif gateway_type == 1:
            # check that it's OK
            dns.inet.inet_pton(dns.inet.AF_INET, gateway)
        elif gateway_type == 2:
            # check that it's OK
            dns.inet.inet_pton(dns.inet.AF_INET6, gateway)
        elif gateway_type == 3:
            pass
        else:
            raise SyntaxError(
                'invalid IPSECKEY gateway type: %d' % gateway_type)
        self.precedence = precedence
        self.gateway_type = gateway_type
        self.algorithm = algorithm
        self.gateway = gateway
        self.key = key

    def to_text(self, origin=None, relativize=True, **kw):
        if self.gateway_type == 0:
            gateway = '.'
        elif self.gateway_type == 1:
            gateway = self.gateway
        elif self.gateway_type == 2:
            gateway = self.gateway
        elif self.gateway_type == 3:
            gateway = str(self.gateway.choose_relativity(origin, relativize))
        else:
            raise ValueError('invalid gateway type')
        return '%d %d %d %s %s' % (self.precedence, self.gateway_type,
                                   self.algorithm, gateway,
                                   dns.rdata._base64ify(self.key))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        precedence = tok.get_uint8()
        gateway_type = tok.get_uint8()
        algorithm = tok.get_uint8()
        if gateway_type == 3:
            gateway = tok.get_name().choose_relativity(origin, relativize)
        else:
            gateway = tok.get_string()
        chunks = []
        while 1:
            t = tok.get().unescape()
            if t.is_eol_or_eof():
                break
            if not t.is_identifier():
                raise dns.exception.SyntaxError
            chunks.append(t.value.encode())
        b64 = b''.join(chunks)
        key = base64.b64decode(b64)
        return cls(rdclass, rdtype, precedence, gateway_type, algorithm,
                   gateway, key)

    def to_wire(self, file, compress=None, origin=None):
        header = struct.pack("!BBB", self.precedence, self.gateway_type,
                             self.algorithm)
        file.write(header)
        if self.gateway_type == 0:
            pass
        elif self.gateway_type == 1:
            file.write(dns.inet.inet_pton(dns.inet.AF_INET, self.gateway))
        elif self.gateway_type == 2:
            file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.gateway))
        elif self.gateway_type == 3:
            self.gateway.to_wire(file, None, origin)
        else:
            raise ValueError('invalid gateway type')
        file.write(self.key)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        if rdlen < 3:
            raise dns.exception.FormError
        header = struct.unpack('!BBB', wire[current: current + 3])
        gateway_type = header[1]
        current += 3
        rdlen -= 3
        if gateway_type == 0:
            gateway = None
        elif gateway_type == 1:
            gateway = dns.inet.inet_ntop(dns.inet.AF_INET,
                                         wire[current: current + 4])
            current += 4
            rdlen -= 4
        elif gateway_type == 2:
            gateway = dns.inet.inet_ntop(dns.inet.AF_INET6,
                                         wire[current: current + 16])
            current += 16
            rdlen -= 16
        elif gateway_type == 3:
            (gateway, cused) = dns.name.from_wire(wire[: current + rdlen],
                                                  current)
            current += cused
            rdlen -= cused
        else:
            raise dns.exception.FormError('invalid IPSECKEY gateway type')
        key = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, header[0], gateway_type, header[2],
                   gateway, key)
PKl�\����rdtypes/IN/DHCID.pynu�[���# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import base64

import dns.exception


class DHCID(dns.rdata.Rdata):

    """DHCID record

    @ivar data: the data (the content of the RR is opaque as far as the
    DNS is concerned)
    @type data: string
    @see: RFC 4701"""

    __slots__ = ['data']

    def __init__(self, rdclass, rdtype, data):
        super(DHCID, self).__init__(rdclass, rdtype)
        self.data = data

    def to_text(self, origin=None, relativize=True, **kw):
        return dns.rdata._base64ify(self.data)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        chunks = []
        while 1:
            t = tok.get().unescape()
            if t.is_eol_or_eof():
                break
            if not t.is_identifier():
                raise dns.exception.SyntaxError
            chunks.append(t.value.encode())
        b64 = b''.join(chunks)
        data = base64.b64decode(b64)
        return cls(rdclass, rdtype, data)

    def to_wire(self, file, compress=None, origin=None):
        file.write(self.data)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        data = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, data)
PKl�\��4==rdtypes/IN/A.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.exception
import dns.ipv4
import dns.rdata
import dns.tokenizer


class A(dns.rdata.Rdata):

    """A record.

    @ivar address: an IPv4 address
    @type address: string (in the standard "dotted quad" format)"""

    __slots__ = ['address']

    def __init__(self, rdclass, rdtype, address):
        super(A, self).__init__(rdclass, rdtype)
        # check that it's OK
        dns.ipv4.inet_aton(address)
        self.address = address

    def to_text(self, origin=None, relativize=True, **kw):
        return self.address

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        address = tok.get_identifier()
        tok.get_eol()
        return cls(rdclass, rdtype, address)

    def to_wire(self, file, compress=None, origin=None):
        file.write(dns.ipv4.inet_aton(self.address))

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        address = dns.ipv4.inet_ntoa(wire[current: current + rdlen]).decode()
        return cls(rdclass, rdtype, address)
PKl�\m��B
B
rdtypes/IN/PX.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.name


class PX(dns.rdata.Rdata):

    """PX record.

    @ivar preference: the preference value
    @type preference: int
    @ivar map822: the map822 name
    @type map822: dns.name.Name object
    @ivar mapx400: the mapx400 name
    @type mapx400: dns.name.Name object
    @see: RFC 2163"""

    __slots__ = ['preference', 'map822', 'mapx400']

    def __init__(self, rdclass, rdtype, preference, map822, mapx400):
        super(PX, self).__init__(rdclass, rdtype)
        self.preference = preference
        self.map822 = map822
        self.mapx400 = mapx400

    def to_text(self, origin=None, relativize=True, **kw):
        map822 = self.map822.choose_relativity(origin, relativize)
        mapx400 = self.mapx400.choose_relativity(origin, relativize)
        return '%d %s %s' % (self.preference, map822, mapx400)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        preference = tok.get_uint16()
        map822 = tok.get_name()
        map822 = map822.choose_relativity(origin, relativize)
        mapx400 = tok.get_name(None)
        mapx400 = mapx400.choose_relativity(origin, relativize)
        tok.get_eol()
        return cls(rdclass, rdtype, preference, map822, mapx400)

    def to_wire(self, file, compress=None, origin=None):
        pref = struct.pack("!H", self.preference)
        file.write(pref)
        self.map822.to_wire(file, None, origin)
        self.mapx400.to_wire(file, None, origin)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (preference, ) = struct.unpack('!H', wire[current: current + 2])
        current += 2
        rdlen -= 2
        (map822, cused) = dns.name.from_wire(wire[: current + rdlen],
                                             current)
        if cused > rdlen:
            raise dns.exception.FormError
        current += cused
        rdlen -= cused
        if origin is not None:
            map822 = map822.relativize(origin)
        (mapx400, cused) = dns.name.from_wire(wire[: current + rdlen],
                                              current)
        if cused != rdlen:
            raise dns.exception.FormError
        if origin is not None:
            mapx400 = mapx400.relativize(origin)
        return cls(rdclass, rdtype, preference, map822, mapx400)

    def choose_relativity(self, origin=None, relativize=True):
        self.map822 = self.map822.choose_relativity(origin, relativize)
        self.mapx400 = self.mapx400.choose_relativity(origin, relativize)
PKl�\�qQ��rdtypes/IN/WKS.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import socket
import struct

import dns.ipv4
import dns.rdata
from dns._compat import xrange

_proto_tcp = socket.getprotobyname('tcp')
_proto_udp = socket.getprotobyname('udp')


class WKS(dns.rdata.Rdata):

    """WKS record

    @ivar address: the address
    @type address: string
    @ivar protocol: the protocol
    @type protocol: int
    @ivar bitmap: the bitmap
    @type bitmap: string
    @see: RFC 1035"""

    __slots__ = ['address', 'protocol', 'bitmap']

    def __init__(self, rdclass, rdtype, address, protocol, bitmap):
        super(WKS, self).__init__(rdclass, rdtype)
        self.address = address
        self.protocol = protocol
        if not isinstance(bitmap, bytearray):
            self.bitmap = bytearray(bitmap)
        else:
            self.bitmap = bitmap

    def to_text(self, origin=None, relativize=True, **kw):
        bits = []
        for i in xrange(0, len(self.bitmap)):
            byte = self.bitmap[i]
            for j in xrange(0, 8):
                if byte & (0x80 >> j):
                    bits.append(str(i * 8 + j))
        text = ' '.join(bits)
        return '%s %d %s' % (self.address, self.protocol, text)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        address = tok.get_string()
        protocol = tok.get_string()
        if protocol.isdigit():
            protocol = int(protocol)
        else:
            protocol = socket.getprotobyname(protocol)
        bitmap = bytearray()
        while 1:
            token = tok.get().unescape()
            if token.is_eol_or_eof():
                break
            if token.value.isdigit():
                serv = int(token.value)
            else:
                if protocol != _proto_udp and protocol != _proto_tcp:
                    raise NotImplementedError("protocol must be TCP or UDP")
                if protocol == _proto_udp:
                    protocol_text = "udp"
                else:
                    protocol_text = "tcp"
                serv = socket.getservbyname(token.value, protocol_text)
            i = serv // 8
            l = len(bitmap)
            if l < i + 1:
                for j in xrange(l, i + 1):
                    bitmap.append(0)
            bitmap[i] = bitmap[i] | (0x80 >> (serv % 8))
        bitmap = dns.rdata._truncate_bitmap(bitmap)
        return cls(rdclass, rdtype, address, protocol, bitmap)

    def to_wire(self, file, compress=None, origin=None):
        file.write(dns.ipv4.inet_aton(self.address))
        protocol = struct.pack('!B', self.protocol)
        file.write(protocol)
        file.write(self.bitmap)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        address = dns.ipv4.inet_ntoa(wire[current: current + 4])
        protocol, = struct.unpack('!B', wire[current + 4: current + 5])
        current += 5
        rdlen -= 5
        bitmap = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, address, protocol, bitmap)
PKl�\�2���rdtypes/IN/SRV.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.name


class SRV(dns.rdata.Rdata):

    """SRV record

    @ivar priority: the priority
    @type priority: int
    @ivar weight: the weight
    @type weight: int
    @ivar port: the port of the service
    @type port: int
    @ivar target: the target host
    @type target: dns.name.Name object
    @see: RFC 2782"""

    __slots__ = ['priority', 'weight', 'port', 'target']

    def __init__(self, rdclass, rdtype, priority, weight, port, target):
        super(SRV, self).__init__(rdclass, rdtype)
        self.priority = priority
        self.weight = weight
        self.port = port
        self.target = target

    def to_text(self, origin=None, relativize=True, **kw):
        target = self.target.choose_relativity(origin, relativize)
        return '%d %d %d %s' % (self.priority, self.weight, self.port,
                                target)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        priority = tok.get_uint16()
        weight = tok.get_uint16()
        port = tok.get_uint16()
        target = tok.get_name(None)
        target = target.choose_relativity(origin, relativize)
        tok.get_eol()
        return cls(rdclass, rdtype, priority, weight, port, target)

    def to_wire(self, file, compress=None, origin=None):
        three_ints = struct.pack("!HHH", self.priority, self.weight, self.port)
        file.write(three_ints)
        self.target.to_wire(file, compress, origin)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (priority, weight, port) = struct.unpack('!HHH',
                                                 wire[current: current + 6])
        current += 6
        rdlen -= 6
        (target, cused) = dns.name.from_wire(wire[: current + rdlen],
                                             current)
        if cused != rdlen:
            raise dns.exception.FormError
        if origin is not None:
            target = target.relativize(origin)
        return cls(rdclass, rdtype, priority, weight, port, target)

    def choose_relativity(self, origin=None, relativize=True):
        self.target = self.target.choose_relativity(origin, relativize)
PKl�\�W��vvrdtypes/IN/NAPTR.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.name
import dns.rdata
from dns._compat import xrange, text_type


def _write_string(file, s):
    l = len(s)
    assert l < 256
    file.write(struct.pack('!B', l))
    file.write(s)


def _sanitize(value):
    if isinstance(value, text_type):
        return value.encode()
    return value


class NAPTR(dns.rdata.Rdata):

    """NAPTR record

    @ivar order: order
    @type order: int
    @ivar preference: preference
    @type preference: int
    @ivar flags: flags
    @type flags: string
    @ivar service: service
    @type service: string
    @ivar regexp: regular expression
    @type regexp: string
    @ivar replacement: replacement name
    @type replacement: dns.name.Name object
    @see: RFC 3403"""

    __slots__ = ['order', 'preference', 'flags', 'service', 'regexp',
                 'replacement']

    def __init__(self, rdclass, rdtype, order, preference, flags, service,
                 regexp, replacement):
        super(NAPTR, self).__init__(rdclass, rdtype)
        self.flags = _sanitize(flags)
        self.service = _sanitize(service)
        self.regexp = _sanitize(regexp)
        self.order = order
        self.preference = preference
        self.replacement = replacement

    def to_text(self, origin=None, relativize=True, **kw):
        replacement = self.replacement.choose_relativity(origin, relativize)
        return '%d %d "%s" "%s" "%s" %s' % \
               (self.order, self.preference,
                dns.rdata._escapify(self.flags),
                dns.rdata._escapify(self.service),
                dns.rdata._escapify(self.regexp),
                replacement)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        order = tok.get_uint16()
        preference = tok.get_uint16()
        flags = tok.get_string()
        service = tok.get_string()
        regexp = tok.get_string()
        replacement = tok.get_name()
        replacement = replacement.choose_relativity(origin, relativize)
        tok.get_eol()
        return cls(rdclass, rdtype, order, preference, flags, service,
                   regexp, replacement)

    def to_wire(self, file, compress=None, origin=None):
        two_ints = struct.pack("!HH", self.order, self.preference)
        file.write(two_ints)
        _write_string(file, self.flags)
        _write_string(file, self.service)
        _write_string(file, self.regexp)
        self.replacement.to_wire(file, compress, origin)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (order, preference) = struct.unpack('!HH', wire[current: current + 4])
        current += 4
        rdlen -= 4
        strings = []
        for i in xrange(3):
            l = wire[current]
            current += 1
            rdlen -= 1
            if l > rdlen or rdlen < 0:
                raise dns.exception.FormError
            s = wire[current: current + l].unwrap()
            current += l
            rdlen -= l
            strings.append(s)
        (replacement, cused) = dns.name.from_wire(wire[: current + rdlen],
                                                  current)
        if cused != rdlen:
            raise dns.exception.FormError
        if origin is not None:
            replacement = replacement.relativize(origin)
        return cls(rdclass, rdtype, order, preference, strings[0], strings[1],
                   strings[2], replacement)

    def choose_relativity(self, origin=None, relativize=True):
        self.replacement = self.replacement.choose_relativity(origin,
                                                              relativize)
PKl�\�;�Jrdtypes/IN/NSAP.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import binascii

import dns.exception
import dns.rdata
import dns.tokenizer


class NSAP(dns.rdata.Rdata):

    """NSAP record.

    @ivar address: a NASP
    @type address: string
    @see: RFC 1706"""

    __slots__ = ['address']

    def __init__(self, rdclass, rdtype, address):
        super(NSAP, self).__init__(rdclass, rdtype)
        self.address = address

    def to_text(self, origin=None, relativize=True, **kw):
        return "0x%s" % binascii.hexlify(self.address).decode()

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        address = tok.get_string()
        tok.get_eol()
        if address[0:2] != '0x':
            raise dns.exception.SyntaxError('string does not start with 0x')
        address = address[2:].replace('.', '')
        if len(address) % 2 != 0:
            raise dns.exception.SyntaxError('hexstring has odd length')
        address = binascii.unhexlify(address.encode())
        return cls(rdclass, rdtype, address)

    def to_wire(self, file, compress=None, origin=None):
        file.write(self.address)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        address = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, address)
PKl�\�����rdtypes/IN/AAAA.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.exception
import dns.inet
import dns.rdata
import dns.tokenizer


class AAAA(dns.rdata.Rdata):

    """AAAA record.

    @ivar address: an IPv6 address
    @type address: string (in the standard IPv6 format)"""

    __slots__ = ['address']

    def __init__(self, rdclass, rdtype, address):
        super(AAAA, self).__init__(rdclass, rdtype)
        # check that it's OK
        dns.inet.inet_pton(dns.inet.AF_INET6, address)
        self.address = address

    def to_text(self, origin=None, relativize=True, **kw):
        return self.address

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        address = tok.get_identifier()
        tok.get_eol()
        return cls(rdclass, rdtype, address)

    def to_wire(self, file, compress=None, origin=None):
        file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.address))

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        address = dns.inet.inet_ntop(dns.inet.AF_INET6,
                                     wire[current: current + rdlen])
        return cls(rdclass, rdtype, address)
PKl�\�7��qqrdtypes/IN/KX.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.mxbase


class KX(dns.rdtypes.mxbase.UncompressedMX):

    """KX record"""
PKl�\�0}}rdtypes/IN/NSAP_PTR.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.nsbase


class NSAP_PTR(dns.rdtypes.nsbase.UncompressedNS):

    """NSAP-PTR record"""
PKl�\��V�553rdtypes/__pycache__/dnskeybase.cpython-36.opt-1.pycnu�[���3

�b�W#�@s�ddlZddlZddlZddlZddlZdddddgZdZdZd	Z	eee	d
�Z
edd�e
j�D��Z
d
d�Zdd�ZGdd�dejj�ZdS)�N�SEP�REVOKE�ZONE�flags_to_text_set�flags_from_text_set���)rrrccs|]\}}||fVqdS)N�)�.0�x�yr
r
� /usr/lib/python3.6/dnskeybase.py�	<genexpr>)srcCsLt�}d}x<|dkrF||@r<tj|�}|s2t|�}|j|�|dK}qW|S)zCConvert a DNSKEY flags value to set texts
    @rtype: set([string])ri�)�set�_flag_by_value�get�hex�add)�flagsZ	flags_set�mask�textr
r
rr,s


cCsHd}x>|D]6}y|t|7}Wq
tk
r>td|��Yq
Xq
W|S)zNConvert set of DNSKEY flag mnemonic texts to DNSKEY flag value
    @rtype: intrz!DNSKEY flag '%s' is not supported)�
_flag_by_text�KeyError�NotImplementedError)Z	texts_setrrr
r
rr<s
csdeZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
dd�Z�ZS)�
DNSKEYBasea?Base class for rdata that is like a DNSKEY record

    @ivar flags: the key flags
    @type flags: int
    @ivar protocol: the protocol for which this key may be used
    @type protocol: int
    @ivar algorithm: the algorithm used for the key
    @type algorithm: int
    @ivar key: the public key
    @type key: stringr�protocol�	algorithm�keycs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__r
rr Ys
zDNSKEYBase.__init__NTcKs d|j|j|jtjj|j�fS)Nz%d %d %d %s)rrr�dns�rdataZ
_base64ifyr)r!�origin�
relativize�kwr
r
r�to_text`szDNSKEYBase.to_textc
Cs�|j�}|j�}tjj|j��}g}	x:|j�j�}
|
j�r<P|
j	�sLtj
j�|	j|
j
j��q&Wdj|	�}tj|�}|||||||�S)N�)Z
get_uint16Z	get_uint8r%ZdnssecZalgorithm_from_textZ
get_stringrZunescapeZ
is_eol_or_eofZ
is_identifier�	exception�SyntaxError�append�value�encode�join�base64Z	b64decode)
�clsr"r#�tokr'r(rrrZchunks�tZb64rr
r
r�	from_textds

zDNSKEYBase.from_textcCs0tjd|j|j|j�}|j|�|j|j�dS)Nz!HBB)�struct�packrrr�writer)r!�file�compressr'�headerr
r
r�to_wireus
zDNSKEYBase.to_wirec	Csj|dkrtjj�tjd|||d��}|d7}|d8}||||�j�}||||d|d|d|�S)N�z!HBBrr�)r%r,Z	FormErrorr7�unpackZunwrap)	r3r"r#ZwireZcurrentZrdlenr'r<rr
r
r�	from_wirezszDNSKEYBase.from_wirecCs
t|j�S)zGConvert a DNSKEY flags value to set texts
        @rtype: set([string]))rr)r!r
r
rr�szDNSKEYBase.flags_to_text_set)NT)NT)NN)N)
�__name__�
__module__�__qualname__�__doc__�	__slots__r r*�classmethodr6r=rAr�
__classcell__r
r
)r$rrJs


r)r2r7Z
dns.exceptionr%Z
dns.dnssecZ	dns.rdata�__all__rrrr�dict�itemsrrrr&ZRdatarr
r
r
r�<module>s PKl�\v�~u
u
/rdtypes/__pycache__/nsbase.cpython-36.opt-1.pycnu�[���3

�b�W#�@sPdZddlmZddlZddlZddlZGdd�dejj�Z	Gdd�de	�Z
dS)zNS-like base classes.�)�BytesIONcsjeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	dd
d�Z
eddd��Zddd�Z�Z
S)�NSBasez�Base class for rdata that is like an NS record.

    @ivar target: the target name of the rdata
    @type target: dns.name.Name object�targetcstt|�j||�||_dS)N)�superr�__init__r)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/nsbase.pyr"szNSBase.__init__NTcKs|jj||�}t|�S)N)r�choose_relativity�str)r�origin�
relativize�kwrrrr�to_text&szNSBase.to_textcCs(|j�}|j||�}|j�||||�S)N)Zget_namer
Zget_eol)�clsrr	�tokrrrrrr�	from_text*szNSBase.from_textcCs|jj|||�dS)N)r�to_wire)r�file�compressrrrrr1szNSBase.to_wirecCs|jj|�S)N)r�
to_digestable)rrrrrr4szNSBase.to_digestablec	CsLtjj|d||�|�\}}||kr.tjj�|dk	r@|j|�}||||�S)N)�dns�name�	from_wireZ	exceptionZ	FormErrorr)	rrr	ZwireZcurrentZrdlenrrZcusedrrrr7s

zNSBase.from_wirecCs|jj||�|_dS)N)rr
)rrrrrrr
AszNSBase.choose_relativity)NT)NT)NN)N)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrrrr
�
__classcell__rr)r
rrs


	rcs,eZdZdZd�fdd�	Zddd�Z�ZS)	�UncompressedNSz�Base class for rdata that is like an NS record, but whose name
    is not compressed when convert to DNS wire format, and whose
    digestable form is not downcased.Ncstt|�j|d|�dS)N)rr$r)rrrr)r
rrrKszUncompressedNS.to_wirecCst�}|j|d|�|j�S)N)rr�getvalue)rr�frrrrNszUncompressedNS.to_digestable)NN)N)rrrr rrr#rr)r
rr$Esr$)r �iorZ
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarr$rrrr�<module>s,PKl�\t���0rdtypes/__pycache__/txtbase.cpython-36.opt-1.pycnu�[���3

�b�W��@sHdZddlZddlZddlZddlZddlmZGdd�dejj	�Z
dS)zTXT-like base class.�N)�binary_typecsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�TXTBasez�Base class for rdata that is like a TXT record

    @ivar strings: the text strings
    @type strings: list of string
    @see: RFC 1035�stringscs4tt|�j||�t|t�r"|g}|dd�|_dS)N)�superr�__init__�
isinstance�strr)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/txtbase.pyr$s
zTXTBase.__init__NTcKs8d}d}x*|jD] }|d|tjj|�f7}d}qW|S)N�z%s"%s"� )r�dns�rdataZ	_escapify)r	�origin�
relativize�kwZtxt�prefix�sr
r
r�to_text*szTXTBase.to_textc	Cs�g}xz|j�j�}|j�rP|j�p*|j�s8tjjd��t|j	�dkrRtjjd��|j	}t
|t�rn|j|�q|j|j
��qWt|�dkr�tjj�||||�S)Nzexpected a string�zstring too longr)�getZunescapeZ
is_eol_or_eofZis_quoted_stringZ
is_identifierr�	exception�SyntaxError�len�valuerr�append�encodeZ
UnexpectedEnd)	�clsr
r�tokrrr�tokenrr
r
r�	from_text2s 
zTXTBase.from_textcCs8x2|jD](}t|�}|jtjd|��|j|�qWdS)Nz!B)rr�write�struct�pack)r	�file�compressrr�lr
r
r�to_wireFszTXTBase.to_wirec
Cstg}xb|dkrf||}|d7}|d8}||kr6tjj�||||�j�}	||7}||8}|j|	�qW||||�S)Nr�)rrZ	FormErrorZunwrapr)
r!r
rZwireZcurrentZrdlenrrr*rr
r
r�	from_wireMs
zTXTBase.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr$r+r-�
__classcell__r
r
)rrrs

r)r1r&Z
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZdns._compatrrZRdatarr
r
r
r�<module>sPKl�\��C�
�
)rdtypes/__pycache__/mxbase.cpython-36.pycnu�[���3

�b�WL�@shdZddlmZddlZddlZddlZddlZGdd�dejj	�Z
Gdd�de
�ZGdd	�d	e
�ZdS)
zMX-like base classes.�)�BytesIONcsleZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	ddd�Z
eddd��Zddd�Z�Z
S)�MXBasez�Base class for rdata that is like an MX record.

    @ivar preference: the preference value
    @type preference: int
    @ivar exchange: the exchange name
    @type exchange: dns.name.Name object�
preference�exchangecs"tt|�j||�||_||_dS)N)�superr�__init__rr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/mxbase.pyr%szMXBase.__init__NTcKs|jj||�}d|j|fS)Nz%d %s)r�choose_relativityr)r�origin�
relativize�kwrrrr
�to_text*szMXBase.to_textcCs2|j�}|j�}|j||�}|j�|||||�S)N)Z
get_uint16Zget_namerZget_eol)�clsr	r
�tokrrrrrrr
�	from_text.s
zMXBase.from_textcCs,tjd|j�}|j|�|jj|||�dS)Nz!H)�struct�packr�writer�to_wire)r�file�compressrZprefrrr
r6s
zMXBase.to_wirecCstjd|j�|jj|�S)Nz!H)rrrr�
to_digestable)rrrrr
r;szMXBase.to_digestablec
Csxtjd|||d��\}|d7}|d8}tjj|d||�|�\}}	|	|krXtjj�|dk	rj|j|�}|||||�S)Nz!H�)r�unpack�dns�name�	from_wireZ	exceptionZ	FormErrorr)
rr	r
ZwireZcurrentZrdlenrrrZcusedrrr
r!?s

zMXBase.from_wirecCs|jj||�|_dS)N)rr)rrrrrr
rLszMXBase.choose_relativity)NT)NT)NN)N)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrrr!r�
__classcell__rr)rr
rs


rcs,eZdZdZd�fdd�	Zddd�Z�ZS)	�UncompressedMXz�Base class for rdata that is like an MX record, but whose name
    is not compressed when converted to DNS wire format, and whose
    digestable form is not downcased.Ncstt|�j|d|�dS)N)rr)r)rrrr)rrr
rVszUncompressedMX.to_wirecCst�}|j|d|�|j�S)N)rr�getvalue)rr�frrr
rYszUncompressedMX.to_digestable)NN)N)r"r#r$r%rrr(rr)rr
r)Psr)cs"eZdZdZd�fdd�	Z�ZS)�UncompressedDowncasingMXzuBase class for rdata that is like an MX record, but whose name
    is not compressed when convert to DNS wire format.Ncstt|�j|d|�dS)N)rr,r)rrrr)rrr
rdsz UncompressedDowncasingMX.to_wire)NN)r"r#r$r%rr(rr)rr
r,_sr,)
r%�iorrZ
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarr)r,rrrr
�<module>s6PKl�\��C�
�
/rdtypes/__pycache__/mxbase.cpython-36.opt-1.pycnu�[���3

�b�WL�@shdZddlmZddlZddlZddlZddlZGdd�dejj	�Z
Gdd�de
�ZGdd	�d	e
�ZdS)
zMX-like base classes.�)�BytesIONcsleZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	ddd�Z
eddd��Zddd�Z�Z
S)�MXBasez�Base class for rdata that is like an MX record.

    @ivar preference: the preference value
    @type preference: int
    @ivar exchange: the exchange name
    @type exchange: dns.name.Name object�
preference�exchangecs"tt|�j||�||_||_dS)N)�superr�__init__rr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/mxbase.pyr%szMXBase.__init__NTcKs|jj||�}d|j|fS)Nz%d %s)r�choose_relativityr)r�origin�
relativize�kwrrrr
�to_text*szMXBase.to_textcCs2|j�}|j�}|j||�}|j�|||||�S)N)Z
get_uint16Zget_namerZget_eol)�clsr	r
�tokrrrrrrr
�	from_text.s
zMXBase.from_textcCs,tjd|j�}|j|�|jj|||�dS)Nz!H)�struct�packr�writer�to_wire)r�file�compressrZprefrrr
r6s
zMXBase.to_wirecCstjd|j�|jj|�S)Nz!H)rrrr�
to_digestable)rrrrr
r;szMXBase.to_digestablec
Csxtjd|||d��\}|d7}|d8}tjj|d||�|�\}}	|	|krXtjj�|dk	rj|j|�}|||||�S)Nz!H�)r�unpack�dns�name�	from_wireZ	exceptionZ	FormErrorr)
rr	r
ZwireZcurrentZrdlenrrrZcusedrrr
r!?s

zMXBase.from_wirecCs|jj||�|_dS)N)rr)rrrrrr
rLszMXBase.choose_relativity)NT)NT)NN)N)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrrr!r�
__classcell__rr)rr
rs


rcs,eZdZdZd�fdd�	Zddd�Z�ZS)	�UncompressedMXz�Base class for rdata that is like an MX record, but whose name
    is not compressed when converted to DNS wire format, and whose
    digestable form is not downcased.Ncstt|�j|d|�dS)N)rr)r)rrrr)rrr
rVszUncompressedMX.to_wirecCst�}|j|d|�|j�S)N)rr�getvalue)rr�frrr
rYszUncompressedMX.to_digestable)NN)N)r"r#r$r%rrr(rr)rr
r)Psr)cs"eZdZdZd�fdd�	Z�ZS)�UncompressedDowncasingMXzuBase class for rdata that is like an MX record, but whose name
    is not compressed when convert to DNS wire format.Ncstt|�j|d|�dS)N)rr,r)rrrr)rrr
rdsz UncompressedDowncasingMX.to_wire)NN)r"r#r$r%rr(rr)rr
r,_sr,)
r%�iorrZ
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarr)r,rrrr
�<module>s6PKl�\��B1		*rdtypes/__pycache__/txtbase.cpython-36.pycnu�[���3

�b�W��@sHdZddlZddlZddlZddlZddlmZGdd�dejj	�Z
dS)zTXT-like base class.�N)�binary_typecsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�TXTBasez�Base class for rdata that is like a TXT record

    @ivar strings: the text strings
    @type strings: list of string
    @see: RFC 1035�stringscs4tt|�j||�t|t�r"|g}|dd�|_dS)N)�superr�__init__�
isinstance�strr)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/txtbase.pyr$s
zTXTBase.__init__NTcKs8d}d}x*|jD] }|d|tjj|�f7}d}qW|S)N�z%s"%s"� )r�dns�rdataZ	_escapify)r	�origin�
relativize�kwZtxt�prefix�sr
r
r�to_text*szTXTBase.to_textc	Cs�g}xz|j�j�}|j�rP|j�p*|j�s8tjjd��t|j	�dkrRtjjd��|j	}t
|t�rn|j|�q|j|j
��qWt|�dkr�tjj�||||�S)Nzexpected a string�zstring too longr)�getZunescapeZ
is_eol_or_eofZis_quoted_stringZ
is_identifierr�	exception�SyntaxError�len�valuerr�append�encodeZ
UnexpectedEnd)	�clsr
r�tokrrr�tokenrr
r
r�	from_text2s 
zTXTBase.from_textcCsDx>|jD]4}t|�}|dks t�|jtjd|��|j|�qWdS)N�z!B)rr�AssertionError�write�struct�pack)r	�file�compressrr�lr
r
r�to_wireFs
zTXTBase.to_wirec
Cstg}xb|dkrf||}|d7}|d8}||kr6tjj�||||�j�}	||7}||8}|j|	�qW||||�S)Nr�)rrZ	FormErrorZunwrapr)
r!r
rZwireZcurrentZrdlenrrr,rr
r
r�	from_wireMs
zTXTBase.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr$r-r/�
__classcell__r
r
)rrrs

r)r3r(Z
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZdns._compatrrZRdatarr
r
r
r�<module>sPKl�\��acc0rdtypes/__pycache__/euibase.cpython-36.opt-1.pycnu�[���3

�b�W�
�@s4ddlZddlZddlmZGdd�dejj�ZdS)�N)�xrangecsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�EUIBasez�EUIxx record

    @ivar fingerprint: xx-bit Extended Unique Identifier (EUI-xx)
    @type fingerprint: string
    @see: rfc7043.txt�euicsFtt|�j||�t|�|jkr<tjjd|jd|jf��||_dS)Nz EUI%s rdata has to have %s bytes�)	�superr�__init__�len�byte_len�dns�	exceptionZ	FormErrorr)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/euibase.pyr$s
zEUIBase.__init__NTcKstjj|jdd�jdd�S)N�)Z	chunksize� �-)r
�rdataZ_hexifyr�replace)r�origin�
relativize�kwrrr�to_text+szEUIBase.to_textcCs�|j�}|j�t|�|jkr0tjjd|j��td|jddd�}x(|D] }||dkrLtjjd|��qLW|j	dd�}yt
j|j��}	Wn:t
tfk
r�}
ztjjdt|
���WYdd}
~
XnX||||	�S)	Nz"Input text must have %s charactersr��rzDash expected at position %s�zHex decoding error: %s)Z
get_stringZget_eolrZtext_lenr
r�SyntaxErrorrr	r�binasciiZ	unhexlify�encode�
ValueError�	TypeError�str)�clsr
r�tokrr�textZexpected_dash_idxs�i�dataZexrrr�	from_text.s 
&zEUIBase.from_textcCs|j|j�dS)N)�writer)r�file�compressrrrr�to_wireAszEUIBase.to_wirecCs ||||�j�}||||�S)N)Zunwrap)r$r
rZwireZcurrentZrdlenrrrrr�	from_wireDszEUIBase.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr)r-r.�
__classcell__rr)rrrs

r)rZ	dns.rdatar
Zdns._compatrrZRdatarrrrr�<module>sPKl�\�E�� 	 	/rdtypes/__pycache__/dsbase.cpython-36.opt-1.pycnu�[���3

�b�W�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�Ncs\eZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
�ZS)�DSBaseaJBase class for rdata that is like a DS record

    @ivar key_tag: the key tag
    @type key_tag: int
    @ivar algorithm: the algorithm
    @type algorithm: int
    @ivar digest_type: the digest type
    @type digest_type: int
    @ivar digest: the digest
    @type digest: int
    @see: draft-ietf-dnsext-delegation-signer-14.txt�key_tag�	algorithm�digest_type�digestcs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__��/usr/lib/python3.6/dsbase.pyr's
zDSBase.__init__NTcKs$d|j|j|jtjj|jdd�fS)Nz%d %d %d %s�)Z	chunksize)rrr�dns�rdataZ_hexifyr)r	�origin�
relativize�kwr
r
r�to_text/s

zDSBase.to_textcCs~|j�}|j�}|j�}g}	x:|j�j�}
|
j�r4P|
j�sDtjj�|	j	|
j
j��qWdj|	�}t
j|�}|||||||�S)N�)Z
get_uint16Z	get_uint8�getZunescapeZ
is_eol_or_eofZ
is_identifierrZ	exception�SyntaxError�append�value�encode�join�binasciiZ	unhexlify)�clsr
r�tokrrrrrZchunks�trr
r
r�	from_text5s

zDSBase.from_textcCs0tjd|j|j|j�}|j|�|j|j�dS)Nz!HBB)�struct�packrrr�writer)r	�file�compressr�headerr
r
r�to_wireGs
zDSBase.to_wirec	CsZtjd|||d��}|d7}|d8}||||�j�}||||d|d|d|�S)Nz!HBB�r��)r"�unpackZunwrap)	rr
rZwireZcurrentZrdlenrr'rr
r
r�	from_wireMs
zDSBase.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr!r(r-�
__classcell__r
r
)rrrs

r)r"rZ	dns.rdatarZ
dns.rdatatyperZRdatarr
r
r
r�<module>sPKl�\z�\J��+rdtypes/__pycache__/__init__.cpython-36.pycnu�[���3

�b�W�@sdZdddddgZdS)zDNS rdata type classes�ANY�INZeuibaseZmxbaseZnsbaseN)�__doc__�__all__�rr�/usr/lib/python3.6/__init__.py�<module>s
PKl�\v�~u
u
)rdtypes/__pycache__/nsbase.cpython-36.pycnu�[���3

�b�W#�@sPdZddlmZddlZddlZddlZGdd�dejj�Z	Gdd�de	�Z
dS)zNS-like base classes.�)�BytesIONcsjeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	dd
d�Z
eddd��Zddd�Z�Z
S)�NSBasez�Base class for rdata that is like an NS record.

    @ivar target: the target name of the rdata
    @type target: dns.name.Name object�targetcstt|�j||�||_dS)N)�superr�__init__r)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/nsbase.pyr"szNSBase.__init__NTcKs|jj||�}t|�S)N)r�choose_relativity�str)r�origin�
relativize�kwrrrr�to_text&szNSBase.to_textcCs(|j�}|j||�}|j�||||�S)N)Zget_namer
Zget_eol)�clsrr	�tokrrrrrr�	from_text*szNSBase.from_textcCs|jj|||�dS)N)r�to_wire)r�file�compressrrrrr1szNSBase.to_wirecCs|jj|�S)N)r�
to_digestable)rrrrrr4szNSBase.to_digestablec	CsLtjj|d||�|�\}}||kr.tjj�|dk	r@|j|�}||||�S)N)�dns�name�	from_wireZ	exceptionZ	FormErrorr)	rrr	ZwireZcurrentZrdlenrrZcusedrrrr7s

zNSBase.from_wirecCs|jj||�|_dS)N)rr
)rrrrrrr
AszNSBase.choose_relativity)NT)NT)NN)N)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrrrr
�
__classcell__rr)r
rrs


	rcs,eZdZdZd�fdd�	Zddd�Z�ZS)	�UncompressedNSz�Base class for rdata that is like an NS record, but whose name
    is not compressed when convert to DNS wire format, and whose
    digestable form is not downcased.Ncstt|�j|d|�dS)N)rr$r)rrrr)r
rrrKszUncompressedNS.to_wirecCst�}|j|d|�|j�S)N)rr�getvalue)rr�frrrrNszUncompressedNS.to_digestable)NN)N)rrrr rrr#rr)r
rr$Esr$)r �iorZ
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarr$rrrr�<module>s,PKl�\z�\J��1rdtypes/__pycache__/__init__.cpython-36.opt-1.pycnu�[���3

�b�W�@sdZdddddgZdS)zDNS rdata type classes�ANY�INZeuibaseZmxbaseZnsbaseN)�__doc__�__all__�rr�/usr/lib/python3.6/__init__.py�<module>s
PKl�\��acc*rdtypes/__pycache__/euibase.cpython-36.pycnu�[���3

�b�W�
�@s4ddlZddlZddlmZGdd�dejj�ZdS)�N)�xrangecsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�EUIBasez�EUIxx record

    @ivar fingerprint: xx-bit Extended Unique Identifier (EUI-xx)
    @type fingerprint: string
    @see: rfc7043.txt�euicsFtt|�j||�t|�|jkr<tjjd|jd|jf��||_dS)Nz EUI%s rdata has to have %s bytes�)	�superr�__init__�len�byte_len�dns�	exceptionZ	FormErrorr)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/euibase.pyr$s
zEUIBase.__init__NTcKstjj|jdd�jdd�S)N�)Z	chunksize� �-)r
�rdataZ_hexifyr�replace)r�origin�
relativize�kwrrr�to_text+szEUIBase.to_textcCs�|j�}|j�t|�|jkr0tjjd|j��td|jddd�}x(|D] }||dkrLtjjd|��qLW|j	dd�}yt
j|j��}	Wn:t
tfk
r�}
ztjjdt|
���WYdd}
~
XnX||||	�S)	Nz"Input text must have %s charactersr��rzDash expected at position %s�zHex decoding error: %s)Z
get_stringZget_eolrZtext_lenr
r�SyntaxErrorrr	r�binasciiZ	unhexlify�encode�
ValueError�	TypeError�str)�clsr
r�tokrr�textZexpected_dash_idxs�i�dataZexrrr�	from_text.s 
&zEUIBase.from_textcCs|j|j�dS)N)�writer)r�file�compressrrrr�to_wireAszEUIBase.to_wirecCs ||||�j�}||||�S)N)Zunwrap)r$r
rZwireZcurrentZrdlenrrrrr�	from_wireDszEUIBase.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr)r-r.�
__classcell__rr)rrrs

r)rZ	dns.rdatar
Zdns._compatrrZRdatarrrrr�<module>sPKl�\��V�55-rdtypes/__pycache__/dnskeybase.cpython-36.pycnu�[���3

�b�W#�@s�ddlZddlZddlZddlZddlZdddddgZdZdZd	Z	eee	d
�Z
edd�e
j�D��Z
d
d�Zdd�ZGdd�dejj�ZdS)�N�SEP�REVOKE�ZONE�flags_to_text_set�flags_from_text_set���)rrrccs|]\}}||fVqdS)N�)�.0�x�yr
r
� /usr/lib/python3.6/dnskeybase.py�	<genexpr>)srcCsLt�}d}x<|dkrF||@r<tj|�}|s2t|�}|j|�|dK}qW|S)zCConvert a DNSKEY flags value to set texts
    @rtype: set([string])ri�)�set�_flag_by_value�get�hex�add)�flagsZ	flags_set�mask�textr
r
rr,s


cCsHd}x>|D]6}y|t|7}Wq
tk
r>td|��Yq
Xq
W|S)zNConvert set of DNSKEY flag mnemonic texts to DNSKEY flag value
    @rtype: intrz!DNSKEY flag '%s' is not supported)�
_flag_by_text�KeyError�NotImplementedError)Z	texts_setrrr
r
rr<s
csdeZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
dd�Z�ZS)�
DNSKEYBasea?Base class for rdata that is like a DNSKEY record

    @ivar flags: the key flags
    @type flags: int
    @ivar protocol: the protocol for which this key may be used
    @type protocol: int
    @ivar algorithm: the algorithm used for the key
    @type algorithm: int
    @ivar key: the public key
    @type key: stringr�protocol�	algorithm�keycs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__r
rr Ys
zDNSKEYBase.__init__NTcKs d|j|j|jtjj|j�fS)Nz%d %d %d %s)rrr�dns�rdataZ
_base64ifyr)r!�origin�
relativize�kwr
r
r�to_text`szDNSKEYBase.to_textc
Cs�|j�}|j�}tjj|j��}g}	x:|j�j�}
|
j�r<P|
j	�sLtj
j�|	j|
j
j��q&Wdj|	�}tj|�}|||||||�S)N�)Z
get_uint16Z	get_uint8r%ZdnssecZalgorithm_from_textZ
get_stringrZunescapeZ
is_eol_or_eofZ
is_identifier�	exception�SyntaxError�append�value�encode�join�base64Z	b64decode)
�clsr"r#�tokr'r(rrrZchunks�tZb64rr
r
r�	from_textds

zDNSKEYBase.from_textcCs0tjd|j|j|j�}|j|�|j|j�dS)Nz!HBB)�struct�packrrr�writer)r!�file�compressr'�headerr
r
r�to_wireus
zDNSKEYBase.to_wirec	Csj|dkrtjj�tjd|||d��}|d7}|d8}||||�j�}||||d|d|d|�S)N�z!HBBrr�)r%r,Z	FormErrorr7�unpackZunwrap)	r3r"r#ZwireZcurrentZrdlenr'r<rr
r
r�	from_wirezszDNSKEYBase.from_wirecCs
t|j�S)zGConvert a DNSKEY flags value to set texts
        @rtype: set([string]))rr)r!r
r
rr�szDNSKEYBase.flags_to_text_set)NT)NT)NN)N)
�__name__�
__module__�__qualname__�__doc__�	__slots__r r*�classmethodr6r=rAr�
__classcell__r
r
)r$rrJs


r)r2r7Z
dns.exceptionr%Z
dns.dnssecZ	dns.rdata�__all__rrrr�dict�itemsrrrr&ZRdatarr
r
r
r�<module>s PKl�\�E�� 	 	)rdtypes/__pycache__/dsbase.cpython-36.pycnu�[���3

�b�W�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�Ncs\eZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
�ZS)�DSBaseaJBase class for rdata that is like a DS record

    @ivar key_tag: the key tag
    @type key_tag: int
    @ivar algorithm: the algorithm
    @type algorithm: int
    @ivar digest_type: the digest type
    @type digest_type: int
    @ivar digest: the digest
    @type digest: int
    @see: draft-ietf-dnsext-delegation-signer-14.txt�key_tag�	algorithm�digest_type�digestcs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__��/usr/lib/python3.6/dsbase.pyr's
zDSBase.__init__NTcKs$d|j|j|jtjj|jdd�fS)Nz%d %d %d %s�)Z	chunksize)rrr�dns�rdataZ_hexifyr)r	�origin�
relativize�kwr
r
r�to_text/s

zDSBase.to_textcCs~|j�}|j�}|j�}g}	x:|j�j�}
|
j�r4P|
j�sDtjj�|	j	|
j
j��qWdj|	�}t
j|�}|||||||�S)N�)Z
get_uint16Z	get_uint8�getZunescapeZ
is_eol_or_eofZ
is_identifierrZ	exception�SyntaxError�append�value�encode�join�binasciiZ	unhexlify)�clsr
r�tokrrrrrZchunks�trr
r
r�	from_text5s

zDSBase.from_textcCs0tjd|j|j|j�}|j|�|j|j�dS)Nz!HBB)�struct�packrrr�writer)r	�file�compressr�headerr
r
r�to_wireGs
zDSBase.to_wirec	CsZtjd|||d��}|d7}|d8}||||�j�}||||d|d|d|�S)Nz!HBB�r��)r"�unpackZunwrap)	rr
rZwireZcurrentZrdlenrr'rr
r
r�	from_wireMs
zDSBase.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr!r(r-�
__classcell__r
r
)rrrs

r)r"rZ	dns.rdatarZ
dns.rdatatyperZRdatarr
r
r
r�<module>sPKl�\�$�##rdtypes/dnskeybase.pynu�[���# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import base64
import struct

import dns.exception
import dns.dnssec
import dns.rdata

# wildcard import
__all__ = ["SEP", "REVOKE", "ZONE",
           "flags_to_text_set", "flags_from_text_set"]

# flag constants
SEP = 0x0001
REVOKE = 0x0080
ZONE = 0x0100

_flag_by_text = {
    'SEP': SEP,
    'REVOKE': REVOKE,
    'ZONE': ZONE
}

# We construct the inverse mapping programmatically to ensure that we
# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
# would cause the mapping not to be true inverse.
_flag_by_value = dict((y, x) for x, y in _flag_by_text.items())


def flags_to_text_set(flags):
    """Convert a DNSKEY flags value to set texts
    @rtype: set([string])"""

    flags_set = set()
    mask = 0x1
    while mask <= 0x8000:
        if flags & mask:
            text = _flag_by_value.get(mask)
            if not text:
                text = hex(mask)
            flags_set.add(text)
        mask <<= 1
    return flags_set


def flags_from_text_set(texts_set):
    """Convert set of DNSKEY flag mnemonic texts to DNSKEY flag value
    @rtype: int"""

    flags = 0
    for text in texts_set:
        try:
            flags += _flag_by_text[text]
        except KeyError:
            raise NotImplementedError(
                "DNSKEY flag '%s' is not supported" % text)
    return flags


class DNSKEYBase(dns.rdata.Rdata):

    """Base class for rdata that is like a DNSKEY record

    @ivar flags: the key flags
    @type flags: int
    @ivar protocol: the protocol for which this key may be used
    @type protocol: int
    @ivar algorithm: the algorithm used for the key
    @type algorithm: int
    @ivar key: the public key
    @type key: string"""

    __slots__ = ['flags', 'protocol', 'algorithm', 'key']

    def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key):
        super(DNSKEYBase, self).__init__(rdclass, rdtype)
        self.flags = flags
        self.protocol = protocol
        self.algorithm = algorithm
        self.key = key

    def to_text(self, origin=None, relativize=True, **kw):
        return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm,
                                dns.rdata._base64ify(self.key))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        flags = tok.get_uint16()
        protocol = tok.get_uint8()
        algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
        chunks = []
        while 1:
            t = tok.get().unescape()
            if t.is_eol_or_eof():
                break
            if not t.is_identifier():
                raise dns.exception.SyntaxError
            chunks.append(t.value.encode())
        b64 = b''.join(chunks)
        key = base64.b64decode(b64)
        return cls(rdclass, rdtype, flags, protocol, algorithm, key)

    def to_wire(self, file, compress=None, origin=None):
        header = struct.pack("!HBB", self.flags, self.protocol, self.algorithm)
        file.write(header)
        file.write(self.key)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        if rdlen < 4:
            raise dns.exception.FormError
        header = struct.unpack('!HBB', wire[current: current + 4])
        current += 4
        rdlen -= 4
        key = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, header[0], header[1], header[2],
                   key)

    def flags_to_text_set(self):
        """Convert a DNSKEY flags value to set texts
        @rtype: set([string])"""
        return flags_to_text_set(self.flags)
PKl�\j_[�rdtypes/__init__.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS rdata type classes"""

__all__ = [
    'ANY',
    'IN',
    'euibase',
    'mxbase',
    'nsbase',
]
PKl�\@�eLLrdtypes/mxbase.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""MX-like base classes."""

from io import BytesIO
import struct

import dns.exception
import dns.rdata
import dns.name


class MXBase(dns.rdata.Rdata):

    """Base class for rdata that is like an MX record.

    @ivar preference: the preference value
    @type preference: int
    @ivar exchange: the exchange name
    @type exchange: dns.name.Name object"""

    __slots__ = ['preference', 'exchange']

    def __init__(self, rdclass, rdtype, preference, exchange):
        super(MXBase, self).__init__(rdclass, rdtype)
        self.preference = preference
        self.exchange = exchange

    def to_text(self, origin=None, relativize=True, **kw):
        exchange = self.exchange.choose_relativity(origin, relativize)
        return '%d %s' % (self.preference, exchange)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        preference = tok.get_uint16()
        exchange = tok.get_name()
        exchange = exchange.choose_relativity(origin, relativize)
        tok.get_eol()
        return cls(rdclass, rdtype, preference, exchange)

    def to_wire(self, file, compress=None, origin=None):
        pref = struct.pack("!H", self.preference)
        file.write(pref)
        self.exchange.to_wire(file, compress, origin)

    def to_digestable(self, origin=None):
        return struct.pack("!H", self.preference) + \
            self.exchange.to_digestable(origin)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (preference, ) = struct.unpack('!H', wire[current: current + 2])
        current += 2
        rdlen -= 2
        (exchange, cused) = dns.name.from_wire(wire[: current + rdlen],
                                               current)
        if cused != rdlen:
            raise dns.exception.FormError
        if origin is not None:
            exchange = exchange.relativize(origin)
        return cls(rdclass, rdtype, preference, exchange)

    def choose_relativity(self, origin=None, relativize=True):
        self.exchange = self.exchange.choose_relativity(origin, relativize)


class UncompressedMX(MXBase):

    """Base class for rdata that is like an MX record, but whose name
    is not compressed when converted to DNS wire format, and whose
    digestable form is not downcased."""

    def to_wire(self, file, compress=None, origin=None):
        super(UncompressedMX, self).to_wire(file, None, origin)

    def to_digestable(self, origin=None):
        f = BytesIO()
        self.to_wire(f, None, origin)
        return f.getvalue()


class UncompressedDowncasingMX(MXBase):

    """Base class for rdata that is like an MX record, but whose name
    is not compressed when convert to DNS wire format."""

    def to_wire(self, file, compress=None, origin=None):
        super(UncompressedDowncasingMX, self).to_wire(file, None, origin)
PKl�\e�B�rdtypes/dsbase.pynu�[���# Copyright (C) 2010, 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct
import binascii

import dns.rdata
import dns.rdatatype


class DSBase(dns.rdata.Rdata):

    """Base class for rdata that is like a DS record

    @ivar key_tag: the key tag
    @type key_tag: int
    @ivar algorithm: the algorithm
    @type algorithm: int
    @ivar digest_type: the digest type
    @type digest_type: int
    @ivar digest: the digest
    @type digest: int
    @see: draft-ietf-dnsext-delegation-signer-14.txt"""

    __slots__ = ['key_tag', 'algorithm', 'digest_type', 'digest']

    def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type,
                 digest):
        super(DSBase, self).__init__(rdclass, rdtype)
        self.key_tag = key_tag
        self.algorithm = algorithm
        self.digest_type = digest_type
        self.digest = digest

    def to_text(self, origin=None, relativize=True, **kw):
        return '%d %d %d %s' % (self.key_tag, self.algorithm,
                                self.digest_type,
                                dns.rdata._hexify(self.digest,
                                                  chunksize=128))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        key_tag = tok.get_uint16()
        algorithm = tok.get_uint8()
        digest_type = tok.get_uint8()
        chunks = []
        while 1:
            t = tok.get().unescape()
            if t.is_eol_or_eof():
                break
            if not t.is_identifier():
                raise dns.exception.SyntaxError
            chunks.append(t.value.encode())
        digest = b''.join(chunks)
        digest = binascii.unhexlify(digest)
        return cls(rdclass, rdtype, key_tag, algorithm, digest_type,
                   digest)

    def to_wire(self, file, compress=None, origin=None):
        header = struct.pack("!HBB", self.key_tag, self.algorithm,
                             self.digest_type)
        file.write(header)
        file.write(self.digest)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        header = struct.unpack("!HBB", wire[current: current + 4])
        current += 4
        rdlen -= 4
        digest = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, header[0], header[1], header[2], digest)
PKl�\!����rdtypes/txtbase.pynu�[���# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""TXT-like base class."""

import struct

import dns.exception
import dns.rdata
import dns.tokenizer
from dns._compat import binary_type


class TXTBase(dns.rdata.Rdata):

    """Base class for rdata that is like a TXT record

    @ivar strings: the text strings
    @type strings: list of string
    @see: RFC 1035"""

    __slots__ = ['strings']

    def __init__(self, rdclass, rdtype, strings):
        super(TXTBase, self).__init__(rdclass, rdtype)
        if isinstance(strings, str):
            strings = [strings]
        self.strings = strings[:]

    def to_text(self, origin=None, relativize=True, **kw):
        txt = ''
        prefix = ''
        for s in self.strings:
            txt += '%s"%s"' % (prefix, dns.rdata._escapify(s))
            prefix = ' '
        return txt

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        strings = []
        while 1:
            token = tok.get().unescape()
            if token.is_eol_or_eof():
                break
            if not (token.is_quoted_string() or token.is_identifier()):
                raise dns.exception.SyntaxError("expected a string")
            if len(token.value) > 255:
                raise dns.exception.SyntaxError("string too long")
            value = token.value
            if isinstance(value, binary_type):
                strings.append(value)
            else:
                strings.append(value.encode())
        if len(strings) == 0:
            raise dns.exception.UnexpectedEnd
        return cls(rdclass, rdtype, strings)

    def to_wire(self, file, compress=None, origin=None):
        for s in self.strings:
            l = len(s)
            assert l < 256
            file.write(struct.pack('!B', l))
            file.write(s)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        strings = []
        while rdlen > 0:
            l = wire[current]
            current += 1
            rdlen -= 1
            if l > rdlen:
                raise dns.exception.FormError
            s = wire[current: current + l].unwrap()
            current += l
            rdlen -= l
            strings.append(s)
        return cls(rdclass, rdtype, strings)
PKl�\z<�##rdtypes/nsbase.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""NS-like base classes."""

from io import BytesIO

import dns.exception
import dns.rdata
import dns.name


class NSBase(dns.rdata.Rdata):

    """Base class for rdata that is like an NS record.

    @ivar target: the target name of the rdata
    @type target: dns.name.Name object"""

    __slots__ = ['target']

    def __init__(self, rdclass, rdtype, target):
        super(NSBase, self).__init__(rdclass, rdtype)
        self.target = target

    def to_text(self, origin=None, relativize=True, **kw):
        target = self.target.choose_relativity(origin, relativize)
        return str(target)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        target = tok.get_name()
        target = target.choose_relativity(origin, relativize)
        tok.get_eol()
        return cls(rdclass, rdtype, target)

    def to_wire(self, file, compress=None, origin=None):
        self.target.to_wire(file, compress, origin)

    def to_digestable(self, origin=None):
        return self.target.to_digestable(origin)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (target, cused) = dns.name.from_wire(wire[: current + rdlen],
                                             current)
        if cused != rdlen:
            raise dns.exception.FormError
        if origin is not None:
            target = target.relativize(origin)
        return cls(rdclass, rdtype, target)

    def choose_relativity(self, origin=None, relativize=True):
        self.target = self.target.choose_relativity(origin, relativize)


class UncompressedNS(NSBase):

    """Base class for rdata that is like an NS record, but whose name
    is not compressed when convert to DNS wire format, and whose
    digestable form is not downcased."""

    def to_wire(self, file, compress=None, origin=None):
        super(UncompressedNS, self).to_wire(file, None, origin)

    def to_digestable(self, origin=None):
        f = BytesIO()
        self.to_wire(f, None, origin)
        return f.getvalue()
PKl�\���
�
rdtypes/euibase.pynu�[���# Copyright (C) 2015 Red Hat, Inc.
# Author: Petr Spacek <pspacek@redhat.com>
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import binascii

import dns.rdata
from dns._compat import xrange


class EUIBase(dns.rdata.Rdata):

    """EUIxx record

    @ivar fingerprint: xx-bit Extended Unique Identifier (EUI-xx)
    @type fingerprint: string
    @see: rfc7043.txt"""

    __slots__ = ['eui']
    # define these in subclasses
    # byte_len = 6  # 0123456789ab (in hex)
    # text_len = byte_len * 3 - 1  # 01-23-45-67-89-ab

    def __init__(self, rdclass, rdtype, eui):
        super(EUIBase, self).__init__(rdclass, rdtype)
        if len(eui) != self.byte_len:
            raise dns.exception.FormError('EUI%s rdata has to have %s bytes'
                                          % (self.byte_len * 8, self.byte_len))
        self.eui = eui

    def to_text(self, origin=None, relativize=True, **kw):
        return dns.rdata._hexify(self.eui, chunksize=2).replace(' ', '-')

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        text = tok.get_string()
        tok.get_eol()
        if len(text) != cls.text_len:
            raise dns.exception.SyntaxError(
                'Input text must have %s characters' % cls.text_len)
        expected_dash_idxs = xrange(2, cls.byte_len * 3 - 1, 3)
        for i in expected_dash_idxs:
            if text[i] != '-':
                raise dns.exception.SyntaxError('Dash expected at position %s'
                                                % i)
        text = text.replace('-', '')
        try:
            data = binascii.unhexlify(text.encode())
        except (ValueError, TypeError) as ex:
            raise dns.exception.SyntaxError('Hex decoding error: %s' % str(ex))
        return cls(rdclass, rdtype, data)

    def to_wire(self, file, compress=None, origin=None):
        file.write(self.eui)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        eui = wire[current:current + rdlen].unwrap()
        return cls(rdclass, rdtype, eui)
PKl�\CN�cGGrdtypes/ANY/X25.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.tokenizer
from dns._compat import text_type


class X25(dns.rdata.Rdata):

    """X25 record

    @ivar address: the PSDN address
    @type address: string
    @see: RFC 1183"""

    __slots__ = ['address']

    def __init__(self, rdclass, rdtype, address):
        super(X25, self).__init__(rdclass, rdtype)
        if isinstance(address, text_type):
            self.address = address.encode()
        else:
            self.address = address

    def to_text(self, origin=None, relativize=True, **kw):
        return '"%s"' % dns.rdata._escapify(self.address)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        address = tok.get_string()
        tok.get_eol()
        return cls(rdclass, rdtype, address)

    def to_wire(self, file, compress=None, origin=None):
        l = len(self.address)
        assert l < 256
        file.write(struct.pack('!B', l))
        file.write(self.address)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        l = wire[current]
        current += 1
        rdlen -= 1
        if l != rdlen:
            raise dns.exception.FormError
        address = wire[current: current + l].unwrap()
        return cls(rdclass, rdtype, address)
PKl�\y1s��rdtypes/ANY/GPOS.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.tokenizer
from dns._compat import long, text_type


def _validate_float_string(what):
    if what[0] == b'-'[0] or what[0] == b'+'[0]:
        what = what[1:]
    if what.isdigit():
        return
    (left, right) = what.split(b'.')
    if left == b'' and right == b'':
        raise dns.exception.FormError
    if not left == b'' and not left.decode().isdigit():
        raise dns.exception.FormError
    if not right == b'' and not right.decode().isdigit():
        raise dns.exception.FormError


def _sanitize(value):
    if isinstance(value, text_type):
        return value.encode()
    return value


class GPOS(dns.rdata.Rdata):

    """GPOS record

    @ivar latitude: latitude
    @type latitude: string
    @ivar longitude: longitude
    @type longitude: string
    @ivar altitude: altitude
    @type altitude: string
    @see: RFC 1712"""

    __slots__ = ['latitude', 'longitude', 'altitude']

    def __init__(self, rdclass, rdtype, latitude, longitude, altitude):
        super(GPOS, self).__init__(rdclass, rdtype)
        if isinstance(latitude, float) or \
           isinstance(latitude, int) or \
           isinstance(latitude, long):
            latitude = str(latitude)
        if isinstance(longitude, float) or \
           isinstance(longitude, int) or \
           isinstance(longitude, long):
            longitude = str(longitude)
        if isinstance(altitude, float) or \
           isinstance(altitude, int) or \
           isinstance(altitude, long):
            altitude = str(altitude)
        latitude = _sanitize(latitude)
        longitude = _sanitize(longitude)
        altitude = _sanitize(altitude)
        _validate_float_string(latitude)
        _validate_float_string(longitude)
        _validate_float_string(altitude)
        self.latitude = latitude
        self.longitude = longitude
        self.altitude = altitude

    def to_text(self, origin=None, relativize=True, **kw):
        return '%s %s %s' % (self.latitude.decode(),
                             self.longitude.decode(),
                             self.altitude.decode())

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        latitude = tok.get_string()
        longitude = tok.get_string()
        altitude = tok.get_string()
        tok.get_eol()
        return cls(rdclass, rdtype, latitude, longitude, altitude)

    def to_wire(self, file, compress=None, origin=None):
        l = len(self.latitude)
        assert l < 256
        file.write(struct.pack('!B', l))
        file.write(self.latitude)
        l = len(self.longitude)
        assert l < 256
        file.write(struct.pack('!B', l))
        file.write(self.longitude)
        l = len(self.altitude)
        assert l < 256
        file.write(struct.pack('!B', l))
        file.write(self.altitude)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        l = wire[current]
        current += 1
        rdlen -= 1
        if l > rdlen:
            raise dns.exception.FormError
        latitude = wire[current: current + l].unwrap()
        current += l
        rdlen -= l
        l = wire[current]
        current += 1
        rdlen -= 1
        if l > rdlen:
            raise dns.exception.FormError
        longitude = wire[current: current + l].unwrap()
        current += l
        rdlen -= l
        l = wire[current]
        current += 1
        rdlen -= 1
        if l != rdlen:
            raise dns.exception.FormError
        altitude = wire[current: current + l].unwrap()
        return cls(rdclass, rdtype, latitude, longitude, altitude)

    def _get_float_latitude(self):
        return float(self.latitude)

    def _set_float_latitude(self, value):
        self.latitude = str(value)

    float_latitude = property(_get_float_latitude, _set_float_latitude,
                              doc="latitude as a floating point value")

    def _get_float_longitude(self):
        return float(self.longitude)

    def _set_float_longitude(self, value):
        self.longitude = str(value)

    float_longitude = property(_get_float_longitude, _set_float_longitude,
                               doc="longitude as a floating point value")

    def _get_float_altitude(self):
        return float(self.altitude)

    def _set_float_altitude(self, value):
        self.altitude = str(value)

    float_altitude = property(_get_float_altitude, _set_float_altitude,
                              doc="altitude as a floating point value")
PKl�\ab4[[*rdtypes/ANY/__pycache__/DLV.cpython-36.pycnu�[���3

�b�W`�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�DLVz
DLV recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/DLV.pyrsr)Zdns.rdtypes.dsbaseZdnsZrdtypesZdsbaseZDSBaserrrrr�<module>sPKl�\����1rdtypes/ANY/__pycache__/TLSA.cpython-36.opt-1.pycnu�[���3

�b�W��@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�Ncs\eZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
�ZS)�TLSAa*TLSA record

    @ivar usage: The certificate usage
    @type usage: int
    @ivar selector: The selector field
    @type selector: int
    @ivar mtype: The 'matching type' field
    @type mtype: int
    @ivar cert: The 'Certificate Association Data' field
    @type cert: string
    @see: RFC 6698�usage�selector�mtype�certcs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__��/usr/lib/python3.6/TLSA.pyr's
z
TLSA.__init__NTcKs$d|j|j|jtjj|jdd�fS)Nz%d %d %d %s�)Z	chunksize)rrr�dns�rdataZ_hexifyr)r	�origin�
relativize�kwr
r
r�to_text/s

zTLSA.to_textcCs~|j�}|j�}|j�}g}	x:|j�j�}
|
j�r4P|
j�sDtjj�|	j|
j	j
��qWdj|	�}tj
|�}|||||||�S)N�)Z	get_uint8�getZunescapeZ
is_eol_or_eofZ
is_identifierrZ	exception�SyntaxError�append�value�encode�join�binasciiZ	unhexlify)�clsr
r�tokrrrrrZcert_chunks�trr
r
r�	from_text6s

zTLSA.from_textcCs0tjd|j|j|j�}|j|�|j|j�dS)Nz!BBB)�struct�packrrr�writer)r	�file�compressr�headerr
r
r�to_wireGs
zTLSA.to_wirec	CsZtjd|||d��}|d7}|d8}||||�j�}||||d|d|d|�S)Nz!BBB�r��)r"�unpackZunwrap)	rr
rZwireZcurrentZrdlenrr'rr
r
r�	from_wireLs
zTLSA.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr!r(r-�
__classcell__r
r
)rrrs

r)r"rZ	dns.rdatarZ
dns.rdatatyperZRdatarr
r
r
r�<module>sPKl�\ab4[[0rdtypes/ANY/__pycache__/DLV.cpython-36.opt-1.pycnu�[���3

�b�W`�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�DLVz
DLV recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/DLV.pyrsr)Zdns.rdtypes.dsbaseZdnsZrdtypesZdsbaseZDSBaserrrrr�<module>sPKl�\I��pp2rdtypes/ANY/__pycache__/CSYNC.cpython-36.opt-1.pycnu�[���3

�b�W$�@sLddlZddlZddlZddlZddlZddlmZGdd�dejj	�Z
dS)�N)�xrangecsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�CSYNCz�CSYNC record

    @ivar serial: the SOA serial number
    @type serial: int
    @ivar flags: the CSYNC flags
    @type flags: int
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples�serial�flags�windowscs(tt|�j||�||_||_||_dS)N)�superr�__init__rrr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/CSYNC.pyr%szCSYNC.__init__NTcKs�d}x�|jD]�\}}g}x`tdt|��D]N}||}	x@tdd�D]2}
|	d|
?@r@|jtjj|d|d|
��q@Wq(W|ddj|�7}qWd|j|j	|fS)N�r���� z%d %d%s)
rr�len�append�dns�	rdatatype�to_text�joinrr)r	�origin�
relativize�kw�text�window�bitmap�bits�i�byte�jr
r
rr+s
 z
CSYNC.to_textcCs@|j�}|j�}g}xZ|j�j�}	|	j�r,Ptjj|	j�}
|
dkrNtj	j
d��|
dkrbtj	j
d��|j|
�qW|j�d}d}d}
t
dd�}g}x�|D]|}
|
|
kr�q�|
}
|
d}||kr�|j||d|�f�t
dd�}|}|
d}|d}|d}|d	}||d
|?B||<q�W|j||d|�f�||||||�S)NrzCSYNC with bit 0i��zCSYNC with bit > 65535�� rr�r)Z
get_uint32Z
get_uint16�getZunescapeZ
is_eol_or_eofrr�	from_text�value�	exception�SyntaxErrorr�sort�	bytearray)�clsr
r�tokrrrrZrdtypes�tokenZnrdtyper�octetsZprior_rdtyperrZ
new_window�offsetr"�bitr
r
rr(8sF
zCSYNC.from_textcCsR|jtjd|j|j��x4|jD]*\}}|jtjd|t|���|j|�q WdS)Nz!IHz!BB)�write�struct�packrrrr)r	�file�compressrrrr
r
r�to_wire_sz
CSYNC.to_wirec
Cs|dkrtjjd��tjd|||d��\}}|d7}|d8}g}	x�|dkr�|dkrbtjjd��||}
||d}|dks�|dkr�tjjd��|d	7}|d	8}||kr�tjjd
��t||||�j��}||7}||8}|	j|
|f�qFW||||||	�S)N�zCSYNC too shortz!IHr�r&r%zbad CSYNC octets�zbad CSYNC bitmap length)rr*Z	FormErrorr5�unpackr-Zunwrapr)
r.r
rZwireZcurrentZrdlenrrrrrr1rr
r
r�	from_wirees,
zCSYNC.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr(r9r>�
__classcell__r
r
)rrrs	


&
r)r5Z
dns.exceptionrZ	dns.rdataZ
dns.rdatatypeZdns.nameZdns._compatrZrdataZRdatarr
r
r
r�<module>sPKl�\�UXTXX/rdtypes/ANY/__pycache__/DS.cpython-36.opt-1.pycnu�[���3

�b�Wi�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�DSz	DS recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/DS.pyrsr)Zdns.rdtypes.dsbaseZdnsZrdtypesZdsbaseZDSBaserrrrr�<module>sPKl�\^��0rdtypes/ANY/__pycache__/CAA.cpython-36.opt-1.pycnu�[���3

�b�W>
�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�CAAz�CAA (Certification Authority Authorization) record

    @ivar flags: the flags
    @type flags: int
    @ivar tag: the tag
    @type tag: string
    @ivar value: the value
    @type value: string
    @see: RFC 6844�flags�tag�valuecs(tt|�j||�||_||_||_dS)N)�superr�__init__rrr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/CAA.pyr%szCAA.__init__NTcKs$d|jtjj|j�tjj|j�fS)Nz
%u %s "%s")r�dns�rdataZ	_escapifyrr)r�origin�
relativize�kwrrr
�to_text+szCAA.to_textc	Cs\|j�}|j�j�}t|�dkr,tjjd��|j�s@tjjd��|j�j�}||||||�S)N�ztag too longztag is not alphanumeric)Z	get_uint8Z
get_string�encode�lenrZ	exception�SyntaxError�isalnum)	�clsr	r
�tokrrrrrrrr
�	from_text0sz
CAA.from_textcCsL|jtjd|j��t|j�}|jtjd|��|j|j�|j|j�dS)Nz!B)�write�struct�packrrrr)r�file�compressr�lrrr
�to_wire;s

zCAA.to_wirecCs\tjd|||d��\}}|d7}||||�}	|||||d�}
|||||	|
�S)Nz!BB�)r�unpack)rr	r
ZwireZcurrentZrdlenrrr!rrrrr
�	from_wireCs
z
CAA.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr"r%�
__classcell__rr)rr
rs




r)rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerrZRdatarrrrr
�<module>sPKl�\[[QXX/rdtypes/ANY/__pycache__/NS.cpython-36.opt-1.pycnu�[���3

�b�Wi�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�NSz	NS recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/NS.pyrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZNSBaserrrrr�<module>sPKl�\�}��<<+rdtypes/ANY/__pycache__/GPOS.cpython-36.pycnu�[���3

�b�W��@sXddlZddlZddlZddlZddlmZmZdd�Zdd�Z	Gdd�dej
j�ZdS)	�N)�long�	text_typecCs�|ddks|ddkr$|dd�}|j�r0dS|jd�\}}|dkrV|dkrVtjj�|dkrv|j�j�rvtjj�|dkr�|j�j�r�tjj�dS)	Nr�-�+��.��-�+)�isdigit�split�dns�	exception�	FormError�decode)Zwhat�left�right�r�/usr/lib/python3.6/GPOS.py�_validate_float_stringsrcCst|t�r|j�S|S)N)�
isinstancer�encode)�valuerrr�	_sanitize&s
rcs�eZdZdZdddgZ�fdd�Zd!d	d
�Zed"dd��Zd#d
d�Z	ed$dd��Z
dd�Zdd�Ze
eedd�Zdd�Zdd�Ze
eedd�Zdd�Zdd�Ze
eed d�Z�ZS)%�GPOSz�GPOS record

    @ivar latitude: latitude
    @type latitude: string
    @ivar longitude: longitude
    @type longitude: string
    @ivar altitude: altitude
    @type altitude: string
    @see: RFC 1712�latitude�	longitude�altitudecs�tt|�j||�t|t�s0t|t�s0t|t�r8t|�}t|t�sVt|t�sVt|t�r^t|�}t|t�s|t|t�s|t|t�r�t|�}t|�}t|�}t|�}t	|�t	|�t	|�||_
||_||_dS)N)
�superr�__init__r�float�intr�strrrrrr)�self�rdclass�rdtyperrr)�	__class__rrr:s,








z
GPOS.__init__NTcKs d|jj�|jj�|jj�fS)Nz%s %s %s)rrrr)r#�origin�
relativize�kwrrr�to_textRs
zGPOS.to_textc	Cs0|j�}|j�}|j�}|j�||||||�S)N)Z
get_stringZget_eol)	�clsr$r%�tokr'r(rrrrrr�	from_textWs
zGPOS.from_textcCs�t|j�}|dkst�|jtjd|��|j|j�t|j�}|dksJt�|jtjd|��|j|j�t|j�}|dks~t�|jtjd|��|j|j�dS)N�z!B)�lenr�AssertionError�write�struct�packrr)r#�file�compressr'�lrrr�to_wire_s


zGPOS.to_wirecCs�||}|d7}|d8}||kr(tjj�||||�j�}||7}||8}||}|d7}|d8}||krttjj�||||�j�}	||7}||8}||}|d7}|d8}||kr�tjj�||||�j�}
|||||	|
�S)Nr)r
rrZunwrap)r+r$r%ZwireZcurrentZrdlenr'r6rrrrrr�	from_wirems.zGPOS.from_wirecCs
t|j�S)N)r r)r#rrr�_get_float_latitude�szGPOS._get_float_latitudecCst|�|_dS)N)r"r)r#rrrr�_set_float_latitude�szGPOS._set_float_latitudez"latitude as a floating point value)�doccCs
t|j�S)N)r r)r#rrr�_get_float_longitude�szGPOS._get_float_longitudecCst|�|_dS)N)r"r)r#rrrr�_set_float_longitude�szGPOS._set_float_longitudez#longitude as a floating point valuecCs
t|j�S)N)r r)r#rrr�_get_float_altitude�szGPOS._get_float_altitudecCst|�|_dS)N)r"r)r#rrrr�_set_float_altitude�szGPOS._set_float_altitudez"altitude as a floating point value)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr*�classmethodr-r7r8r9r:�propertyZfloat_latituder<r=Zfloat_longituder>r?Zfloat_altitude�
__classcell__rr)r&rr,s*



r)
r2Z
dns.exceptionr
Z	dns.rdataZ
dns.tokenizerZdns._compatrrrrZrdataZRdatarrrrr�<module>sPKl�\�;[[*rdtypes/ANY/__pycache__/PTR.cpython-36.pycnu�[���3

�b�Wk�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�PTRz
PTR recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/PTR.pyrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZNSBaserrrrr�<module>sPKl�\�ݹSXX)rdtypes/ANY/__pycache__/MX.cpython-36.pycnu�[���3

�b�Wi�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�MXz	MX recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/MX.pyrsr)Zdns.rdtypes.mxbaseZdnsZrdtypesZmxbaseZMXBaserrrrr�<module>sPKl�\���r��1rdtypes/ANY/__pycache__/NSEC.cpython-36.opt-1.pycnu�[���3

�b�WR�@sLddlZddlZddlZddlZddlZddlmZGdd�dejj	�Z
dS)�N)�xrangecsbeZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	eddd��Z
ddd�Z�ZS)�NSECz�NSEC record

    @ivar next: the next name
    @type next: dns.name.Name object
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples�next�windowscs"tt|�j||�||_||_dS)N)�superr�__init__rr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/NSEC.pyr$sz
NSEC.__init__NTcKs�|jj||�}d}x�|jD]�\}}g}x`tdt|��D]N}	||	}
x@tdd�D]2}|
d|?@rN|jtjj|d|	d|��qNWq6W|ddj	|�7}qWd||fS)N�r���� z%s%s)
r�choose_relativityrr�len�append�dns�	rdatatype�to_text�join)r�origin�
relativize�kwr�text�window�bitmap�bits�i�byte�jrrr
r)s
 zNSEC.to_textcCsB|j�}|j||�}g}xZ|j�j�}|j�r0Ptjj|j�}	|	dkrRtj	j
d��|	dkrftj	j
d��|j|	�qW|j�d}
d}d}t
dd�}
g}x�|D]|}	|	|kr�q�|	}|	d}||
kr�|j|
|
d|�f�t
dd�}
|}
|	d}|d}|d}|d	}|
|d
|?B|
|<q�W|j|
|
d|�f�|||||�S)NrzNSEC with bit 0i��zNSEC with bit > 65535�� rr�r)Zget_namer�getZunescapeZ
is_eol_or_eofrr�	from_text�value�	exception�SyntaxErrorr�sort�	bytearray)�clsr	r
�tokrrrZrdtypes�tokenZnrdtyper�octetsZprior_rdtyperrZ
new_window�offsetr"�bitrrr
r(7sF
zNSEC.from_textcCsJ|jj|d|�x4|jD]*\}}|jtjd|t|���|j|�qWdS)Nz!BB)r�to_wirer�write�struct�packr)r�file�compressrrrrrr
r4^szNSEC.to_wirec
Cs�tjj|d||�|�\}}||7}||8}g}	x�|dkr�|dkrPtjjd��||}
||d}|dkst|dkr�tjjd��|d7}|d8}||kr�tjjd��t||||�j��}||7}||8}|	j|
|f�q4W|dk	r�|j|�}|||||	�S)	Nr�zNSEC too shortr&r%zbad NSEC octets�zbad NSEC bitmap length)	r�name�	from_wirer*Z	FormErrorr-Zunwraprr)
r.r	r
ZwireZcurrentZrdlenrrZcusedrrr1rrrr
r=ds,

zNSEC.from_wirecCs|jj||�|_dS)N)rr)rrrrrr
r}szNSEC.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr(r4r=r�
__classcell__rr)rr
rs
&
r)r6Z
dns.exceptionrZ	dns.rdataZ
dns.rdatatypeZdns.nameZdns._compatrZrdataZRdatarrrrr
�<module>sPKl�\u���[[,rdtypes/ANY/__pycache__/SSHFP.cpython-36.pycnu�[���3

�b�W�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�SSHFPz�SSHFP record

    @ivar algorithm: the algorithm
    @type algorithm: int
    @ivar fp_type: the digest type
    @type fp_type: int
    @ivar fingerprint: the fingerprint
    @type fingerprint: string
    @see: draft-ietf-secsh-dns-05.txt�	algorithm�fp_type�fingerprintcs(tt|�j||�||_||_||_dS)N)�superr�__init__rrr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/SSHFP.pyr%szSSHFP.__init__NTcKs d|j|jtjj|jdd�fS)Nz%d %d %s�)Z	chunksize)rr�dns�rdataZ_hexifyr)r�origin�
relativize�kwrrr
�to_text,s
z
SSHFP.to_textcCst|j�}|j�}g}x:|j�j�}	|	j�r,P|	j�s<tjj�|j|	j	j
��qWdj|�}
tj
|
�}
||||||
�S)N�)Z	get_uint8�getZunescapeZ
is_eol_or_eofZ
is_identifierrZ	exception�SyntaxError�append�value�encode�join�binasciiZ	unhexlify)�clsr	r
�tokrrrrZchunks�trrrr
�	from_text2s

zSSHFP.from_textcCs,tjd|j|j�}|j|�|j|j�dS)Nz!BB)�struct�packrr�writer)r�file�compressr�headerrrr
�to_wireBs
z
SSHFP.to_wirec	CsTtjd|||d��}|d7}|d8}||||�j�}||||d|d|�S)Nz!BB�r�)r!�unpackZunwrap)	rr	r
ZwireZcurrentZrdlenrr&rrrr
�	from_wireGs
zSSHFP.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr r'r+�
__classcell__rr)rr
rs



r)r!rZ	dns.rdatarZ
dns.rdatatyperZRdatarrrrr
�<module>sPKl�\?�['��0rdtypes/ANY/__pycache__/URI.cpython-36.opt-1.pycnu�[���3

�b�WR�@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�URIz�URI record

    @ivar priority: the priority
    @type priority: int
    @ivar weight: the weight
    @type weight: int
    @ivar target: the target host
    @type target: dns.name.Name object
    @see: draft-faltstrom-uri-13�priority�weight�targetcsVtt|�j||�||_||_t|�dkr6tjjd��t	|t
�rL|j�|_n||_dS)N�zURI target cannot be empty)
�superr�__init__rr�len�dns�	exception�SyntaxError�
isinstancer�encoder)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/URI.pyr	's
zURI.__init__NTcKsd|j|j|jj�fS)Nz
%d %d "%s")rrr�decode)r�origin�
relativize�kwrrr�to_text2s
zURI.to_textc	CsR|j�}|j�}|j�j�}|j�p*|j�s8tjjd��|j�||||||j	�S)NzURI target must be a string)
Z
get_uint16�getZunescapeZis_quoted_stringZ
is_identifierrrr
Zget_eol�value)	�clsrr�tokrrrrrrrr�	from_text6sz
URI.from_textcCs,tjd|j|j�}|j|�|j|j�dS)Nz!HH)�struct�packrr�writer)r�file�compressrZtwo_intsrrr�to_wire@s
zURI.to_wirec
Csh|dkrtjjd��tjd|||d��\}}|d7}|d8}||||�}	||7}||||||	�S)N�zURI RR is shorter than 5 octetsz!HH�)rrZ	FormErrorr �unpack)
rrrZwireZcurrentZrdlenrrrrrrr�	from_wireEsz
URI.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r	r�classmethodrr%r)�
__classcell__rr)rrrs


	
r)
r Z
dns.exceptionrZ	dns.rdataZdns.nameZdns._compatrZrdataZRdatarrrrr�<module>s
PKl�\I��pp,rdtypes/ANY/__pycache__/CSYNC.cpython-36.pycnu�[���3

�b�W$�@sLddlZddlZddlZddlZddlZddlmZGdd�dejj	�Z
dS)�N)�xrangecsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�CSYNCz�CSYNC record

    @ivar serial: the SOA serial number
    @type serial: int
    @ivar flags: the CSYNC flags
    @type flags: int
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples�serial�flags�windowscs(tt|�j||�||_||_||_dS)N)�superr�__init__rrr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/CSYNC.pyr%szCSYNC.__init__NTcKs�d}x�|jD]�\}}g}x`tdt|��D]N}||}	x@tdd�D]2}
|	d|
?@r@|jtjj|d|d|
��q@Wq(W|ddj|�7}qWd|j|j	|fS)N�r���� z%d %d%s)
rr�len�append�dns�	rdatatype�to_text�joinrr)r	�origin�
relativize�kw�text�window�bitmap�bits�i�byte�jr
r
rr+s
 z
CSYNC.to_textcCs@|j�}|j�}g}xZ|j�j�}	|	j�r,Ptjj|	j�}
|
dkrNtj	j
d��|
dkrbtj	j
d��|j|
�qW|j�d}d}d}
t
dd�}g}x�|D]|}
|
|
kr�q�|
}
|
d}||kr�|j||d|�f�t
dd�}|}|
d}|d}|d}|d	}||d
|?B||<q�W|j||d|�f�||||||�S)NrzCSYNC with bit 0i��zCSYNC with bit > 65535�� rr�r)Z
get_uint32Z
get_uint16�getZunescapeZ
is_eol_or_eofrr�	from_text�value�	exception�SyntaxErrorr�sort�	bytearray)�clsr
r�tokrrrrZrdtypes�tokenZnrdtyper�octetsZprior_rdtyperrZ
new_window�offsetr"�bitr
r
rr(8sF
zCSYNC.from_textcCsR|jtjd|j|j��x4|jD]*\}}|jtjd|t|���|j|�q WdS)Nz!IHz!BB)�write�struct�packrrrr)r	�file�compressrrrr
r
r�to_wire_sz
CSYNC.to_wirec
Cs|dkrtjjd��tjd|||d��\}}|d7}|d8}g}	x�|dkr�|dkrbtjjd��||}
||d}|dks�|dkr�tjjd��|d	7}|d	8}||kr�tjjd
��t||||�j��}||7}||8}|	j|
|f�qFW||||||	�S)N�zCSYNC too shortz!IHr�r&r%zbad CSYNC octets�zbad CSYNC bitmap length)rr*Z	FormErrorr5�unpackr-Zunwrapr)
r.r
rZwireZcurrentZrdlenrrrrrr1rr
r
r�	from_wirees,
zCSYNC.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr(r9r>�
__classcell__r
r
)rrrs	


&
r)r5Z
dns.exceptionrZ	dns.rdataZ
dns.rdatatypeZdns.nameZdns._compatrZrdataZRdatarr
r
r
r�<module>sPKl�\��h��*rdtypes/ANY/__pycache__/SOA.cpython-36.pycnu�[���3

�b�W��@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsveZdZdZdddddddgZ�fd	d
�Zdd
d�Zeddd��Zddd�Z	ddd�Z
eddd��Zddd�Z�Z
S)�SOAa�SOA record

    @ivar mname: the SOA MNAME (master name) field
    @type mname: dns.name.Name object
    @ivar rname: the SOA RNAME (responsible name) field
    @type rname: dns.name.Name object
    @ivar serial: The zone's serial number
    @type serial: int
    @ivar refresh: The zone's refresh value (in seconds)
    @type refresh: int
    @ivar retry: The zone's retry value (in seconds)
    @type retry: int
    @ivar expire: The zone's expiration value (in seconds)
    @type expire: int
    @ivar minimum: The zone's negative caching time (in seconds, called
    "minimum" for historical reasons)
    @type minimum: int
    @see: RFC 1035�mname�rname�serial�refresh�retry�expire�minimumc

s@tt|�j||�||_||_||_||_||_||_|	|_	dS)N)
�superr�__init__rrrrrrr	)
�self�rdclass�rdtyperrrrrrr	)�	__class__��/usr/lib/python3.6/SOA.pyr/szSOA.__init__NTcKs<|jj||�}|jj||�}d|||j|j|j|j|jfS)Nz%s %s %d %d %d %d %d)r�choose_relativityrrrrrr	)r�origin�
relativize�kwrrrrr�to_text:s
zSOA.to_textc

Csp|j�}|j�}|j||�}|j||�}|j�}|j�}	|j�}
|j�}|j�}|j�|||||||	|
||�	S)N)Zget_namerZ
get_uint32Zget_ttlZget_eol)
�clsr
r�tokrrrrrrrrr	rrr�	from_textAsz
SOA.from_textcCsL|jj|||�|jj|||�tjd|j|j|j|j|j	�}|j
|�dS)Nz!IIIII)r�to_wirer�struct�packrrrrr	�write)r�file�compressr�	five_intsrrrrPs
zSOA.to_wirecCs6|jj|�|jj|�tjd|j|j|j|j|j	�S)Nz!IIIII)
r�
to_digestablerrrrrrrr	)rrrrrr!WszSOA.to_digestablecCs�tjj|d||�|�\}}||7}||8}tjj|d||�|�\}	}||7}||8}|dkrltjj�tjd||||��}
|dk	r�|j|�}|	j|�}	|||||	|
d|
d|
d|
d|
d�	S)N�z!IIIIIr����)�dns�name�	from_wireZ	exceptionZ	FormErrorr�unpackr)rr
rZwireZcurrentZrdlenrrZcusedrr rrrr)]s 


z
SOA.from_wirecCs$|jj||�|_|jj||�|_dS)N)rrr)rrrrrrrpszSOA.choose_relativity)NT)NT)NN)N)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr!r)r�
__classcell__rr)rrrs


r)rZ
dns.exceptionr'Z	dns.rdataZdns.nameZrdataZRdatarrrrr�<module>sPKl�\�	{���2rdtypes/ANY/__pycache__/NSEC3.cpython-36.opt-1.pycnu�[���3

�b�W��@s�ddlZddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
yejdd�Zejdd�Z
Wn,ek
r�ejdd�Zejdd�Z
YnXdZdZGdd	�d	ejj�ZdS)
�N)�xrange�	text_typeZ 0123456789ABCDEFGHIJKLMNOPQRSTUVZ ABCDEFGHIJKLMNOPQRSTUVWXYZ234567s 0123456789ABCDEFGHIJKLMNOPQRSTUVs ABCDEFGHIJKLMNOPQRSTUVWXYZ234567�cs`eZdZdZddddddgZ�fdd	�Zddd
�Zeddd��Zddd�Z	eddd��Z
�ZS)�NSEC3a�NSEC3 record

    @ivar algorithm: the hash algorithm number
    @type algorithm: int
    @ivar flags: the flags
    @type flags: int
    @ivar iterations: the number of iterations
    @type iterations: int
    @ivar salt: the salt
    @type salt: string
    @ivar next: the next name hash
    @type next: string
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples�	algorithm�flags�
iterations�salt�next�windowsc		sPtt|�j||�||_||_||_t|t�r:|j�|_	n||_	||_
||_dS)N)�superr�__init__rrr�
isinstancer�encoder	r
r)	�self�rdclass�rdtyperrrr	r
r)�	__class__��/usr/lib/python3.6/NSEC3.pyr
?s
zNSEC3.__init__NTc
Ks�tj|j�jt�j�j�}|jdkr*d}ntj	|j�j�}d}x�|j
D]�\}}g}	x`tdt|��D]N}
||
}x@tdd�D]2}|d|?@rz|	j
tjj|d|
d|��qzWqbW|ddj|	�7}qFWd	|j|j|j|||fS)
N��-�r���� z%u %u %u %s %s%s)�base64Z	b32encoder
�	translate�b32_normal_to_hex�lower�decoder	�binasciiZhexlifyrr�len�append�dns�	rdatatype�to_text�joinrrr)
r�origin�
relativize�kwr
r	�text�window�bitmap�bits�i�byte�jrrrr'Ls"

 
z
NSEC3.to_textc	Cs�|j�}|j�}|j�}|j�}	|	dkr.d}	ntj|	jd��}	|j�jd�j�jt�}
t	j
|
�}
g}xZ|j�j�}|j
�r|Ptjj|j�}
|
dkr�tjjd��|
dkr�tjjd��|j|
�qfW|j�d}d}d}tdd	�}g}x�|D]�}
|
|kr�q�|
}|
d
}||k�rD|dk�r4|j|dj|d|��f�tdd	�}|}|
d
}|d}|d}|d
}||d|?B||<q�W|dk�r�|j||d|�f�|||||||	|
|�S)Nrr�asciirzNSEC3 with bit 0i��zNSEC3 with bit > 65535�� rrrrr)Z	get_uint8Z
get_uint16Z
get_stringr"Z	unhexlifyr�upperr�b32_hex_to_normalrZ	b32decode�getZunescapeZ
is_eol_or_eofr%r&�	from_text�value�	exception�SyntaxErrorr$�sort�	bytearrayr()�clsrr�tokr)r*rrrr	r
Zrdtypes�tokenZnrdtyper-�octetsZprior_rdtyper.rZ
new_window�offsetr1�bitrrrr9`s\




zNSEC3.from_textcCs�t|j�}|jtjd|j|j|j|��|j|j�t|j�}|jtjd|��|j|j�x4|j	D]*\}}|jtjd|t|���|j|�qdWdS)Nz!BBHBz!Bz!BB)
r#r	�write�struct�packrrrr
r)r�file�compressr)�lr-r.rrr�to_wire�s

z
NSEC3.to_wirec	CsZtjd|||d��\}}}	}
|d7}|d8}||||
�j�}||
7}||
8}||}|d7}|d8}||||�j�}
||7}||8}g}x�|dk�rB|dkr�tjjd��||}||d}|dks�|dkr�tjjd��|d	7}|d	8}||k�r
tjjd
��t||||�j��}||7}||8}|j||f�q�W||||||	||
|�S)Nz!BBHB�rr�zNSEC3 too shortr5zbad NSEC3 octets�zbad NSEC3 bitmap length)rF�unpackZunwrapr%r;Z	FormErrorr>r$)r?rrZwireZcurrentZrdlenr)rrrZslenr	Znlenr
rr-rBr.rrr�	from_wire�s< 
zNSEC3.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r
r'�classmethodr9rKrP�
__classcell__rr)rrr,s
1
r)rr"�stringrFZ
dns.exceptionr%Z	dns.rdataZ
dns.rdatatypeZdns._compatrr�	maketransr7r�AttributeError�bytesZSHA1ZOPTOUTZrdataZRdatarrrrr�<module>s(
PKl�\w-��2rdtypes/ANY/__pycache__/EUI48.cpython-36.opt-1.pycnu�[���3

�b�Wd�@s"ddlZGdd�dejjj�ZdS)�Nc@s eZdZdZdZeddZdS)�EUI48z�EUI48 record

    @ivar fingerprint: 48-bit Extended Unique Identifier (EUI-48)
    @type fingerprint: string
    @see: rfc7043.txt���N)�__name__�
__module__�__qualname__�__doc__Zbyte_lenZtext_len�r
r
�/usr/lib/python3.6/EUI48.pyrsr)Zdns.rdtypes.euibaseZdnsZrdtypesZeuibaseZEUIBaserr
r
r
r�<module>sPKl�\u���[[2rdtypes/ANY/__pycache__/SSHFP.cpython-36.opt-1.pycnu�[���3

�b�W�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�SSHFPz�SSHFP record

    @ivar algorithm: the algorithm
    @type algorithm: int
    @ivar fp_type: the digest type
    @type fp_type: int
    @ivar fingerprint: the fingerprint
    @type fingerprint: string
    @see: draft-ietf-secsh-dns-05.txt�	algorithm�fp_type�fingerprintcs(tt|�j||�||_||_||_dS)N)�superr�__init__rrr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/SSHFP.pyr%szSSHFP.__init__NTcKs d|j|jtjj|jdd�fS)Nz%d %d %s�)Z	chunksize)rr�dns�rdataZ_hexifyr)r�origin�
relativize�kwrrr
�to_text,s
z
SSHFP.to_textcCst|j�}|j�}g}x:|j�j�}	|	j�r,P|	j�s<tjj�|j|	j	j
��qWdj|�}
tj
|
�}
||||||
�S)N�)Z	get_uint8�getZunescapeZ
is_eol_or_eofZ
is_identifierrZ	exception�SyntaxError�append�value�encode�join�binasciiZ	unhexlify)�clsr	r
�tokrrrrZchunks�trrrr
�	from_text2s

zSSHFP.from_textcCs,tjd|j|j�}|j|�|j|j�dS)Nz!BB)�struct�packrr�writer)r�file�compressr�headerrrr
�to_wireBs
z
SSHFP.to_wirec	CsTtjd|||d��}|d7}|d8}||||�j�}||||d|d|�S)Nz!BB�r�)r!�unpackZunwrap)	rr	r
ZwireZcurrentZrdlenrr&rrrr
�	from_wireGs
zSSHFP.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr r'r+�
__classcell__rr)rr
rs



r)r!rZ	dns.rdatarZ
dns.rdatatyperZRdatarrrrr
�<module>sPKl�\��,���+rdtypes/ANY/__pycache__/ISDN.cpython-36.pycnu�[���3

�b�W��@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecsXeZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	eddd��Z
�ZS)�ISDNz�ISDN record

    @ivar address: the ISDN address
    @type address: string
    @ivar subaddress: the ISDN subaddress (or '' if not present)
    @type subaddress: string
    @see: RFC 1183�address�
subaddresscsNtt|�j||�t|t�r(|j�|_n||_t|t�rD|j�|_n||_dS)N)�superr�__init__�
isinstancer�encoderr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/ISDN.pyr$s

z
ISDN.__init__NTcKs<|jr&dtjj|j�tjj|j�fSdtjj|j�SdS)Nz	"%s" "%s"z"%s")r�dns�rdataZ	_escapifyr)r
�origin�
relativize�kwrrr�to_text/szISDN.to_textc	CsP|j�}|j�}|j�s,|j|�|j�}n|j|�d}|j�|||||�S)N�)Z
get_string�getZ
is_eol_or_eofZungetZget_eol)	�clsrr�tokrrr�trrrr�	from_text6s


zISDN.from_textcCstt|j�}|dkst�|jtjd|��|j|j�t|j�}|dkrp|dksRt�|jtjd|��|j|j�dS)N�z!Br)�lenr�AssertionError�write�struct�packr)r
�file�compressr�lrrr�to_wireCs

zISDN.to_wirec
Cs�||}|d7}|d8}||kr(tjj�||||�j�}||7}||8}|dkr�||}|d7}|d8}||kr|tjj�||||�j�}	nd}	|||||	�S)N�rr)rZ	exceptionZ	FormErrorZunwrap)
rrrZwireZcurrentZrdlenrr$rrrrr�	from_wireNs"zISDN.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr%r'�
__classcell__rr)r
rrs

r)
r Z
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZdns._compatrrZRdatarrrrr�<module>s
PKl�\����2rdtypes/ANY/__pycache__/EUI64.cpython-36.opt-1.pycnu�[���3

�b�Wn�@s"ddlZGdd�dejjj�ZdS)�Nc@s eZdZdZdZeddZdS)�EUI64z�EUI64 record

    @ivar fingerprint: 64-bit Extended Unique Identifier (EUI-64)
    @type fingerprint: string
    @see: rfc7043.txt���N)�__name__�
__module__�__qualname__�__doc__Zbyte_lenZtext_len�r
r
�/usr/lib/python3.6/EUI64.pyrsr)Zdns.rdtypes.euibaseZdnsZrdtypesZeuibaseZEUIBaserr
r
r
r�<module>sPKl�\��ǃ^^*rdtypes/ANY/__pycache__/TXT.cpython-36.pycnu�[���3

�b�Wn�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�TXTz
TXT recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/TXT.pyrsr)Zdns.rdtypes.txtbaseZdnsZrdtypesZtxtbaseZTXTBaserrrrr�<module>sPKl�\�j+���1rdtypes/ANY/__pycache__/CERT.cpython-36.opt-1.pycnu�[���3

�b�Wo�@sxddlZddlZddlZddlZddlZddlZdddddd�Zdd	d
ddd
�Zdd�Z	dd�Z
Gdd�dejj�Z
dS)�N�PKIX�SPKI�PGP�URI�OID)�����rrr	r
r)rrrrrcCstj|�}|dk	r|St|�S)N)�_ctype_by_name�get�int)�what�v�r�/usr/lib/python3.6/CERT.py�_ctype_from_text)s
rcCstj|�}|dk	r|St|�S)N)�_ctype_by_valuer
�str)rrrrr�_ctype_to_text0s
rcs\eZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
�ZS)�CERTa"CERT record

    @ivar certificate_type: certificate type
    @type certificate_type: int
    @ivar key_tag: key tag
    @type key_tag: int
    @ivar algorithm: algorithm
    @type algorithm: int
    @ivar certificate: the certificate or CRL
    @type certificate: string
    @see: RFC 2538�certificate_type�key_tag�	algorithm�certificatecs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__rrrGs
z
CERT.__init__NTcKs0t|j�}d||jtjj|j�tjj|j	�fS)Nz%s %d %s %s)
rrr�dns�dnssecZalgorithm_to_textr�rdataZ
_base64ifyr)r�origin�
relativize�kwrrrr�to_textOs
zCERT.to_textc
Cs�t|j��}|j�}tjj|j��}|dks4|dkr@tjjd��g}	x:|j�j	�}
|
j
�r\P|
j�sltjj�|	j|
j
j��qFWdj|	�}tj|�}|||||||�S)Nr�zbad algorithm type�)rZ
get_stringZ
get_uint16r"r#Zalgorithm_from_text�	exception�SyntaxErrorr
ZunescapeZ
is_eol_or_eofZ
is_identifier�append�value�encode�join�base64Z	b64decode)
�clsrr �tokr%r&rrrZchunks�tZb64rrrr�	from_textUs"


zCERT.from_textcCs0tjd|j|j|j�}|j|�|j|j�dS)Nz!HHB)�struct�packrrr�writer)r�file�compressr%�prefixrrr�to_wireis
zCERT.to_wirecCsl|||d�j�}|d7}|d8}|dkr4tjj�tjd|�\}}	}
||||�j�}|||||	|
|�S)N�rz!HHB)Zunwrapr"r+Z	FormErrorr6�unpack)r2rr ZwireZcurrentZrdlenr%r;rrrrrrr�	from_wireoszCERT.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr(�classmethodr5r<r?�
__classcell__rr)r!rr7s

r)r6r1Z
dns.exceptionr"Z
dns.dnssecZ	dns.rdataZ
dns.tokenizerrrrrr$ZRdatarrrrr�<module>s$PKl�\o�DB��2rdtypes/ANY/__pycache__/HINFO.cpython-36.opt-1.pycnu�[���3

�b�Wi
�@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecsXeZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	eddd��Z
�ZS)�HINFOz�HINFO record

    @ivar cpu: the CPU type
    @type cpu: string
    @ivar os: the OS type
    @type os: string
    @see: RFC 1035�cpu�oscsNtt|�j||�t|t�r(|j�|_n||_t|t�rD|j�|_n||_dS)N)�superr�__init__�
isinstancer�encoderr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/HINFO.pyr$s

zHINFO.__init__NTcKs dtjj|j�tjj|j�fS)Nz	"%s" "%s")�dns�rdataZ	_escapifyrr)r
�origin�
relativize�kwrrr�to_text/sz
HINFO.to_textcCs&|j�}|j�}|j�|||||�S)N)Z
get_stringZget_eol)�clsrr�tokrrrrrrr�	from_text3szHINFO.from_textcCsTt|j�}|jtjd|��|j|j�t|j�}|jtjd|��|j|j�dS)Nz!B)�lenr�write�struct�packr)r
�file�compressr�lrrr�to_wire:s

z
HINFO.to_wirec
Cs�||}|d7}|d8}||kr(tjj�||||�j�}||7}||8}||}|d7}|d8}||krttjj�||||�j�}	|||||	�S)N�)rZ	exceptionZ	FormErrorZunwrap)
rrrZwireZcurrentZrdlenrrrrrrr�	from_wireDszHINFO.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr r"�
__classcell__rr)r
rrs


r)
rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZdns._compatrrZRdatarrrrr�<module>s
PKm�\�	{���,rdtypes/ANY/__pycache__/NSEC3.cpython-36.pycnu�[���3

�b�W��@s�ddlZddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
yejdd�Zejdd�Z
Wn,ek
r�ejdd�Zejdd�Z
YnXdZdZGdd	�d	ejj�ZdS)
�N)�xrange�	text_typeZ 0123456789ABCDEFGHIJKLMNOPQRSTUVZ ABCDEFGHIJKLMNOPQRSTUVWXYZ234567s 0123456789ABCDEFGHIJKLMNOPQRSTUVs ABCDEFGHIJKLMNOPQRSTUVWXYZ234567�cs`eZdZdZddddddgZ�fdd	�Zddd
�Zeddd��Zddd�Z	eddd��Z
�ZS)�NSEC3a�NSEC3 record

    @ivar algorithm: the hash algorithm number
    @type algorithm: int
    @ivar flags: the flags
    @type flags: int
    @ivar iterations: the number of iterations
    @type iterations: int
    @ivar salt: the salt
    @type salt: string
    @ivar next: the next name hash
    @type next: string
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples�	algorithm�flags�
iterations�salt�next�windowsc		sPtt|�j||�||_||_||_t|t�r:|j�|_	n||_	||_
||_dS)N)�superr�__init__rrr�
isinstancer�encoder	r
r)	�self�rdclass�rdtyperrrr	r
r)�	__class__��/usr/lib/python3.6/NSEC3.pyr
?s
zNSEC3.__init__NTc
Ks�tj|j�jt�j�j�}|jdkr*d}ntj	|j�j�}d}x�|j
D]�\}}g}	x`tdt|��D]N}
||
}x@tdd�D]2}|d|?@rz|	j
tjj|d|
d|��qzWqbW|ddj|	�7}qFWd	|j|j|j|||fS)
N��-�r���� z%u %u %u %s %s%s)�base64Z	b32encoder
�	translate�b32_normal_to_hex�lower�decoder	�binasciiZhexlifyrr�len�append�dns�	rdatatype�to_text�joinrrr)
r�origin�
relativize�kwr
r	�text�window�bitmap�bits�i�byte�jrrrr'Ls"

 
z
NSEC3.to_textc	Cs�|j�}|j�}|j�}|j�}	|	dkr.d}	ntj|	jd��}	|j�jd�j�jt�}
t	j
|
�}
g}xZ|j�j�}|j
�r|Ptjj|j�}
|
dkr�tjjd��|
dkr�tjjd��|j|
�qfW|j�d}d}d}tdd	�}g}x�|D]�}
|
|kr�q�|
}|
d
}||k�rD|dk�r4|j|dj|d|��f�tdd	�}|}|
d
}|d}|d}|d
}||d|?B||<q�W|dk�r�|j||d|�f�|||||||	|
|�S)Nrr�asciirzNSEC3 with bit 0i��zNSEC3 with bit > 65535�� rrrrr)Z	get_uint8Z
get_uint16Z
get_stringr"Z	unhexlifyr�upperr�b32_hex_to_normalrZ	b32decode�getZunescapeZ
is_eol_or_eofr%r&�	from_text�value�	exception�SyntaxErrorr$�sort�	bytearrayr()�clsrr�tokr)r*rrrr	r
Zrdtypes�tokenZnrdtyper-�octetsZprior_rdtyper.rZ
new_window�offsetr1�bitrrrr9`s\




zNSEC3.from_textcCs�t|j�}|jtjd|j|j|j|��|j|j�t|j�}|jtjd|��|j|j�x4|j	D]*\}}|jtjd|t|���|j|�qdWdS)Nz!BBHBz!Bz!BB)
r#r	�write�struct�packrrrr
r)r�file�compressr)�lr-r.rrr�to_wire�s

z
NSEC3.to_wirec	CsZtjd|||d��\}}}	}
|d7}|d8}||||
�j�}||
7}||
8}||}|d7}|d8}||||�j�}
||7}||8}g}x�|dk�rB|dkr�tjjd��||}||d}|dks�|dkr�tjjd��|d	7}|d	8}||k�r
tjjd
��t||||�j��}||7}||8}|j||f�q�W||||||	||
|�S)Nz!BBHB�rr�zNSEC3 too shortr5zbad NSEC3 octets�zbad NSEC3 bitmap length)rF�unpackZunwrapr%r;Z	FormErrorr>r$)r?rrZwireZcurrentZrdlenr)rrrZslenr	Znlenr
rr-rBr.rrr�	from_wire�s< 
zNSEC3.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r
r'�classmethodr9rKrP�
__classcell__rr)rrr,s
1
r)rr"�stringrFZ
dns.exceptionr%Z	dns.rdataZ
dns.rdatatypeZdns._compatrr�	maketransr7r�AttributeError�bytesZSHA1ZOPTOUTZrdataZRdatarrrrr�<module>s(
PKm�\�eQ??2rdtypes/ANY/__pycache__/AFSDB.cpython-36.opt-1.pycnu�[���3

�b�W8�@s"ddlZGdd�dejjj�ZdS)�Nc@sDeZdZdZdd�Zdd�Zeee�Zdd�Zdd	�Z	eee	�Z
d
S)�AFSDBz�AFSDB record

    @ivar subtype: the subtype value
    @type subtype: int
    @ivar hostname: the hostname name
    @type hostname: dns.name.Name objectcCs|jS)N)�
preference)�self�r�/usr/lib/python3.6/AFSDB.py�get_subtype'szAFSDB.get_subtypecCs
||_dS)N)r)r�subtyperrr�set_subtype*szAFSDB.set_subtypecCs|jS)N)�exchange)rrrr�get_hostname/szAFSDB.get_hostnamecCs
||_dS)N)r
)r�hostnamerrr�set_hostname2szAFSDB.set_hostnameN)�__name__�
__module__�__qualname__�__doc__rr	�propertyrrr
rrrrrrs

r)Zdns.rdtypes.mxbaseZdnsZrdtypesZmxbaseZUncompressedDowncasingMXrrrrr�<module>sPKm�\����.rdtypes/ANY/__pycache__/CDNSKEY.cpython-36.pycnu�[���3

�b�W�@s:ddlZddlmZmZddgZGdd�dejjj�ZdS)�N)�flags_to_text_set�flags_from_text_setrrc@seZdZdZdS)�CDNSKEYzCDNSKEY recordN)�__name__�
__module__�__qualname__�__doc__�r	r	�/usr/lib/python3.6/CDNSKEY.pyrsr)	Zdns.rdtypes.dnskeybaseZdnsrr�__all__ZrdtypesZ
dnskeybaseZ
DNSKEYBaserr	r	r	r
�<module>sPKm�\5�rr*rdtypes/ANY/__pycache__/SPF.cpython-36.pycnu�[���3

�b�W��@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�SPFzSPF record

    @see: RFC 4408N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/SPF.pyrsr)Zdns.rdtypes.txtbaseZdnsZrdtypesZtxtbaseZTXTBaserrrrr�<module>sPKm�\r���,rdtypes/ANY/__pycache__/HINFO.cpython-36.pycnu�[���3

�b�Wi
�@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecsXeZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	eddd��Z
�ZS)�HINFOz�HINFO record

    @ivar cpu: the CPU type
    @type cpu: string
    @ivar os: the OS type
    @type os: string
    @see: RFC 1035�cpu�oscsNtt|�j||�t|t�r(|j�|_n||_t|t�rD|j�|_n||_dS)N)�superr�__init__�
isinstancer�encoderr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/HINFO.pyr$s

zHINFO.__init__NTcKs dtjj|j�tjj|j�fS)Nz	"%s" "%s")�dns�rdataZ	_escapifyrr)r
�origin�
relativize�kwrrr�to_text/sz
HINFO.to_textcCs&|j�}|j�}|j�|||||�S)N)Z
get_stringZget_eol)�clsrr�tokrrrrrrr�	from_text3szHINFO.from_textcCslt|j�}|dkst�|jtjd|��|j|j�t|j�}|dksJt�|jtjd|��|j|j�dS)N�z!B)�lenr�AssertionError�write�struct�packr)r
�file�compressr�lrrr�to_wire:s

z
HINFO.to_wirec
Cs�||}|d7}|d8}||kr(tjj�||||�j�}||7}||8}||}|d7}|d8}||krttjj�||||�j�}	|||||	�S)N�)rZ	exceptionZ	FormErrorZunwrap)
rrrZwireZcurrentZrdlenrr!rrrrr�	from_wireDszHINFO.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr"r$�
__classcell__rr)r
rrs


r)
rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZdns._compatrrZRdatarrrrr�<module>s
PKm�\�\m
��0rdtypes/ANY/__pycache__/HIP.cpython-36.opt-1.pycnu�[���3

�b�W0�@sHddlZddlZddlZddlZddlZddlZGdd�dejj�Z	dS)�NcsfeZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
ddd�Z�ZS)�HIPa=HIP record

    @ivar hit: the host identity tag
    @type hit: string
    @ivar algorithm: the public key cryptographic algorithm
    @type algorithm: int
    @ivar key: the public key
    @type key: string
    @ivar servers: the rendezvous servers
    @type servers: list of dns.name.Name objects
    @see: RFC 5205�hit�	algorithm�key�serverscs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__��/usr/lib/python3.6/HIP.pyr)s
zHIP.__init__NTc	Ks�tj|j�j�}tj|j�jdd�j�}d}g}x |jD]}|j	|j
||��q8Wt|�dkrz|ddjdd�|D��7}d|j
|||fS)	N�
��r� css|]}|j�VqdS)N)Z
to_unicode)�.0�xr
r
r�	<genexpr>8szHIP.to_text.<locals>.<genexpr>z
%u %s %s%s)�binasciiZhexlifyr�decode�base64Z	b64encoder�replacer�append�choose_relativity�len�joinr)	r	�origin�
relativize�kwrr�textr�serverr
r
r�to_text0szHIP.to_textcCs�|j�}tj|j�j��}t|�dkr2tjjd��t	j
|j�j��}g}	x<|j�}
|
j�r\Ptj
j|
j|�}|j||�|	j|�qJW|||||||	�S)N�zHIT too long)Z	get_uint8rZ	unhexlifyZ
get_string�encoder�dnsZ	exception�SyntaxErrorrZ	b64decode�getZ
is_eol_or_eof�name�	from_text�valuerr)�clsr
r�tokrrrrrr�tokenr"r
r
rr*;sz
HIP.from_textcCsft|j�}t|j�}|jtjd||j|��|j|j�|j|j�x|jD]}|j|d|�qLWdS)Nz!BBH)	rrr�write�struct�packrr�to_wire)r	�file�compressr�lh�lkr"r
r
rr2Ls

zHIP.to_wirecCs�tjd|||d��\}}}	|d7}|d8}||||�j�}
||7}||8}||||	�j�}||	7}||	8}g}xV|dkr�tjj|d||�|�\}
}||7}||8}|dk	r�|
j|�}
|j|
�q|W||||
|||�S)Nz!BBH�r)r0�unpackZunwrapr&r)�	from_wirerr)r,r
rZwireZcurrentZrdlenrr5rr6rrrr"Zcusedr
r
rr9Us(


z
HIP.from_wirecCs4g}x$|jD]}|j||�}|j|�qW||_dS)N)rrr)r	rrrr"r
r
rrls
zHIP.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr#�classmethodr*r2r9r�
__classcell__r
r
)rrrs

	r)
r0rrZ
dns.exceptionr&Z	dns.rdataZ
dns.rdatatypeZrdataZRdatarr
r
r
r�<module>sPKm�\����4rdtypes/ANY/__pycache__/CDNSKEY.cpython-36.opt-1.pycnu�[���3

�b�W�@s:ddlZddlmZmZddgZGdd�dejjj�ZdS)�N)�flags_to_text_set�flags_from_text_setrrc@seZdZdZdS)�CDNSKEYzCDNSKEY recordN)�__name__�
__module__�__qualname__�__doc__�r	r	�/usr/lib/python3.6/CDNSKEY.pyrsr)	Zdns.rdtypes.dnskeybaseZdnsrr�__all__ZrdtypesZ
dnskeybaseZ
DNSKEYBaserr	r	r	r
�<module>sPKm�\��ǃ^^0rdtypes/ANY/__pycache__/TXT.cpython-36.opt-1.pycnu�[���3

�b�Wn�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�TXTz
TXT recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/TXT.pyrsr)Zdns.rdtypes.txtbaseZdnsZrdtypesZtxtbaseZTXTBaserrrrr�<module>sPKm�\���__,rdtypes/ANY/__pycache__/RRSIG.cpython-36.pycnu�[���3

�b�W�@s|ddlZddlZddlZddlZddlZddlZddlZddlZGdd�dej	j
�Zdd�Zdd�Z
Gdd	�d	ejj�ZdS)
�Nc@seZdZdZdS)�
BadSigTimez:Time in DNS SIG or RRSIG resource record cannot be parsed.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/RRSIG.pyrsrc
Cs�t|�dkrt�t|dd��}t|dd��}t|dd��}t|dd��}t|dd��}t|dd��}tj||||||dddf	�S)N�r����
�)�lenr�int�calendarZtimegm)�whatZyearZmonthZdayZhourZminute�secondrrr�sigtime_to_posixtime srcCstjdtj|��S)Nz%Y%m%d%H%M%S)�timeZstrftimeZgmtime)rrrr�posixtime_to_sigtime-src	sxeZdZdZdddddddd	d
g	Z�fdd�Zd
d�Zddd�Zeddd��Z	ddd�Z
eddd��Zddd�Z�Z
S) �RRSIGa~RRSIG record

    @ivar type_covered: the rdata type this signature covers
    @type type_covered: int
    @ivar algorithm: the algorithm used for the sig
    @type algorithm: int
    @ivar labels: number of labels
    @type labels: int
    @ivar original_ttl: the original TTL
    @type original_ttl: long
    @ivar expiration: signature expiration time
    @type expiration: long
    @ivar inception: signature inception time
    @type inception: long
    @ivar key_tag: the key tag
    @type key_tag: int
    @ivar signer: the signer
    @type signer: dns.name.Name object
    @ivar signature: the signature
    @type signature: string�type_covered�	algorithm�labels�original_ttl�
expiration�	inception�key_tag�signer�	signaturecsLtt|�j||�||_||_||_||_||_||_|	|_	|
|_
||_dS)N)�superr�__init__rrrrrrrrr )�self�rdclass�rdtyperrrrrrrrr )�	__class__rrr"LszRRSIG.__init__cCs|jS)N)r)r#rrr�coversZszRRSIG.coversNTcKsLdtjj|j�|j|j|jt|j�t|j	�|j
|jj||�tj
j|j�f	S)Nz%s %d %d %d %s %s %d %s %s)�dns�	rdatatype�to_textrrrrrrrrr�choose_relativity�rdataZ
_base64ifyr )r#�origin�
relativize�kwrrrr*]sz
RRSIG.to_textcCs�tjj|j��}tjj|j��}|j�}|j�}	t|j��}
t|j��}|j�}|j	�}
|
j
||�}
g}x:|j�j�}|j
�r�P|j�s�tjj�|j|jj��qjWdj|�}tj|�}|||||||	|
|||
|�S)N�)r(r)�	from_textZ
get_stringZdnssecZalgorithm_from_textZget_intZget_ttlrZget_namer+�getZunescapeZ
is_eol_or_eofZ
is_identifier�	exception�SyntaxError�append�value�encode�join�base64Z	b64decode)�clsr$r%�tokr-r.rrrrrrrrZchunks�tZb64r rrrr1js,


zRRSIG.from_textc	CsPtjd|j|j|j|j|j|j|j�}|j	|�|j
j|d|�|j	|j�dS)Nz!HBBIIIH)
�struct�packrrrrrrr�writer�to_wirer )r#�file�compressr-�headerrrrr@�s

z
RRSIG.to_wirecCs�tjd|||d��}|d7}|d8}tjj|d||�|�\}}	||	7}||	8}|dk	rh|j|�}||||�j�}
||||d|d|d|d|d|d|d	||
�S)
Nz!HBBIIIH�r���r
�r)r=�unpackr(�name�	from_wirer.Zunwrap)r:r$r%ZwireZcurrentZrdlenr-rCrZcusedr rrrrK�s
zRRSIG.from_wirecCs|jj||�|_dS)N)rr+)r#r-r.rrrr+�szRRSIG.choose_relativity)NT)NT)NN)N)NT)rrrr�	__slots__r"r'r*�classmethodr1r@rKr+�
__classcell__rr)r&rr1s


	r)r9rr=rZ
dns.dnssecr(Z
dns.exceptionZ	dns.rdataZ
dns.rdatatyper3ZDNSExceptionrrrr,ZRdatarrrrr�<module>s
PKm�\��M��)rdtypes/ANY/__pycache__/RP.cpython-36.pycnu�[���3

�b�W��@s0ddlZddlZddlZGdd�dejj�ZdS)�NcsleZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	ddd�Z
eddd��Zddd�Z�Z
S)�RPaRP record

    @ivar mbox: The responsible person's mailbox
    @type mbox: dns.name.Name object
    @ivar txt: The owner name of a node with TXT records, or the root name
    if no TXT records are associated with this RP.
    @type txt: dns.name.Name object
    @see: RFC 1183�mbox�txtcs"tt|�j||�||_||_dS)N)�superr�__init__rr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/RP.pyr"szRP.__init__NTcKs0|jj||�}|jj||�}dt|�t|�fS)Nz%s %s)r�choose_relativityr�str)r�origin�
relativize�kwrrrrr�to_text'sz
RP.to_textcCs>|j�}|j�}|j||�}|j||�}|j�|||||�S)N)Zget_namer
Zget_eol)�clsrr	�tokrrrrrrr�	from_text,szRP.from_textcCs$|jj|d|�|jj|d|�dS)N)r�to_wirer)r�file�compressrrrrr5sz
RP.to_wirecCs|jj|�|jj|�S)N)r�
to_digestabler)rrrrrr9s
zRP.to_digestablec
Cs�tjj|d||�|�\}}||7}||8}|dkr>tjj�tjj|d||�|�\}	}||krltjj�|dk	r�|j|�}|	j|�}	|||||	�S)Nr)�dns�name�	from_wireZ	exceptionZ	FormErrorr)
rrr	ZwireZcurrentZrdlenrrZcusedrrrrr=s



zRP.from_wirecCs$|jj||�|_|jj||�|_dS)N)rr
r)rrrrrrr
NszRP.choose_relativity)NT)NT)NN)N)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrrrr
�
__classcell__rr)r
rrs	


r)Z
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarrrrr�<module>sPKm�\&c��1rdtypes/ANY/__pycache__/GPOS.cpython-36.opt-1.pycnu�[���3

�b�W��@sXddlZddlZddlZddlZddlmZmZdd�Zdd�Z	Gdd�dej
j�ZdS)	�N)�long�	text_typecCs�|ddks|ddkr$|dd�}|j�r0dS|jd�\}}|dkrV|dkrVtjj�|dkrv|j�j�rvtjj�|dkr�|j�j�r�tjj�dS)	Nr�-�+��.��-�+)�isdigit�split�dns�	exception�	FormError�decode)Zwhat�left�right�r�/usr/lib/python3.6/GPOS.py�_validate_float_stringsrcCst|t�r|j�S|S)N)�
isinstancer�encode)�valuerrr�	_sanitize&s
rcs�eZdZdZdddgZ�fdd�Zd!d	d
�Zed"dd��Zd#d
d�Z	ed$dd��Z
dd�Zdd�Ze
eedd�Zdd�Zdd�Ze
eedd�Zdd�Zdd�Ze
eed d�Z�ZS)%�GPOSz�GPOS record

    @ivar latitude: latitude
    @type latitude: string
    @ivar longitude: longitude
    @type longitude: string
    @ivar altitude: altitude
    @type altitude: string
    @see: RFC 1712�latitude�	longitude�altitudecs�tt|�j||�t|t�s0t|t�s0t|t�r8t|�}t|t�sVt|t�sVt|t�r^t|�}t|t�s|t|t�s|t|t�r�t|�}t|�}t|�}t|�}t	|�t	|�t	|�||_
||_||_dS)N)
�superr�__init__r�float�intr�strrrrrr)�self�rdclass�rdtyperrr)�	__class__rrr:s,








z
GPOS.__init__NTcKs d|jj�|jj�|jj�fS)Nz%s %s %s)rrrr)r#�origin�
relativize�kwrrr�to_textRs
zGPOS.to_textc	Cs0|j�}|j�}|j�}|j�||||||�S)N)Z
get_stringZget_eol)	�clsr$r%�tokr'r(rrrrrr�	from_textWs
zGPOS.from_textcCs|t|j�}|jtjd|��|j|j�t|j�}|jtjd|��|j|j�t|j�}|jtjd|��|j|j�dS)Nz!B)�lenr�write�struct�packrr)r#�file�compressr'�lrrr�to_wire_s


zGPOS.to_wirecCs�||}|d7}|d8}||kr(tjj�||||�j�}||7}||8}||}|d7}|d8}||krttjj�||||�j�}	||7}||8}||}|d7}|d8}||kr�tjj�||||�j�}
|||||	|
�S)Nr)r
rrZunwrap)r+r$r%ZwireZcurrentZrdlenr'r4rrrrrr�	from_wirems.zGPOS.from_wirecCs
t|j�S)N)r r)r#rrr�_get_float_latitude�szGPOS._get_float_latitudecCst|�|_dS)N)r"r)r#rrrr�_set_float_latitude�szGPOS._set_float_latitudez"latitude as a floating point value)�doccCs
t|j�S)N)r r)r#rrr�_get_float_longitude�szGPOS._get_float_longitudecCst|�|_dS)N)r"r)r#rrrr�_set_float_longitude�szGPOS._set_float_longitudez#longitude as a floating point valuecCs
t|j�S)N)r r)r#rrr�_get_float_altitude�szGPOS._get_float_altitudecCst|�|_dS)N)r"r)r#rrrr�_set_float_altitude�szGPOS._set_float_altitudez"altitude as a floating point value)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr*�classmethodr-r5r6r7r8�propertyZfloat_latituder:r;Zfloat_longituder<r=Zfloat_altitude�
__classcell__rr)r&rr,s*



r)
r0Z
dns.exceptionr
Z	dns.rdataZ
dns.tokenizerZdns._compatrrrrZrdataZRdatarrrrr�<module>sPKm�\���r��+rdtypes/ANY/__pycache__/NSEC.cpython-36.pycnu�[���3

�b�WR�@sLddlZddlZddlZddlZddlZddlmZGdd�dejj	�Z
dS)�N)�xrangecsbeZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	eddd��Z
ddd�Z�ZS)�NSECz�NSEC record

    @ivar next: the next name
    @type next: dns.name.Name object
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples�next�windowscs"tt|�j||�||_||_dS)N)�superr�__init__rr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/NSEC.pyr$sz
NSEC.__init__NTcKs�|jj||�}d}x�|jD]�\}}g}x`tdt|��D]N}	||	}
x@tdd�D]2}|
d|?@rN|jtjj|d|	d|��qNWq6W|ddj	|�7}qWd||fS)N�r���� z%s%s)
r�choose_relativityrr�len�append�dns�	rdatatype�to_text�join)r�origin�
relativize�kwr�text�window�bitmap�bits�i�byte�jrrr
r)s
 zNSEC.to_textcCsB|j�}|j||�}g}xZ|j�j�}|j�r0Ptjj|j�}	|	dkrRtj	j
d��|	dkrftj	j
d��|j|	�qW|j�d}
d}d}t
dd�}
g}x�|D]|}	|	|kr�q�|	}|	d}||
kr�|j|
|
d|�f�t
dd�}
|}
|	d}|d}|d}|d	}|
|d
|?B|
|<q�W|j|
|
d|�f�|||||�S)NrzNSEC with bit 0i��zNSEC with bit > 65535�� rr�r)Zget_namer�getZunescapeZ
is_eol_or_eofrr�	from_text�value�	exception�SyntaxErrorr�sort�	bytearray)�clsr	r
�tokrrrZrdtypes�tokenZnrdtyper�octetsZprior_rdtyperrZ
new_window�offsetr"�bitrrr
r(7sF
zNSEC.from_textcCsJ|jj|d|�x4|jD]*\}}|jtjd|t|���|j|�qWdS)Nz!BB)r�to_wirer�write�struct�packr)r�file�compressrrrrrr
r4^szNSEC.to_wirec
Cs�tjj|d||�|�\}}||7}||8}g}	x�|dkr�|dkrPtjjd��||}
||d}|dkst|dkr�tjjd��|d7}|d8}||kr�tjjd��t||||�j��}||7}||8}|	j|
|f�q4W|dk	r�|j|�}|||||	�S)	Nr�zNSEC too shortr&r%zbad NSEC octets�zbad NSEC bitmap length)	r�name�	from_wirer*Z	FormErrorr-Zunwraprr)
r.r	r
ZwireZcurrentZrdlenrrZcusedrrr1rrrr
r=ds,

zNSEC.from_wirecCs|jj||�|_dS)N)rr)rrrrrr
r}szNSEC.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr(r4r=r�
__classcell__rr)rr
rs
&
r)r6Z
dns.exceptionrZ	dns.rdataZ
dns.rdatatypeZdns.nameZdns._compatrZrdataZRdatarrrrr
�<module>sPKm�\�>���*rdtypes/ANY/__pycache__/AVC.cpython-36.pycnu�[���3

ӓ�W��@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�AVCzbAVC record

    @see: U{http://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template}N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/AVC.pyrsr)Zdns.rdtypes.txtbaseZdnsZrdtypesZtxtbaseZTXTBaserrrrr�<module>sPKm�\����,rdtypes/ANY/__pycache__/EUI64.cpython-36.pycnu�[���3

�b�Wn�@s"ddlZGdd�dejjj�ZdS)�Nc@s eZdZdZdZeddZdS)�EUI64z�EUI64 record

    @ivar fingerprint: 64-bit Extended Unique Identifier (EUI-64)
    @type fingerprint: string
    @see: rfc7043.txt���N)�__name__�
__module__�__qualname__�__doc__Zbyte_lenZtext_len�r
r
�/usr/lib/python3.6/EUI64.pyrsr)Zdns.rdtypes.euibaseZdnsZrdtypesZeuibaseZEUIBaserr
r
r
r�<module>sPKm�\��)	)	1rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-36.pycnu�[���3

�b�W�@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecs\eZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
�ZS)�
NSEC3PARAMaNSEC3PARAM record

    @ivar algorithm: the hash algorithm number
    @type algorithm: int
    @ivar flags: the flags
    @type flags: int
    @ivar iterations: the number of iterations
    @type iterations: int
    @ivar salt: the salt
    @type salt: string�	algorithm�flags�
iterations�saltcsDtt|�j||�||_||_||_t|t�r:|j�|_	n||_	dS)N)
�superr�__init__rrr�
isinstancer�encoder)�self�rdclass�rdtyperrrr)�	__class__�� /usr/lib/python3.6/NSEC3PARAM.pyr	's
zNSEC3PARAM.__init__NTcKs6|jdkrd}ntj|j�j�}d|j|j|j|fS)N��-z%u %u %u %s)r�binasciiZhexlify�decoderrr)r�origin�
relativize�kwrrrr�to_text1s

zNSEC3PARAM.to_textc
CsV|j�}|j�}|j�}|j�}	|	dkr.d}	ntj|	j��}	|j�|||||||	�S)Nr�)Z	get_uint8Z
get_uint16Z
get_stringrZ	unhexlifyrZget_eol)
�clsr
r�tokrrrrrrrrr�	from_text9szNSEC3PARAM.from_textcCs8t|j�}|jtjd|j|j|j|��|j|j�dS)Nz!BBHB)�lenr�write�struct�packrrr)r�file�compressr�lrrr�to_wireFs
zNSEC3PARAM.to_wirecCsvtjd|||d��\}}}	}
|d7}|d8}||||
�j�}||
7}||
8}|dkrdtjj�||||||	|�S)Nz!BBHB�r)r �unpackZunwrap�dnsZ	exceptionZ	FormError)rr
rZwireZcurrentZrdlenrrrrZslenrrrr�	from_wireLszNSEC3PARAM.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r	r�classmethodrr%r)�
__classcell__rr)rrrs


r)
r rZ
dns.exceptionr(Z	dns.rdataZdns._compatrZrdataZRdatarrrrr�<module>s
PKm�\����+rdtypes/ANY/__pycache__/TLSA.cpython-36.pycnu�[���3

�b�W��@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�Ncs\eZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
�ZS)�TLSAa*TLSA record

    @ivar usage: The certificate usage
    @type usage: int
    @ivar selector: The selector field
    @type selector: int
    @ivar mtype: The 'matching type' field
    @type mtype: int
    @ivar cert: The 'Certificate Association Data' field
    @type cert: string
    @see: RFC 6698�usage�selector�mtype�certcs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__��/usr/lib/python3.6/TLSA.pyr's
z
TLSA.__init__NTcKs$d|j|j|jtjj|jdd�fS)Nz%d %d %d %s�)Z	chunksize)rrr�dns�rdataZ_hexifyr)r	�origin�
relativize�kwr
r
r�to_text/s

zTLSA.to_textcCs~|j�}|j�}|j�}g}	x:|j�j�}
|
j�r4P|
j�sDtjj�|	j|
j	j
��qWdj|	�}tj
|�}|||||||�S)N�)Z	get_uint8�getZunescapeZ
is_eol_or_eofZ
is_identifierrZ	exception�SyntaxError�append�value�encode�join�binasciiZ	unhexlify)�clsr
r�tokrrrrrZcert_chunks�trr
r
r�	from_text6s

zTLSA.from_textcCs0tjd|j|j|j�}|j|�|j|j�dS)Nz!BBB)�struct�packrrr�writer)r	�file�compressr�headerr
r
r�to_wireGs
zTLSA.to_wirec	CsZtjd|||d��}|d7}|d8}||||�j�}||||d|d|d|�S)Nz!BBB�r��)r"�unpackZunwrap)	rr
rZwireZcurrentZrdlenrr'rr
r
r�	from_wireLs
zTLSA.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodr!r(r-�
__classcell__r
r
)rrrs

r)r"rZ	dns.rdatarZ
dns.rdatatyperZRdatarr
r
r
r�<module>sPKm�\!�F0��-rdtypes/ANY/__pycache__/DNSKEY.cpython-36.pycnu�[���3

�b�W�@s:ddlZddlmZmZddgZGdd�dejjj�ZdS)�N)�flags_to_text_set�flags_from_text_setrrc@seZdZdZdS)�DNSKEYz
DNSKEY recordN)�__name__�
__module__�__qualname__�__doc__�r	r	�/usr/lib/python3.6/DNSKEY.pyrsr)	Zdns.rdtypes.dnskeybaseZdnsrr�__all__ZrdtypesZ
dnskeybaseZ
DNSKEYBaserr	r	r	r
�<module>sPKm�\��h��0rdtypes/ANY/__pycache__/SOA.cpython-36.opt-1.pycnu�[���3

�b�W��@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsveZdZdZdddddddgZ�fd	d
�Zdd
d�Zeddd��Zddd�Z	ddd�Z
eddd��Zddd�Z�Z
S)�SOAa�SOA record

    @ivar mname: the SOA MNAME (master name) field
    @type mname: dns.name.Name object
    @ivar rname: the SOA RNAME (responsible name) field
    @type rname: dns.name.Name object
    @ivar serial: The zone's serial number
    @type serial: int
    @ivar refresh: The zone's refresh value (in seconds)
    @type refresh: int
    @ivar retry: The zone's retry value (in seconds)
    @type retry: int
    @ivar expire: The zone's expiration value (in seconds)
    @type expire: int
    @ivar minimum: The zone's negative caching time (in seconds, called
    "minimum" for historical reasons)
    @type minimum: int
    @see: RFC 1035�mname�rname�serial�refresh�retry�expire�minimumc

s@tt|�j||�||_||_||_||_||_||_|	|_	dS)N)
�superr�__init__rrrrrrr	)
�self�rdclass�rdtyperrrrrrr	)�	__class__��/usr/lib/python3.6/SOA.pyr/szSOA.__init__NTcKs<|jj||�}|jj||�}d|||j|j|j|j|jfS)Nz%s %s %d %d %d %d %d)r�choose_relativityrrrrrr	)r�origin�
relativize�kwrrrrr�to_text:s
zSOA.to_textc

Csp|j�}|j�}|j||�}|j||�}|j�}|j�}	|j�}
|j�}|j�}|j�|||||||	|
||�	S)N)Zget_namerZ
get_uint32Zget_ttlZget_eol)
�clsr
r�tokrrrrrrrrr	rrr�	from_textAsz
SOA.from_textcCsL|jj|||�|jj|||�tjd|j|j|j|j|j	�}|j
|�dS)Nz!IIIII)r�to_wirer�struct�packrrrrr	�write)r�file�compressr�	five_intsrrrrPs
zSOA.to_wirecCs6|jj|�|jj|�tjd|j|j|j|j|j	�S)Nz!IIIII)
r�
to_digestablerrrrrrrr	)rrrrrr!WszSOA.to_digestablecCs�tjj|d||�|�\}}||7}||8}tjj|d||�|�\}	}||7}||8}|dkrltjj�tjd||||��}
|dk	r�|j|�}|	j|�}	|||||	|
d|
d|
d|
d|
d�	S)N�z!IIIIIr����)�dns�name�	from_wireZ	exceptionZ	FormErrorr�unpackr)rr
rZwireZcurrentZrdlenrrZcusedrr rrrr)]s 


z
SOA.from_wirecCs$|jj||�|_|jj||�|_dS)N)rrr)rrrrrrrpszSOA.choose_relativity)NT)NT)NN)N)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr!r)r�
__classcell__rr)rrrs


r)rZ
dns.exceptionr'Z	dns.rdataZdns.nameZrdataZRdatarrrrr�<module>sPKm�\U���/rdtypes/ANY/__pycache__/__init__.cpython-36.pycnu�[���3

�b�W��@sJdZddddddddd	d
ddd
ddddddddddddddddddgZd S)!z'Class ANY (generic) rdata type classes.ZAFSDBZCDNSKEYZCDSZCERTZCNAMEZDLVZDNAMEZDNSKEYZDSZEUI48ZEUI64ZGPOSZHINFOZHIPZISDNZLOCZMXZNSZNSECZNSEC3Z
NSEC3PARAMZTLSAZPTRZRPZRRSIGZRTZSOAZSPFZSSHFPZTXTZX25N)�__doc__�__all__�rr�/usr/lib/python3.6/__init__.py�<module>s>PKm�\w-��,rdtypes/ANY/__pycache__/EUI48.cpython-36.pycnu�[���3

�b�Wd�@s"ddlZGdd�dejjj�ZdS)�Nc@s eZdZdZdZeddZdS)�EUI48z�EUI48 record

    @ivar fingerprint: 48-bit Extended Unique Identifier (EUI-48)
    @type fingerprint: string
    @see: rfc7043.txt���N)�__name__�
__module__�__qualname__�__doc__Zbyte_lenZtext_len�r
r
�/usr/lib/python3.6/EUI48.pyrsr)Zdns.rdtypes.euibaseZdnsZrdtypesZeuibaseZEUIBaserr
r
r
r�<module>sPKm�\�ݹSXX/rdtypes/ANY/__pycache__/MX.cpython-36.opt-1.pycnu�[���3

�b�Wi�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�MXz	MX recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/MX.pyrsr)Zdns.rdtypes.mxbaseZdnsZrdtypesZmxbaseZMXBaserrrrr�<module>sPKm�\!�F0��3rdtypes/ANY/__pycache__/DNSKEY.cpython-36.opt-1.pycnu�[���3

�b�W�@s:ddlZddlmZmZddgZGdd�dejjj�ZdS)�N)�flags_to_text_set�flags_from_text_setrrc@seZdZdZdS)�DNSKEYz
DNSKEY recordN)�__name__�
__module__�__qualname__�__doc__�r	r	�/usr/lib/python3.6/DNSKEY.pyrsr)	Zdns.rdtypes.dnskeybaseZdnsrr�__all__ZrdtypesZ
dnskeybaseZ
DNSKEYBaserr	r	r	r
�<module>sPKm�\�eQ??,rdtypes/ANY/__pycache__/AFSDB.cpython-36.pycnu�[���3

�b�W8�@s"ddlZGdd�dejjj�ZdS)�Nc@sDeZdZdZdd�Zdd�Zeee�Zdd�Zdd	�Z	eee	�Z
d
S)�AFSDBz�AFSDB record

    @ivar subtype: the subtype value
    @type subtype: int
    @ivar hostname: the hostname name
    @type hostname: dns.name.Name objectcCs|jS)N)�
preference)�self�r�/usr/lib/python3.6/AFSDB.py�get_subtype'szAFSDB.get_subtypecCs
||_dS)N)r)r�subtyperrr�set_subtype*szAFSDB.set_subtypecCs|jS)N)�exchange)rrrr�get_hostname/szAFSDB.get_hostnamecCs
||_dS)N)r
)r�hostnamerrr�set_hostname2szAFSDB.set_hostnameN)�__name__�
__module__�__qualname__�__doc__rr	�propertyrrr
rrrrrrs

r)Zdns.rdtypes.mxbaseZdnsZrdtypesZmxbaseZUncompressedDowncasingMXrrrrr�<module>sPKm�\#c� ..2rdtypes/ANY/__pycache__/CNAME.cpython-36.opt-1.pycnu�[���3

�b�W<�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�CNAMEz�CNAME record

    Note: although CNAME is officially a singleton type, dnspython allows
    non-singleton CNAME rdatasets because such sets have been commonly
    used by BIND and other nameservers for load balancing.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/CNAME.pyrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZNSBaserrrrr�<module>sPKm�\T/��[[0rdtypes/ANY/__pycache__/CDS.cpython-36.opt-1.pycnu�[���3

�b�Wk�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�CDSz
CDS recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/CDS.pyrsr)Zdns.rdtypes.dsbaseZdnsZrdtypesZdsbaseZDSBaserrrrr�<module>sPKm�\�UXTXX)rdtypes/ANY/__pycache__/DS.cpython-36.pycnu�[���3

�b�Wi�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�DSz	DS recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/DS.pyrsr)Zdns.rdtypes.dsbaseZdnsZrdtypesZdsbaseZDSBaserrrrr�<module>sPKm�\��+�((*rdtypes/ANY/__pycache__/CAA.cpython-36.pycnu�[���3

�b�W>
�@s8ddlZddlZddlZddlZGdd�dejj�ZdS)�NcsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�CAAz�CAA (Certification Authority Authorization) record

    @ivar flags: the flags
    @type flags: int
    @ivar tag: the tag
    @type tag: string
    @ivar value: the value
    @type value: string
    @see: RFC 6844�flags�tag�valuecs(tt|�j||�||_||_||_dS)N)�superr�__init__rrr)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/CAA.pyr%szCAA.__init__NTcKs$d|jtjj|j�tjj|j�fS)Nz
%u %s "%s")r�dns�rdataZ	_escapifyrr)r�origin�
relativize�kwrrr
�to_text+szCAA.to_textc	Cs\|j�}|j�j�}t|�dkr,tjjd��|j�s@tjjd��|j�j�}||||||�S)N�ztag too longztag is not alphanumeric)Z	get_uint8Z
get_string�encode�lenrZ	exception�SyntaxError�isalnum)	�clsr	r
�tokrrrrrrrr
�	from_text0sz
CAA.from_textcCsX|jtjd|j��t|j�}|dks*t�|jtjd|��|j|j�|j|j�dS)Nz!B�)�write�struct�packrrr�AssertionErrorr)r�file�compressr�lrrr
�to_wire;s
zCAA.to_wirecCs\tjd|||d��\}}|d7}||||�}	|||||d�}
|||||	|
�S)Nz!BB�)r�unpack)rr	r
ZwireZcurrentZrdlenrrr#rrrrr
�	from_wireCs
z
CAA.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr$r'�
__classcell__rr)rr
rs




r)rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerrZRdatarrrrr
�<module>sPKm�\5�rr0rdtypes/ANY/__pycache__/SPF.cpython-36.opt-1.pycnu�[���3

�b�W��@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�SPFzSPF record

    @see: RFC 4408N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/SPF.pyrsr)Zdns.rdtypes.txtbaseZdnsZrdtypesZtxtbaseZTXTBaserrrrr�<module>sPKm�\U���5rdtypes/ANY/__pycache__/__init__.cpython-36.opt-1.pycnu�[���3

�b�W��@sJdZddddddddd	d
ddd
ddddddddddddddddddgZd S)!z'Class ANY (generic) rdata type classes.ZAFSDBZCDNSKEYZCDSZCERTZCNAMEZDLVZDNAMEZDNSKEYZDSZEUI48ZEUI64ZGPOSZHINFOZHIPZISDNZLOCZMXZNSZNSECZNSEC3Z
NSEC3PARAMZTLSAZPTRZRPZRRSIGZRTZSOAZSPFZSSHFPZTXTZX25N)�__doc__�__all__�rr�/usr/lib/python3.6/__init__.py�<module>s>PKm�\���__2rdtypes/ANY/__pycache__/RRSIG.cpython-36.opt-1.pycnu�[���3

�b�W�@s|ddlZddlZddlZddlZddlZddlZddlZddlZGdd�dej	j
�Zdd�Zdd�Z
Gdd	�d	ejj�ZdS)
�Nc@seZdZdZdS)�
BadSigTimez:Time in DNS SIG or RRSIG resource record cannot be parsed.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/RRSIG.pyrsrc
Cs�t|�dkrt�t|dd��}t|dd��}t|dd��}t|dd��}t|dd��}t|dd��}tj||||||dddf	�S)N�r����
�)�lenr�int�calendarZtimegm)�whatZyearZmonthZdayZhourZminute�secondrrr�sigtime_to_posixtime srcCstjdtj|��S)Nz%Y%m%d%H%M%S)�timeZstrftimeZgmtime)rrrr�posixtime_to_sigtime-src	sxeZdZdZdddddddd	d
g	Z�fdd�Zd
d�Zddd�Zeddd��Z	ddd�Z
eddd��Zddd�Z�Z
S) �RRSIGa~RRSIG record

    @ivar type_covered: the rdata type this signature covers
    @type type_covered: int
    @ivar algorithm: the algorithm used for the sig
    @type algorithm: int
    @ivar labels: number of labels
    @type labels: int
    @ivar original_ttl: the original TTL
    @type original_ttl: long
    @ivar expiration: signature expiration time
    @type expiration: long
    @ivar inception: signature inception time
    @type inception: long
    @ivar key_tag: the key tag
    @type key_tag: int
    @ivar signer: the signer
    @type signer: dns.name.Name object
    @ivar signature: the signature
    @type signature: string�type_covered�	algorithm�labels�original_ttl�
expiration�	inception�key_tag�signer�	signaturecsLtt|�j||�||_||_||_||_||_||_|	|_	|
|_
||_dS)N)�superr�__init__rrrrrrrrr )�self�rdclass�rdtyperrrrrrrrr )�	__class__rrr"LszRRSIG.__init__cCs|jS)N)r)r#rrr�coversZszRRSIG.coversNTcKsLdtjj|j�|j|j|jt|j�t|j	�|j
|jj||�tj
j|j�f	S)Nz%s %d %d %d %s %s %d %s %s)�dns�	rdatatype�to_textrrrrrrrrr�choose_relativity�rdataZ
_base64ifyr )r#�origin�
relativize�kwrrrr*]sz
RRSIG.to_textcCs�tjj|j��}tjj|j��}|j�}|j�}	t|j��}
t|j��}|j�}|j	�}
|
j
||�}
g}x:|j�j�}|j
�r�P|j�s�tjj�|j|jj��qjWdj|�}tj|�}|||||||	|
|||
|�S)N�)r(r)�	from_textZ
get_stringZdnssecZalgorithm_from_textZget_intZget_ttlrZget_namer+�getZunescapeZ
is_eol_or_eofZ
is_identifier�	exception�SyntaxError�append�value�encode�join�base64Z	b64decode)�clsr$r%�tokr-r.rrrrrrrrZchunks�tZb64r rrrr1js,


zRRSIG.from_textc	CsPtjd|j|j|j|j|j|j|j�}|j	|�|j
j|d|�|j	|j�dS)Nz!HBBIIIH)
�struct�packrrrrrrr�writer�to_wirer )r#�file�compressr-�headerrrrr@�s

z
RRSIG.to_wirecCs�tjd|||d��}|d7}|d8}tjj|d||�|�\}}	||	7}||	8}|dk	rh|j|�}||||�j�}
||||d|d|d|d|d|d|d	||
�S)
Nz!HBBIIIH�r���r
�r)r=�unpackr(�name�	from_wirer.Zunwrap)r:r$r%ZwireZcurrentZrdlenr-rCrZcusedr rrrrK�s
zRRSIG.from_wirecCs|jj||�|_dS)N)rr+)r#r-r.rrrr+�szRRSIG.choose_relativity)NT)NT)NN)N)NT)rrrr�	__slots__r"r'r*�classmethodr1r@rKr+�
__classcell__rr)r&rr1s


	r)r9rr=rZ
dns.dnssecr(Z
dns.exceptionZ	dns.rdataZ
dns.rdatatyper3ZDNSExceptionrrrr,ZRdatarrrrr�<module>s
PKm�\��?rjj/rdtypes/ANY/__pycache__/RT.cpython-36.opt-1.pycnu�[���3

�b�W{�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�RTz	RT recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/RT.pyrsr)Zdns.rdtypes.mxbaseZdnsZrdtypesZmxbaseZUncompressedDowncasingMXrrrrr�<module>sPKm�\T/��[[*rdtypes/ANY/__pycache__/CDS.cpython-36.pycnu�[���3

�b�Wk�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�CDSz
CDS recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/CDS.pyrsr)Zdns.rdtypes.dsbaseZdnsZrdtypesZdsbaseZDSBaserrrrr�<module>sPKm�\[[QXX)rdtypes/ANY/__pycache__/NS.cpython-36.pycnu�[���3

�b�Wi�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�NSz	NS recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/NS.pyrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZNSBaserrrrr�<module>sPKm�\��?rjj)rdtypes/ANY/__pycache__/RT.cpython-36.pycnu�[���3

�b�W{�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�RTz	RT recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/RT.pyrsr)Zdns.rdtypes.mxbaseZdnsZrdtypesZmxbaseZUncompressedDowncasingMXrrrrr�<module>sPKm�\�.�M��*rdtypes/ANY/__pycache__/X25.cpython-36.pycnu�[���3

�b�WG�@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�X25z\X25 record

    @ivar address: the PSDN address
    @type address: string
    @see: RFC 1183�addresscs2tt|�j||�t|t�r(|j�|_n||_dS)N)�superr�__init__�
isinstancer�encoder)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/X25.pyr"s
zX25.__init__NTcKsdtjj|j�S)Nz"%s")�dns�rdataZ	_escapifyr)r	�origin�
relativize�kwr
r
r�to_text)szX25.to_textcCs|j�}|j�||||�S)N)Z
get_stringZget_eol)�clsr
r�tokrrrr
r
r�	from_text,sz
X25.from_textcCs8t|j�}|dkst�|jtjd|��|j|j�dS)N�z!B)�lenr�AssertionError�write�struct�pack)r	�file�compressr�lr
r
r�to_wire2s
zX25.to_wirec	CsH||}|d7}|d8}||kr(tjj�||||�j�}||||�S)N�)rZ	exceptionZ	FormErrorZunwrap)	rr
rZwireZcurrentZrdlenrr rr
r
r�	from_wire8sz
X25.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr!r#�
__classcell__r
r
)rrrs

r)
rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZdns._compatrrZRdatarr
r
r
r�<module>s
PKm�\j/�jk k 0rdtypes/ANY/__pycache__/LOC.cpython-36.opt-1.pycnu�[���3

�b�W�/�@s�ddlmZddlZddlZddlZddlmZmZm	Z	e
dd�edd�D��ZdZ
dZd	Zd
d�Zdd
�Zdd�Zdd�Zdd�ZGdd�dejj�ZdS)�)�divisionN)�long�xrange�round_py2_compatccs|]}td|�VqdS)�
N)r)�.0�i�r	�/usr/lib/python3.6/LOC.py�	<genexpr>sr�gY@g��.Ag@�@cCsh|dkrdSd}x2ttt��D]"}|t|td�kr|d}PqW|dksT|dkrdtjjd|��|S)Nr�z%s value out of bounds)r�len�_powsr�dns�	exception�SyntaxError)�what�descZexprr	r	r
�_exponent_of!srcCs�|dkrd}|d9}nd}t|d�}t|d�}||d8}t|d�}||d8}t|d�}|t|d�8}t|�}|||||fS)Nrr
i��6i`�i����r)r�int)rZsignZdegreesZminutes�secondsr	r	r
�_float_to_tuple.s
rcCsXt|d�}|t|d�d7}|t|d�d7}|t|d�d7}t|d�|S)	Nrr
gN@�g �@�g@wKA�)�float)r�valuer	r	r
�_tuple_to_float?s
rcCs4t|�}t||�d@}|td|�d@}|d|S)N�r�)rr�pow)rr�exponent�baser	r	r
�_encode_sizeGsr%cCsV|d@}|dkr tjjd|��|d@d?}|dkrDtjjd|��t|�td|�S)Nr �	zbad %s exponent��rzbad %s baser)rrrrr")rrr#r$r	r	r
�_decode_sizeNsr(cs�eZdZdZddddddgZeeef�fdd	�	Zddd
�Z	e
d dd��Zd!dd�Ze
d"dd��Z
dd�Zdd�Zeeedd�Zdd�Zdd�Zeeedd�Z�ZS)#�LOCa�LOC record

    @ivar latitude: latitude
    @type latitude: (int, int, int, int, sign) tuple specifying the degrees, minutes,
    seconds, milliseconds, and sign of the coordinate.
    @ivar longitude: longitude
    @type longitude: (int, int, int, int, sign) tuple specifying the degrees,
    minutes, seconds, milliseconds, and sign of the coordinate.
    @ivar altitude: altitude
    @type altitude: float
    @ivar size: size of the sphere
    @type size: float
    @ivar horizontal_precision: horizontal precision
    @type horizontal_precision: float
    @ivar vertical_precision: vertical precision
    @type vertical_precision: float
    @see: RFC 1876�latitude�	longitude�altitude�size�horizontal_precision�vertical_precisionc		s�tt|�j||�t|t�s&t|t�r.t|�}t|t�r@t|�}||_t|t�sZt|t�rbt|�}t|t�rtt|�}||_	t|�|_
t|�|_t|�|_t|�|_
dS)a�Initialize a LOC record instance.

        The parameters I{latitude} and I{longitude} may be either a 4-tuple
        of integers specifying (degrees, minutes, seconds, milliseconds),
        or they may be floating point values specifying the number of
        degrees. The other parameters are floats. Size, horizontal precision,
        and vertical precision are specified in centimeters.N)�superr)�__init__�
isinstancerrrrr*r+r,r-r.r/)	�self�rdclass�rdtyper*r+r,r-�hprec�vprec)�	__class__r	r
r1os




zLOC.__init__NTc
Ks�|jddkrd}nd}|jddkr,d}nd}d|jd|jd|jd	|jd
||jd|jd|jd	|jd
||jdf}|jtks�|jtks�|jtkr�|d|jd|jd|jdf7}|S)
Nrr�N�S�E�Wz(%d %d %d.%03d %s %d %d %d.%03d %s %0.2fmr
rrgY@z %0.2fm %0.2fm %0.2fm)	r*r+r,r-�
_default_sizer.�_default_hprecr/�_default_vprec)r3�origin�
relativize�kwZlat_hemisphereZlong_hemisphere�textr	r	r
�to_text�s&



zLOC.to_textc	Cs�dddddg}dddddg}t}t}	t}
|j�|d<|j�}|j��r0t|�|d<|j�}d|k�r|jd�\}}
|j�s�tj	j
d��t|�|d<|ddkr�tj	j
d��t|
�}|dks�|dks�|
j�r�tj	j
d	��|dkr�d
}n|dkr�d}nd}|t|
�|d<|j�}n|j��r0t|�|d<|j�}|dk�rDd|d
<n|dk�rZtj	j
d��|j�|d<|j�}|j��rpt|�|d<|j�}d|k�rR|jd�\}}
|j��s�tj	j
d��t|�|d<|ddk�r�tj	j
d��t|
�}|dk�s|dk�s|
j��rtj	j
d��|dk�r$d
}n|dk�r4d}nd}|t|
�|d<|j�}n|j��rpt|�|d<|j�}|dk�r�d|d
<n|dk�r�tj	j
d��|j�}|ddk�r�|dd�}t|�d}|j
�j�}|j��s�|j}|ddk�r�|dd�}t|�d}|j
�j�}|j��s�|j}|ddk�r@|dd�}t|�d}	|j
�j�}|j��s�|j}|d dk�r�|dd!�}t|�d}
|j�||||||||	|
�S)"Nrr
�.zbad latitude seconds valuer�<zlatitude seconds >= 60rzbad latitude milliseconds value�drr:rr9zbad latitude hemisphere valuezbad longitude seconds valuezlongitude seconds >= 60z bad longitude milliseconds valuer<r;zbad longitude hemisphere value�mgY@rrrrrrrrrr)r=r>r?Zget_intZ
get_string�isdigitr�splitrrrrr�getZunescapeZ
is_eol_or_eofrZget_eol)�clsr4r5�tokr@rAr*r+r-r6r7�tr�milliseconds�lrHr,�tokenrr	r	r
�	from_text�s�









 









z
LOC.from_textc	Cs�|jdd|jdd|jdd|jd|jd}td	�|}|jdd|jdd|jdd|jd|jd}td	�|}t|j�td
�}t|jd�}t|jd�}	t|jd
�}
tj	dd||	|
|||�}|j
|�dS)Nri��6r
i`�ri�rrli���r-zhorizontal precisionzvertical precisionz!BBBBIII)r*rr+r,r%r-r.r/�struct�pack�write)r3�file�compressr@rOr*r+r,r-r6r7�wirer	r	r
�to_wires((zLOC.to_wirec	Cstjd||||��\}}}	}
}}}
|td�krHt|td��d}nd
ttd�|�d}|dksp|dkr|tjjd��|td�kr�t|td��d}ndttd�|�d}|dks�|dkr�tjjd��t|
�d	}
t|d
�}t|	d�}	t|
d�}
||||||
||	|
�S)Nz!BBBBIIIli��6r
g�V@zbad latitudeg�f@z
bad longitudeg�cAr-zhorizontal precisionzvertical precisionrg�V�rg�f�)rS�unpackrrrrZ	FormErrorr()rLr4r5rXZcurrentZrdlenr@�versionr-r6r7r*r+r,r	r	r
�	from_wires"&


z
LOC.from_wirecCs
t|j�S)N)rr*)r3r	r	r
�_get_float_latitude5szLOC._get_float_latitudecCst|�|_dS)N)rr*)r3rr	r	r
�_set_float_latitude8szLOC._set_float_latitudez"latitude as a floating point value)�doccCs
t|j�S)N)rr+)r3r	r	r
�_get_float_longitude>szLOC._get_float_longitudecCst|�|_dS)N)rr+)r3rr	r	r
�_set_float_longitudeAszLOC._set_float_longitudez#longitude as a floating point value)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r=r>r?r1rD�classmethodrRrYr\r]r^�propertyZfloat_latituder`raZfloat_longitude�
__classcell__r	r	)r8r
r)Xs&
e
r))Z
__future__rrSZ
dns.exceptionrZ	dns.rdataZdns._compatrrr�tuple�rangerr=r>r?rrrr%r(ZrdataZRdatar)r	r	r	r
�<module>s

PKm�\�\m
��*rdtypes/ANY/__pycache__/HIP.cpython-36.pycnu�[���3

�b�W0�@sHddlZddlZddlZddlZddlZddlZGdd�dejj�Z	dS)�NcsfeZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
ddd�Z�ZS)�HIPa=HIP record

    @ivar hit: the host identity tag
    @type hit: string
    @ivar algorithm: the public key cryptographic algorithm
    @type algorithm: int
    @ivar key: the public key
    @type key: string
    @ivar servers: the rendezvous servers
    @type servers: list of dns.name.Name objects
    @see: RFC 5205�hit�	algorithm�key�serverscs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__��/usr/lib/python3.6/HIP.pyr)s
zHIP.__init__NTc	Ks�tj|j�j�}tj|j�jdd�j�}d}g}x |jD]}|j	|j
||��q8Wt|�dkrz|ddjdd�|D��7}d|j
|||fS)	N�
��r� css|]}|j�VqdS)N)Z
to_unicode)�.0�xr
r
r�	<genexpr>8szHIP.to_text.<locals>.<genexpr>z
%u %s %s%s)�binasciiZhexlifyr�decode�base64Z	b64encoder�replacer�append�choose_relativity�len�joinr)	r	�origin�
relativize�kwrr�textr�serverr
r
r�to_text0szHIP.to_textcCs�|j�}tj|j�j��}t|�dkr2tjjd��t	j
|j�j��}g}	x<|j�}
|
j�r\Ptj
j|
j|�}|j||�|	j|�qJW|||||||	�S)N�zHIT too long)Z	get_uint8rZ	unhexlifyZ
get_string�encoder�dnsZ	exception�SyntaxErrorrZ	b64decode�getZ
is_eol_or_eof�name�	from_text�valuerr)�clsr
r�tokrrrrrr�tokenr"r
r
rr*;sz
HIP.from_textcCsft|j�}t|j�}|jtjd||j|��|j|j�|j|j�x|jD]}|j|d|�qLWdS)Nz!BBH)	rrr�write�struct�packrr�to_wire)r	�file�compressr�lh�lkr"r
r
rr2Ls

zHIP.to_wirecCs�tjd|||d��\}}}	|d7}|d8}||||�j�}
||7}||8}||||	�j�}||	7}||	8}g}xV|dkr�tjj|d||�|�\}
}||7}||8}|dk	r�|
j|�}
|j|
�q|W||||
|||�S)Nz!BBH�r)r0�unpackZunwrapr&r)�	from_wirerr)r,r
rZwireZcurrentZrdlenrr5rr6rrrr"Zcusedr
r
rr9Us(


z
HIP.from_wirecCs4g}x$|jD]}|j||�}|j|�qW||_dS)N)rrr)r	rrrr"r
r
rrls
zHIP.choose_relativity)NT)NT)NN)N)NT)
�__name__�
__module__�__qualname__�__doc__�	__slots__rr#�classmethodr*r2r9r�
__classcell__r
r
)rrrs

	r)
r0rrZ
dns.exceptionr&Z	dns.rdataZ
dns.rdatatypeZrdataZRdatarr
r
r
r�<module>sPKm�\j/�jk k *rdtypes/ANY/__pycache__/LOC.cpython-36.pycnu�[���3

�b�W�/�@s�ddlmZddlZddlZddlZddlmZmZm	Z	e
dd�edd�D��ZdZ
dZd	Zd
d�Zdd
�Zdd�Zdd�Zdd�ZGdd�dejj�ZdS)�)�divisionN)�long�xrange�round_py2_compatccs|]}td|�VqdS)�
N)r)�.0�i�r	�/usr/lib/python3.6/LOC.py�	<genexpr>sr�gY@g��.Ag@�@cCsh|dkrdSd}x2ttt��D]"}|t|td�kr|d}PqW|dksT|dkrdtjjd|��|S)Nr�z%s value out of bounds)r�len�_powsr�dns�	exception�SyntaxError)�what�descZexprr	r	r
�_exponent_of!srcCs�|dkrd}|d9}nd}t|d�}t|d�}||d8}t|d�}||d8}t|d�}|t|d�8}t|�}|||||fS)Nrr
i��6i`�i����r)r�int)rZsignZdegreesZminutes�secondsr	r	r
�_float_to_tuple.s
rcCsXt|d�}|t|d�d7}|t|d�d7}|t|d�d7}t|d�|S)	Nrr
gN@�g �@�g@wKA�)�float)r�valuer	r	r
�_tuple_to_float?s
rcCs4t|�}t||�d@}|td|�d@}|d|S)N�r�)rr�pow)rr�exponent�baser	r	r
�_encode_sizeGsr%cCsV|d@}|dkr tjjd|��|d@d?}|dkrDtjjd|��t|�td|�S)Nr �	zbad %s exponent��rzbad %s baser)rrrrr")rrr#r$r	r	r
�_decode_sizeNsr(cs�eZdZdZddddddgZeeef�fdd	�	Zddd
�Z	e
d dd��Zd!dd�Ze
d"dd��Z
dd�Zdd�Zeeedd�Zdd�Zdd�Zeeedd�Z�ZS)#�LOCa�LOC record

    @ivar latitude: latitude
    @type latitude: (int, int, int, int, sign) tuple specifying the degrees, minutes,
    seconds, milliseconds, and sign of the coordinate.
    @ivar longitude: longitude
    @type longitude: (int, int, int, int, sign) tuple specifying the degrees,
    minutes, seconds, milliseconds, and sign of the coordinate.
    @ivar altitude: altitude
    @type altitude: float
    @ivar size: size of the sphere
    @type size: float
    @ivar horizontal_precision: horizontal precision
    @type horizontal_precision: float
    @ivar vertical_precision: vertical precision
    @type vertical_precision: float
    @see: RFC 1876�latitude�	longitude�altitude�size�horizontal_precision�vertical_precisionc		s�tt|�j||�t|t�s&t|t�r.t|�}t|t�r@t|�}||_t|t�sZt|t�rbt|�}t|t�rtt|�}||_	t|�|_
t|�|_t|�|_t|�|_
dS)a�Initialize a LOC record instance.

        The parameters I{latitude} and I{longitude} may be either a 4-tuple
        of integers specifying (degrees, minutes, seconds, milliseconds),
        or they may be floating point values specifying the number of
        degrees. The other parameters are floats. Size, horizontal precision,
        and vertical precision are specified in centimeters.N)�superr)�__init__�
isinstancerrrrr*r+r,r-r.r/)	�self�rdclass�rdtyper*r+r,r-�hprec�vprec)�	__class__r	r
r1os




zLOC.__init__NTc
Ks�|jddkrd}nd}|jddkr,d}nd}d|jd|jd|jd	|jd
||jd|jd|jd	|jd
||jdf}|jtks�|jtks�|jtkr�|d|jd|jd|jdf7}|S)
Nrr�N�S�E�Wz(%d %d %d.%03d %s %d %d %d.%03d %s %0.2fmr
rrgY@z %0.2fm %0.2fm %0.2fm)	r*r+r,r-�
_default_sizer.�_default_hprecr/�_default_vprec)r3�origin�
relativize�kwZlat_hemisphereZlong_hemisphere�textr	r	r
�to_text�s&



zLOC.to_textc	Cs�dddddg}dddddg}t}t}	t}
|j�|d<|j�}|j��r0t|�|d<|j�}d|k�r|jd�\}}
|j�s�tj	j
d��t|�|d<|ddkr�tj	j
d��t|
�}|dks�|dks�|
j�r�tj	j
d	��|dkr�d
}n|dkr�d}nd}|t|
�|d<|j�}n|j��r0t|�|d<|j�}|dk�rDd|d
<n|dk�rZtj	j
d��|j�|d<|j�}|j��rpt|�|d<|j�}d|k�rR|jd�\}}
|j��s�tj	j
d��t|�|d<|ddk�r�tj	j
d��t|
�}|dk�s|dk�s|
j��rtj	j
d��|dk�r$d
}n|dk�r4d}nd}|t|
�|d<|j�}n|j��rpt|�|d<|j�}|dk�r�d|d
<n|dk�r�tj	j
d��|j�}|ddk�r�|dd�}t|�d}|j
�j�}|j��s�|j}|ddk�r�|dd�}t|�d}|j
�j�}|j��s�|j}|ddk�r@|dd�}t|�d}	|j
�j�}|j��s�|j}|d dk�r�|dd!�}t|�d}
|j�||||||||	|
�S)"Nrr
�.zbad latitude seconds valuer�<zlatitude seconds >= 60rzbad latitude milliseconds value�drr:rr9zbad latitude hemisphere valuezbad longitude seconds valuezlongitude seconds >= 60z bad longitude milliseconds valuer<r;zbad longitude hemisphere value�mgY@rrrrrrrrrr)r=r>r?Zget_intZ
get_string�isdigitr�splitrrrrr�getZunescapeZ
is_eol_or_eofrZget_eol)�clsr4r5�tokr@rAr*r+r-r6r7�tr�milliseconds�lrHr,�tokenrr	r	r
�	from_text�s�









 









z
LOC.from_textc	Cs�|jdd|jdd|jdd|jd|jd}td	�|}|jdd|jdd|jdd|jd|jd}td	�|}t|j�td
�}t|jd�}t|jd�}	t|jd
�}
tj	dd||	|
|||�}|j
|�dS)Nri��6r
i`�ri�rrli���r-zhorizontal precisionzvertical precisionz!BBBBIII)r*rr+r,r%r-r.r/�struct�pack�write)r3�file�compressr@rOr*r+r,r-r6r7�wirer	r	r
�to_wires((zLOC.to_wirec	Cstjd||||��\}}}	}
}}}
|td�krHt|td��d}nd
ttd�|�d}|dksp|dkr|tjjd��|td�kr�t|td��d}ndttd�|�d}|dks�|dkr�tjjd��t|
�d	}
t|d
�}t|	d�}	t|
d�}
||||||
||	|
�S)Nz!BBBBIIIli��6r
g�V@zbad latitudeg�f@z
bad longitudeg�cAr-zhorizontal precisionzvertical precisionrg�V�rg�f�)rS�unpackrrrrZ	FormErrorr()rLr4r5rXZcurrentZrdlenr@�versionr-r6r7r*r+r,r	r	r
�	from_wires"&


z
LOC.from_wirecCs
t|j�S)N)rr*)r3r	r	r
�_get_float_latitude5szLOC._get_float_latitudecCst|�|_dS)N)rr*)r3rr	r	r
�_set_float_latitude8szLOC._set_float_latitudez"latitude as a floating point value)�doccCs
t|j�S)N)rr+)r3r	r	r
�_get_float_longitude>szLOC._get_float_longitudecCst|�|_dS)N)rr+)r3rr	r	r
�_set_float_longitudeAszLOC._set_float_longitudez#longitude as a floating point value)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r=r>r?r1rD�classmethodrRrYr\r]r^�propertyZfloat_latituder`raZfloat_longitude�
__classcell__r	r	)r8r
r)Xs&
e
r))Z
__future__rrSZ
dns.exceptionrZ	dns.rdataZdns._compatrrr�tuple�rangerr=r>r?rrrr%r(ZrdataZRdatar)r	r	r	r
�<module>s

PKm�\�!s,rdtypes/ANY/__pycache__/DNAME.cpython-36.pycnu�[���3

�b�W��@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZddd�ZdS)�DNAMEzDNAME recordNcCs|jj|�S)N)�target�
to_digestable)�self�origin�r�/usr/lib/python3.6/DNAME.pyrszDNAME.to_digestable)N)�__name__�
__module__�__qualname__�__doc__rrrrrrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZUncompressedNSrrrrr�<module>sPKm�\�j+���+rdtypes/ANY/__pycache__/CERT.cpython-36.pycnu�[���3

�b�Wo�@sxddlZddlZddlZddlZddlZddlZdddddd�Zdd	d
ddd
�Zdd�Z	dd�Z
Gdd�dejj�Z
dS)�N�PKIX�SPKI�PGP�URI�OID)�����rrr	r
r)rrrrrcCstj|�}|dk	r|St|�S)N)�_ctype_by_name�get�int)�what�v�r�/usr/lib/python3.6/CERT.py�_ctype_from_text)s
rcCstj|�}|dk	r|St|�S)N)�_ctype_by_valuer
�str)rrrrr�_ctype_to_text0s
rcs\eZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
�ZS)�CERTa"CERT record

    @ivar certificate_type: certificate type
    @type certificate_type: int
    @ivar key_tag: key tag
    @type key_tag: int
    @ivar algorithm: algorithm
    @type algorithm: int
    @ivar certificate: the certificate or CRL
    @type certificate: string
    @see: RFC 2538�certificate_type�key_tag�	algorithm�certificatecs.tt|�j||�||_||_||_||_dS)N)�superr�__init__rrrr)�self�rdclass�rdtyperrrr)�	__class__rrrGs
z
CERT.__init__NTcKs0t|j�}d||jtjj|j�tjj|j	�fS)Nz%s %d %s %s)
rrr�dns�dnssecZalgorithm_to_textr�rdataZ
_base64ifyr)r�origin�
relativize�kwrrrr�to_textOs
zCERT.to_textc
Cs�t|j��}|j�}tjj|j��}|dks4|dkr@tjjd��g}	x:|j�j	�}
|
j
�r\P|
j�sltjj�|	j|
j
j��qFWdj|	�}tj|�}|||||||�S)Nr�zbad algorithm type�)rZ
get_stringZ
get_uint16r"r#Zalgorithm_from_text�	exception�SyntaxErrorr
ZunescapeZ
is_eol_or_eofZ
is_identifier�append�value�encode�join�base64Z	b64decode)
�clsrr �tokr%r&rrrZchunks�tZb64rrrr�	from_textUs"


zCERT.from_textcCs0tjd|j|j|j�}|j|�|j|j�dS)Nz!HHB)�struct�packrrr�writer)r�file�compressr%�prefixrrr�to_wireis
zCERT.to_wirecCsl|||d�j�}|d7}|d8}|dkr4tjj�tjd|�\}}	}
||||�j�}|||||	|
|�S)N�rz!HHB)Zunwrapr"r+Z	FormErrorr6�unpack)r2rr ZwireZcurrentZrdlenr%r;rrrrrrr�	from_wireoszCERT.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr(�classmethodr5r<r?�
__classcell__rr)r!rr7s

r)r6r1Z
dns.exceptionr"Z
dns.dnssecZ	dns.rdataZ
dns.tokenizerrrrrr$ZRdatarrrrr�<module>s$PKm�\��M��/rdtypes/ANY/__pycache__/RP.cpython-36.opt-1.pycnu�[���3

�b�W��@s0ddlZddlZddlZGdd�dejj�ZdS)�NcsleZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	ddd�Z
eddd��Zddd�Z�Z
S)�RPaRP record

    @ivar mbox: The responsible person's mailbox
    @type mbox: dns.name.Name object
    @ivar txt: The owner name of a node with TXT records, or the root name
    if no TXT records are associated with this RP.
    @type txt: dns.name.Name object
    @see: RFC 1183�mbox�txtcs"tt|�j||�||_||_dS)N)�superr�__init__rr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/RP.pyr"szRP.__init__NTcKs0|jj||�}|jj||�}dt|�t|�fS)Nz%s %s)r�choose_relativityr�str)r�origin�
relativize�kwrrrrr�to_text'sz
RP.to_textcCs>|j�}|j�}|j||�}|j||�}|j�|||||�S)N)Zget_namer
Zget_eol)�clsrr	�tokrrrrrrr�	from_text,szRP.from_textcCs$|jj|d|�|jj|d|�dS)N)r�to_wirer)r�file�compressrrrrr5sz
RP.to_wirecCs|jj|�|jj|�S)N)r�
to_digestabler)rrrrrr9s
zRP.to_digestablec
Cs�tjj|d||�|�\}}||7}||8}|dkr>tjj�tjj|d||�|�\}	}||krltjj�|dk	r�|j|�}|	j|�}	|||||	�S)Nr)�dns�name�	from_wireZ	exceptionZ	FormErrorr)
rrr	ZwireZcurrentZrdlenrrZcusedrrrrr=s



zRP.from_wirecCs$|jj||�|_|jj||�|_dS)N)rr
r)rrrrrrr
NszRP.choose_relativity)NT)NT)NN)N)N)NT)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrrrr
�
__classcell__rr)r
rrs	


r)Z
dns.exceptionrZ	dns.rdataZdns.nameZrdataZRdatarrrrr�<module>sPKm�\�;[[0rdtypes/ANY/__pycache__/PTR.cpython-36.opt-1.pycnu�[���3

�b�Wk�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�PTRz
PTR recordN)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/PTR.pyrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZNSBaserrrrr�<module>sPKm�\��)	)	7rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-36.opt-1.pycnu�[���3

�b�W�@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecs\eZdZdZddddgZ�fdd�Zdd
d�Zeddd
��Zddd�Z	eddd��Z
�ZS)�
NSEC3PARAMaNSEC3PARAM record

    @ivar algorithm: the hash algorithm number
    @type algorithm: int
    @ivar flags: the flags
    @type flags: int
    @ivar iterations: the number of iterations
    @type iterations: int
    @ivar salt: the salt
    @type salt: string�	algorithm�flags�
iterations�saltcsDtt|�j||�||_||_||_t|t�r:|j�|_	n||_	dS)N)
�superr�__init__rrr�
isinstancer�encoder)�self�rdclass�rdtyperrrr)�	__class__�� /usr/lib/python3.6/NSEC3PARAM.pyr	's
zNSEC3PARAM.__init__NTcKs6|jdkrd}ntj|j�j�}d|j|j|j|fS)N��-z%u %u %u %s)r�binasciiZhexlify�decoderrr)r�origin�
relativize�kwrrrr�to_text1s

zNSEC3PARAM.to_textc
CsV|j�}|j�}|j�}|j�}	|	dkr.d}	ntj|	j��}	|j�|||||||	�S)Nr�)Z	get_uint8Z
get_uint16Z
get_stringrZ	unhexlifyrZget_eol)
�clsr
r�tokrrrrrrrrr�	from_text9szNSEC3PARAM.from_textcCs8t|j�}|jtjd|j|j|j|��|j|j�dS)Nz!BBHB)�lenr�write�struct�packrrr)r�file�compressr�lrrr�to_wireFs
zNSEC3PARAM.to_wirecCsvtjd|||d��\}}}	}
|d7}|d8}||||
�j�}||
7}||
8}|dkrdtjj�||||||	|�S)Nz!BBHB�r)r �unpackZunwrap�dnsZ	exceptionZ	FormError)rr
rZwireZcurrentZrdlenrrrrZslenrrrr�	from_wireLszNSEC3PARAM.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r	r�classmethodrr%r)�
__classcell__rr)rrrs


r)
r rZ
dns.exceptionr(Z	dns.rdataZdns._compatrZrdataZRdatarrrrr�<module>s
PKm�\ޑj��1rdtypes/ANY/__pycache__/ISDN.cpython-36.opt-1.pycnu�[���3

�b�W��@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecsXeZdZdZddgZ�fdd�Zddd	�Zedd
d��Zddd
�Z	eddd��Z
�ZS)�ISDNz�ISDN record

    @ivar address: the ISDN address
    @type address: string
    @ivar subaddress: the ISDN subaddress (or '' if not present)
    @type subaddress: string
    @see: RFC 1183�address�
subaddresscsNtt|�j||�t|t�r(|j�|_n||_t|t�rD|j�|_n||_dS)N)�superr�__init__�
isinstancer�encoderr)�self�rdclass�rdtyperr)�	__class__��/usr/lib/python3.6/ISDN.pyr$s

z
ISDN.__init__NTcKs<|jr&dtjj|j�tjj|j�fSdtjj|j�SdS)Nz	"%s" "%s"z"%s")r�dns�rdataZ	_escapifyr)r
�origin�
relativize�kwrrr�to_text/szISDN.to_textc	CsP|j�}|j�}|j�s,|j|�|j�}n|j|�d}|j�|||||�S)N�)Z
get_string�getZ
is_eol_or_eofZungetZget_eol)	�clsrr�tokrrr�trrrr�	from_text6s


zISDN.from_textcCs\t|j�}|jtjd|��|j|j�t|j�}|dkrX|jtjd|��|j|j�dS)Nz!Br)�lenr�write�struct�packr)r
�file�compressr�lrrr�to_wireCs

zISDN.to_wirec
Cs�||}|d7}|d8}||kr(tjj�||||�j�}||7}||8}|dkr�||}|d7}|d8}||kr|tjj�||||�j�}	nd}	|||||	�S)N�rr)rZ	exceptionZ	FormErrorZunwrap)
rrrZwireZcurrentZrdlenrr"rrrrr�	from_wireNs"zISDN.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrr#r%�
__classcell__rr)r
rrs

r)
rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZdns._compatrrZRdatarrrrr�<module>s
PKm�\������0rdtypes/ANY/__pycache__/X25.cpython-36.opt-1.pycnu�[���3

�b�WG�@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecsVeZdZdZdgZ�fdd�Zddd�Zedd	d
��Zddd�Z	edd
d��Z
�ZS)�X25z\X25 record

    @ivar address: the PSDN address
    @type address: string
    @see: RFC 1183�addresscs2tt|�j||�t|t�r(|j�|_n||_dS)N)�superr�__init__�
isinstancer�encoder)�self�rdclass�rdtyper)�	__class__��/usr/lib/python3.6/X25.pyr"s
zX25.__init__NTcKsdtjj|j�S)Nz"%s")�dns�rdataZ	_escapifyr)r	�origin�
relativize�kwr
r
r�to_text)szX25.to_textcCs|j�}|j�||||�S)N)Z
get_stringZget_eol)�clsr
r�tokrrrr
r
r�	from_text,sz
X25.from_textcCs,t|j�}|jtjd|��|j|j�dS)Nz!B)�lenr�write�struct�pack)r	�file�compressr�lr
r
r�to_wire2s
zX25.to_wirec	CsH||}|d7}|d8}||kr(tjj�||||�j�}||||�S)N�)rZ	exceptionZ	FormErrorZunwrap)	rr
rZwireZcurrentZrdlenrrrr
r
r�	from_wire8sz
X25.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__rr�classmethodrrr!�
__classcell__r
r
)rrrs

r)
rZ
dns.exceptionrZ	dns.rdataZ
dns.tokenizerZdns._compatrrZRdatarr
r
r
r�<module>s
PKm�\#c� ..,rdtypes/ANY/__pycache__/CNAME.cpython-36.pycnu�[���3

�b�W<�@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�CNAMEz�CNAME record

    Note: although CNAME is officially a singleton type, dnspython allows
    non-singleton CNAME rdatasets because such sets have been commonly
    used by BIND and other nameservers for load balancing.N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/CNAME.pyrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZNSBaserrrrr�<module>sPKm�\�>���0rdtypes/ANY/__pycache__/AVC.cpython-36.opt-1.pycnu�[���3

ӓ�W��@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZdS)�AVCzbAVC record

    @see: U{http://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template}N)�__name__�
__module__�__qualname__�__doc__�rr�/usr/lib/python3.6/AVC.pyrsr)Zdns.rdtypes.txtbaseZdnsZrdtypesZtxtbaseZTXTBaserrrrr�<module>sPKm�\?�['��*rdtypes/ANY/__pycache__/URI.cpython-36.pycnu�[���3

�b�WR�@sDddlZddlZddlZddlZddlmZGdd�dejj�Z	dS)�N)�	text_typecsZeZdZdZdddgZ�fdd�Zdd	d
�Zeddd��Zdd
d�Z	eddd��Z
�ZS)�URIz�URI record

    @ivar priority: the priority
    @type priority: int
    @ivar weight: the weight
    @type weight: int
    @ivar target: the target host
    @type target: dns.name.Name object
    @see: draft-faltstrom-uri-13�priority�weight�targetcsVtt|�j||�||_||_t|�dkr6tjjd��t	|t
�rL|j�|_n||_dS)N�zURI target cannot be empty)
�superr�__init__rr�len�dns�	exception�SyntaxError�
isinstancer�encoder)�self�rdclass�rdtyperrr)�	__class__��/usr/lib/python3.6/URI.pyr	's
zURI.__init__NTcKsd|j|j|jj�fS)Nz
%d %d "%s")rrr�decode)r�origin�
relativize�kwrrr�to_text2s
zURI.to_textc	CsR|j�}|j�}|j�j�}|j�p*|j�s8tjjd��|j�||||||j	�S)NzURI target must be a string)
Z
get_uint16�getZunescapeZis_quoted_stringZ
is_identifierrrr
Zget_eol�value)	�clsrr�tokrrrrrrrr�	from_text6sz
URI.from_textcCs,tjd|j|j�}|j|�|j|j�dS)Nz!HH)�struct�packrr�writer)r�file�compressrZtwo_intsrrr�to_wire@s
zURI.to_wirec
Csh|dkrtjjd��tjd|||d��\}}|d7}|d8}||||�}	||7}||||||	�S)N�zURI RR is shorter than 5 octetsz!HH�)rrZ	FormErrorr �unpack)
rrrZwireZcurrentZrdlenrrrrrrr�	from_wireEsz
URI.from_wire)NT)NT)NN)N)�__name__�
__module__�__qualname__�__doc__�	__slots__r	r�classmethodrr%r)�
__classcell__rr)rrrs


	
r)
r Z
dns.exceptionrZ	dns.rdataZdns.nameZdns._compatrZrdataZRdatarrrrr�<module>s
PKm�\�!s2rdtypes/ANY/__pycache__/DNAME.cpython-36.opt-1.pycnu�[���3

�b�W��@s"ddlZGdd�dejjj�ZdS)�Nc@seZdZdZddd�ZdS)�DNAMEzDNAME recordNcCs|jj|�S)N)�target�
to_digestable)�self�origin�r�/usr/lib/python3.6/DNAME.pyrszDNAME.to_digestable)N)�__name__�
__module__�__qualname__�__doc__rrrrrrsr)Zdns.rdtypes.nsbaseZdnsZrdtypesZnsbaseZUncompressedNSrrrrr�<module>sPKm�\Bd����rdtypes/ANY/DNAME.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.nsbase


class DNAME(dns.rdtypes.nsbase.UncompressedNS):

    """DNAME record"""

    def to_digestable(self, origin=None):
        return self.target.to_digestable(origin)
PKm�\�?ddrdtypes/ANY/EUI48.pynu�[���# Copyright (C) 2015 Red Hat, Inc.
# Author: Petr Spacek <pspacek@redhat.com>
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.euibase


class EUI48(dns.rdtypes.euibase.EUIBase):

    """EUI48 record

    @ivar fingerprint: 48-bit Extended Unique Identifier (EUI-48)
    @type fingerprint: string
    @see: rfc7043.txt"""

    byte_len = 6  # 0123456789ab (in hex)
    text_len = byte_len * 3 - 1  # 01-23-45-67-89-ab
PKm�\�C�nnrdtypes/ANY/TXT.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.txtbase


class TXT(dns.rdtypes.txtbase.TXTBase):

    """TXT record"""
PKm�\�x
>
>
rdtypes/ANY/CAA.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.tokenizer


class CAA(dns.rdata.Rdata):

    """CAA (Certification Authority Authorization) record

    @ivar flags: the flags
    @type flags: int
    @ivar tag: the tag
    @type tag: string
    @ivar value: the value
    @type value: string
    @see: RFC 6844"""

    __slots__ = ['flags', 'tag', 'value']

    def __init__(self, rdclass, rdtype, flags, tag, value):
        super(CAA, self).__init__(rdclass, rdtype)
        self.flags = flags
        self.tag = tag
        self.value = value

    def to_text(self, origin=None, relativize=True, **kw):
        return '%u %s "%s"' % (self.flags,
                               dns.rdata._escapify(self.tag),
                               dns.rdata._escapify(self.value))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        flags = tok.get_uint8()
        tag = tok.get_string().encode()
        if len(tag) > 255:
            raise dns.exception.SyntaxError("tag too long")
        if not tag.isalnum():
            raise dns.exception.SyntaxError("tag is not alphanumeric")
        value = tok.get_string().encode()
        return cls(rdclass, rdtype, flags, tag, value)

    def to_wire(self, file, compress=None, origin=None):
        file.write(struct.pack('!B', self.flags))
        l = len(self.tag)
        assert l < 256
        file.write(struct.pack('!B', l))
        file.write(self.tag)
        file.write(self.value)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (flags, l) = struct.unpack('!BB', wire[current: current + 2])
        current += 2
        tag = wire[current: current + l]
        value = wire[current + l:current + rdlen - 2]
        return cls(rdclass, rdtype, flags, tag, value)
PKm�\�EAVkkrdtypes/ANY/PTR.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.nsbase


class PTR(dns.rdtypes.nsbase.NSBase):

    """PTR record"""
PKm�\΍JBiirdtypes/ANY/DS.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.dsbase


class DS(dns.rdtypes.dsbase.DSBase):

    """DS record"""
PKm�\�0��rdtypes/ANY/__init__.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Class ANY (generic) rdata type classes."""

__all__ = [
    'AFSDB',
    'CDNSKEY',
    'CDS',
    'CERT',
    'CNAME',
    'DLV',
    'DNAME',
    'DNSKEY',
    'DS',
    'EUI48',
    'EUI64',
    'GPOS',
    'HINFO',
    'HIP',
    'ISDN',
    'LOC',
    'MX',
    'NS',
    'NSEC',
    'NSEC3',
    'NSEC3PARAM',
    'TLSA',
    'PTR',
    'RP',
    'RRSIG',
    'RT',
    'SOA',
    'SPF',
    'SSHFP',
    'TXT',
    'X25',
]
PKm�\°��rdtypes/ANY/SSHFP.pynu�[���# Copyright (C) 2005-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct
import binascii

import dns.rdata
import dns.rdatatype


class SSHFP(dns.rdata.Rdata):

    """SSHFP record

    @ivar algorithm: the algorithm
    @type algorithm: int
    @ivar fp_type: the digest type
    @type fp_type: int
    @ivar fingerprint: the fingerprint
    @type fingerprint: string
    @see: draft-ietf-secsh-dns-05.txt"""

    __slots__ = ['algorithm', 'fp_type', 'fingerprint']

    def __init__(self, rdclass, rdtype, algorithm, fp_type,
                 fingerprint):
        super(SSHFP, self).__init__(rdclass, rdtype)
        self.algorithm = algorithm
        self.fp_type = fp_type
        self.fingerprint = fingerprint

    def to_text(self, origin=None, relativize=True, **kw):
        return '%d %d %s' % (self.algorithm,
                             self.fp_type,
                             dns.rdata._hexify(self.fingerprint,
                                               chunksize=128))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        algorithm = tok.get_uint8()
        fp_type = tok.get_uint8()
        chunks = []
        while 1:
            t = tok.get().unescape()
            if t.is_eol_or_eof():
                break
            if not t.is_identifier():
                raise dns.exception.SyntaxError
            chunks.append(t.value.encode())
        fingerprint = b''.join(chunks)
        fingerprint = binascii.unhexlify(fingerprint)
        return cls(rdclass, rdtype, algorithm, fp_type, fingerprint)

    def to_wire(self, file, compress=None, origin=None):
        header = struct.pack("!BB", self.algorithm, self.fp_type)
        file.write(header)
        file.write(self.fingerprint)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        header = struct.unpack("!BB", wire[current: current + 2])
        current += 2
        rdlen -= 2
        fingerprint = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, header[0], header[1], fingerprint)
PKm�\�c#���rdtypes/ANY/TLSA.pynu�[���# Copyright (C) 2005-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct
import binascii

import dns.rdata
import dns.rdatatype


class TLSA(dns.rdata.Rdata):

    """TLSA record

    @ivar usage: The certificate usage
    @type usage: int
    @ivar selector: The selector field
    @type selector: int
    @ivar mtype: The 'matching type' field
    @type mtype: int
    @ivar cert: The 'Certificate Association Data' field
    @type cert: string
    @see: RFC 6698"""

    __slots__ = ['usage', 'selector', 'mtype', 'cert']

    def __init__(self, rdclass, rdtype, usage, selector,
                 mtype, cert):
        super(TLSA, self).__init__(rdclass, rdtype)
        self.usage = usage
        self.selector = selector
        self.mtype = mtype
        self.cert = cert

    def to_text(self, origin=None, relativize=True, **kw):
        return '%d %d %d %s' % (self.usage,
                                self.selector,
                                self.mtype,
                                dns.rdata._hexify(self.cert,
                                                  chunksize=128))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        usage = tok.get_uint8()
        selector = tok.get_uint8()
        mtype = tok.get_uint8()
        cert_chunks = []
        while 1:
            t = tok.get().unescape()
            if t.is_eol_or_eof():
                break
            if not t.is_identifier():
                raise dns.exception.SyntaxError
            cert_chunks.append(t.value.encode())
        cert = b''.join(cert_chunks)
        cert = binascii.unhexlify(cert)
        return cls(rdclass, rdtype, usage, selector, mtype, cert)

    def to_wire(self, file, compress=None, origin=None):
        header = struct.pack("!BBB", self.usage, self.selector, self.mtype)
        file.write(header)
        file.write(self.cert)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        header = struct.unpack("!BBB", wire[current: current + 3])
        current += 3
        rdlen -= 3
        cert = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, header[0], header[1], header[2], cert)
PKm�\�� 2�/�/rdtypes/ANY/LOC.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

from __future__ import division

import struct

import dns.exception
import dns.rdata
from dns._compat import long, xrange, round_py2_compat


_pows = tuple(long(10**i) for i in range(0, 11))

# default values are in centimeters
_default_size = 100.0
_default_hprec = 1000000.0
_default_vprec = 1000.0


def _exponent_of(what, desc):
    if what == 0:
        return 0
    exp = None
    for i in xrange(len(_pows)):
        if what // _pows[i] == long(0):
            exp = i - 1
            break
    if exp is None or exp < 0:
        raise dns.exception.SyntaxError("%s value out of bounds" % desc)
    return exp


def _float_to_tuple(what):
    if what < 0:
        sign = -1
        what *= -1
    else:
        sign = 1
    what = round_py2_compat(what * 3600000)
    degrees = int(what // 3600000)
    what -= degrees * 3600000
    minutes = int(what // 60000)
    what -= minutes * 60000
    seconds = int(what // 1000)
    what -= int(seconds * 1000)
    what = int(what)
    return (degrees, minutes, seconds, what, sign)


def _tuple_to_float(what):
    value = float(what[0])
    value += float(what[1]) / 60.0
    value += float(what[2]) / 3600.0
    value += float(what[3]) / 3600000.0
    return float(what[4]) * value


def _encode_size(what, desc):
    what = long(what)
    exponent = _exponent_of(what, desc) & 0xF
    base = what // pow(10, exponent) & 0xF
    return base * 16 + exponent


def _decode_size(what, desc):
    exponent = what & 0x0F
    if exponent > 9:
        raise dns.exception.SyntaxError("bad %s exponent" % desc)
    base = (what & 0xF0) >> 4
    if base > 9:
        raise dns.exception.SyntaxError("bad %s base" % desc)
    return long(base) * pow(10, exponent)


class LOC(dns.rdata.Rdata):

    """LOC record

    @ivar latitude: latitude
    @type latitude: (int, int, int, int, sign) tuple specifying the degrees, minutes,
    seconds, milliseconds, and sign of the coordinate.
    @ivar longitude: longitude
    @type longitude: (int, int, int, int, sign) tuple specifying the degrees,
    minutes, seconds, milliseconds, and sign of the coordinate.
    @ivar altitude: altitude
    @type altitude: float
    @ivar size: size of the sphere
    @type size: float
    @ivar horizontal_precision: horizontal precision
    @type horizontal_precision: float
    @ivar vertical_precision: vertical precision
    @type vertical_precision: float
    @see: RFC 1876"""

    __slots__ = ['latitude', 'longitude', 'altitude', 'size',
                 'horizontal_precision', 'vertical_precision']

    def __init__(self, rdclass, rdtype, latitude, longitude, altitude,
                 size=_default_size, hprec=_default_hprec,
                 vprec=_default_vprec):
        """Initialize a LOC record instance.

        The parameters I{latitude} and I{longitude} may be either a 4-tuple
        of integers specifying (degrees, minutes, seconds, milliseconds),
        or they may be floating point values specifying the number of
        degrees. The other parameters are floats. Size, horizontal precision,
        and vertical precision are specified in centimeters."""

        super(LOC, self).__init__(rdclass, rdtype)
        if isinstance(latitude, int) or isinstance(latitude, long):
            latitude = float(latitude)
        if isinstance(latitude, float):
            latitude = _float_to_tuple(latitude)
        self.latitude = latitude
        if isinstance(longitude, int) or isinstance(longitude, long):
            longitude = float(longitude)
        if isinstance(longitude, float):
            longitude = _float_to_tuple(longitude)
        self.longitude = longitude
        self.altitude = float(altitude)
        self.size = float(size)
        self.horizontal_precision = float(hprec)
        self.vertical_precision = float(vprec)

    def to_text(self, origin=None, relativize=True, **kw):
        if self.latitude[4] > 0:
            lat_hemisphere = 'N'
        else:
            lat_hemisphere = 'S'
        if self.longitude[4] > 0:
            long_hemisphere = 'E'
        else:
            long_hemisphere = 'W'
        text = "%d %d %d.%03d %s %d %d %d.%03d %s %0.2fm" % (
            self.latitude[0], self.latitude[1],
            self.latitude[2], self.latitude[3], lat_hemisphere,
            self.longitude[0], self.longitude[1], self.longitude[2],
            self.longitude[3], long_hemisphere,
            self.altitude / 100.0
        )

        # do not print default values
        if self.size != _default_size or \
            self.horizontal_precision != _default_hprec or \
                self.vertical_precision != _default_vprec:
            text += " %0.2fm %0.2fm %0.2fm" % (
                self.size / 100.0, self.horizontal_precision / 100.0,
                self.vertical_precision / 100.0
            )
        return text

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        latitude = [0, 0, 0, 0, 1]
        longitude = [0, 0, 0, 0, 1]
        size = _default_size
        hprec = _default_hprec
        vprec = _default_vprec

        latitude[0] = tok.get_int()
        t = tok.get_string()
        if t.isdigit():
            latitude[1] = int(t)
            t = tok.get_string()
            if '.' in t:
                (seconds, milliseconds) = t.split('.')
                if not seconds.isdigit():
                    raise dns.exception.SyntaxError(
                        'bad latitude seconds value')
                latitude[2] = int(seconds)
                if latitude[2] >= 60:
                    raise dns.exception.SyntaxError('latitude seconds >= 60')
                l = len(milliseconds)
                if l == 0 or l > 3 or not milliseconds.isdigit():
                    raise dns.exception.SyntaxError(
                        'bad latitude milliseconds value')
                if l == 1:
                    m = 100
                elif l == 2:
                    m = 10
                else:
                    m = 1
                latitude[3] = m * int(milliseconds)
                t = tok.get_string()
            elif t.isdigit():
                latitude[2] = int(t)
                t = tok.get_string()
        if t == 'S':
            latitude[4] = -1
        elif t != 'N':
            raise dns.exception.SyntaxError('bad latitude hemisphere value')

        longitude[0] = tok.get_int()
        t = tok.get_string()
        if t.isdigit():
            longitude[1] = int(t)
            t = tok.get_string()
            if '.' in t:
                (seconds, milliseconds) = t.split('.')
                if not seconds.isdigit():
                    raise dns.exception.SyntaxError(
                        'bad longitude seconds value')
                longitude[2] = int(seconds)
                if longitude[2] >= 60:
                    raise dns.exception.SyntaxError('longitude seconds >= 60')
                l = len(milliseconds)
                if l == 0 or l > 3 or not milliseconds.isdigit():
                    raise dns.exception.SyntaxError(
                        'bad longitude milliseconds value')
                if l == 1:
                    m = 100
                elif l == 2:
                    m = 10
                else:
                    m = 1
                longitude[3] = m * int(milliseconds)
                t = tok.get_string()
            elif t.isdigit():
                longitude[2] = int(t)
                t = tok.get_string()
        if t == 'W':
            longitude[4] = -1
        elif t != 'E':
            raise dns.exception.SyntaxError('bad longitude hemisphere value')

        t = tok.get_string()
        if t[-1] == 'm':
            t = t[0: -1]
        altitude = float(t) * 100.0        # m -> cm

        token = tok.get().unescape()
        if not token.is_eol_or_eof():
            value = token.value
            if value[-1] == 'm':
                value = value[0: -1]
            size = float(value) * 100.0        # m -> cm
            token = tok.get().unescape()
            if not token.is_eol_or_eof():
                value = token.value
                if value[-1] == 'm':
                    value = value[0: -1]
                hprec = float(value) * 100.0        # m -> cm
                token = tok.get().unescape()
                if not token.is_eol_or_eof():
                    value = token.value
                    if value[-1] == 'm':
                        value = value[0: -1]
                    vprec = float(value) * 100.0        # m -> cm
                    tok.get_eol()

        return cls(rdclass, rdtype, latitude, longitude, altitude,
                   size, hprec, vprec)

    def to_wire(self, file, compress=None, origin=None):
        milliseconds = (self.latitude[0] * 3600000 +
                        self.latitude[1] * 60000 +
                        self.latitude[2] * 1000 +
                        self.latitude[3]) * self.latitude[4]
        latitude = long(0x80000000) + milliseconds
        milliseconds = (self.longitude[0] * 3600000 +
                        self.longitude[1] * 60000 +
                        self.longitude[2] * 1000 +
                        self.longitude[3]) * self.longitude[4]
        longitude = long(0x80000000) + milliseconds
        altitude = long(self.altitude) + long(10000000)
        size = _encode_size(self.size, "size")
        hprec = _encode_size(self.horizontal_precision, "horizontal precision")
        vprec = _encode_size(self.vertical_precision, "vertical precision")
        wire = struct.pack("!BBBBIII", 0, size, hprec, vprec, latitude,
                           longitude, altitude)
        file.write(wire)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (version, size, hprec, vprec, latitude, longitude, altitude) = \
            struct.unpack("!BBBBIII", wire[current: current + rdlen])
        if latitude > long(0x80000000):
            latitude = float(latitude - long(0x80000000)) / 3600000
        else:
            latitude = -1 * float(long(0x80000000) - latitude) / 3600000
        if latitude < -90.0 or latitude > 90.0:
            raise dns.exception.FormError("bad latitude")
        if longitude > long(0x80000000):
            longitude = float(longitude - long(0x80000000)) / 3600000
        else:
            longitude = -1 * float(long(0x80000000) - longitude) / 3600000
        if longitude < -180.0 or longitude > 180.0:
            raise dns.exception.FormError("bad longitude")
        altitude = float(altitude) - 10000000.0
        size = _decode_size(size, "size")
        hprec = _decode_size(hprec, "horizontal precision")
        vprec = _decode_size(vprec, "vertical precision")
        return cls(rdclass, rdtype, latitude, longitude, altitude,
                   size, hprec, vprec)

    def _get_float_latitude(self):
        return _tuple_to_float(self.latitude)

    def _set_float_latitude(self, value):
        self.latitude = _float_to_tuple(value)

    float_latitude = property(_get_float_latitude, _set_float_latitude,
                              doc="latitude as a floating point value")

    def _get_float_longitude(self):
        return _tuple_to_float(self.longitude)

    def _set_float_longitude(self, value):
        self.longitude = _float_to_tuple(value)

    float_longitude = property(_get_float_longitude, _set_float_longitude,
                               doc="longitude as a floating point value")
PKm�\�3�,nnrdtypes/ANY/EUI64.pynu�[���# Copyright (C) 2015 Red Hat, Inc.
# Author: Petr Spacek <pspacek@redhat.com>
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.euibase


class EUI64(dns.rdtypes.euibase.EUIBase):

    """EUI64 record

    @ivar fingerprint: 64-bit Extended Unique Identifier (EUI-64)
    @type fingerprint: string
    @see: rfc7043.txt"""

    byte_len = 8  # 0123456789abcdef (in hex)
    text_len = byte_len * 3 - 1  # 01-23-45-67-89-ab-cd-ef
PKm�\���n{{rdtypes/ANY/RT.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.mxbase


class RT(dns.rdtypes.mxbase.UncompressedDowncasingMX):

    """RT record"""
PKm�\�X��rdtypes/ANY/RRSIG.pynu�[���# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import base64
import calendar
import struct
import time

import dns.dnssec
import dns.exception
import dns.rdata
import dns.rdatatype


class BadSigTime(dns.exception.DNSException):

    """Time in DNS SIG or RRSIG resource record cannot be parsed."""


def sigtime_to_posixtime(what):
    if len(what) != 14:
        raise BadSigTime
    year = int(what[0:4])
    month = int(what[4:6])
    day = int(what[6:8])
    hour = int(what[8:10])
    minute = int(what[10:12])
    second = int(what[12:14])
    return calendar.timegm((year, month, day, hour, minute, second,
                            0, 0, 0))


def posixtime_to_sigtime(what):
    return time.strftime('%Y%m%d%H%M%S', time.gmtime(what))


class RRSIG(dns.rdata.Rdata):

    """RRSIG record

    @ivar type_covered: the rdata type this signature covers
    @type type_covered: int
    @ivar algorithm: the algorithm used for the sig
    @type algorithm: int
    @ivar labels: number of labels
    @type labels: int
    @ivar original_ttl: the original TTL
    @type original_ttl: long
    @ivar expiration: signature expiration time
    @type expiration: long
    @ivar inception: signature inception time
    @type inception: long
    @ivar key_tag: the key tag
    @type key_tag: int
    @ivar signer: the signer
    @type signer: dns.name.Name object
    @ivar signature: the signature
    @type signature: string"""

    __slots__ = ['type_covered', 'algorithm', 'labels', 'original_ttl',
                 'expiration', 'inception', 'key_tag', 'signer',
                 'signature']

    def __init__(self, rdclass, rdtype, type_covered, algorithm, labels,
                 original_ttl, expiration, inception, key_tag, signer,
                 signature):
        super(RRSIG, self).__init__(rdclass, rdtype)
        self.type_covered = type_covered
        self.algorithm = algorithm
        self.labels = labels
        self.original_ttl = original_ttl
        self.expiration = expiration
        self.inception = inception
        self.key_tag = key_tag
        self.signer = signer
        self.signature = signature

    def covers(self):
        return self.type_covered

    def to_text(self, origin=None, relativize=True, **kw):
        return '%s %d %d %d %s %s %d %s %s' % (
            dns.rdatatype.to_text(self.type_covered),
            self.algorithm,
            self.labels,
            self.original_ttl,
            posixtime_to_sigtime(self.expiration),
            posixtime_to_sigtime(self.inception),
            self.key_tag,
            self.signer.choose_relativity(origin, relativize),
            dns.rdata._base64ify(self.signature)
        )

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        type_covered = dns.rdatatype.from_text(tok.get_string())
        algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
        labels = tok.get_int()
        original_ttl = tok.get_ttl()
        expiration = sigtime_to_posixtime(tok.get_string())
        inception = sigtime_to_posixtime(tok.get_string())
        key_tag = tok.get_int()
        signer = tok.get_name()
        signer = signer.choose_relativity(origin, relativize)
        chunks = []
        while 1:
            t = tok.get().unescape()
            if t.is_eol_or_eof():
                break
            if not t.is_identifier():
                raise dns.exception.SyntaxError
            chunks.append(t.value.encode())
        b64 = b''.join(chunks)
        signature = base64.b64decode(b64)
        return cls(rdclass, rdtype, type_covered, algorithm, labels,
                   original_ttl, expiration, inception, key_tag, signer,
                   signature)

    def to_wire(self, file, compress=None, origin=None):
        header = struct.pack('!HBBIIIH', self.type_covered,
                             self.algorithm, self.labels,
                             self.original_ttl, self.expiration,
                             self.inception, self.key_tag)
        file.write(header)
        self.signer.to_wire(file, None, origin)
        file.write(self.signature)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        header = struct.unpack('!HBBIIIH', wire[current: current + 18])
        current += 18
        rdlen -= 18
        (signer, cused) = dns.name.from_wire(wire[: current + rdlen], current)
        current += cused
        rdlen -= cused
        if origin is not None:
            signer = signer.relativize(origin)
        signature = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, header[0], header[1], header[2],
                   header[3], header[4], header[5], header[6], signer,
                   signature)

    def choose_relativity(self, origin=None, relativize=True):
        self.signer = self.signer.choose_relativity(origin, relativize)
PKn�\�rdtypes/ANY/DNSKEY.pynu�[���# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.dnskeybase
from dns.rdtypes.dnskeybase import flags_to_text_set, flags_from_text_set


__all__ = ['flags_to_text_set', 'flags_from_text_set']


class DNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase):

    """DNSKEY record"""
PKn�\-��kkrdtypes/ANY/CDS.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.dsbase


class CDS(dns.rdtypes.dsbase.DSBase):

    """CDS record"""
PKn�\���rdtypes/ANY/CDNSKEY.pynu�[���# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.dnskeybase
from dns.rdtypes.dnskeybase import flags_to_text_set, flags_from_text_set


__all__ = ['flags_to_text_set', 'flags_from_text_set']


class CDNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase):

    """CDNSKEY record"""
PKn�\��GRRrdtypes/ANY/NSEC.pynu�[���# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.rdatatype
import dns.name
from dns._compat import xrange


class NSEC(dns.rdata.Rdata):

    """NSEC record

    @ivar next: the next name
    @type next: dns.name.Name object
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples"""

    __slots__ = ['next', 'windows']

    def __init__(self, rdclass, rdtype, next, windows):
        super(NSEC, self).__init__(rdclass, rdtype)
        self.next = next
        self.windows = windows

    def to_text(self, origin=None, relativize=True, **kw):
        next = self.next.choose_relativity(origin, relativize)
        text = ''
        for (window, bitmap) in self.windows:
            bits = []
            for i in xrange(0, len(bitmap)):
                byte = bitmap[i]
                for j in xrange(0, 8):
                    if byte & (0x80 >> j):
                        bits.append(dns.rdatatype.to_text(window * 256 +
                                                          i * 8 + j))
            text += (' ' + ' '.join(bits))
        return '%s%s' % (next, text)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        next = tok.get_name()
        next = next.choose_relativity(origin, relativize)
        rdtypes = []
        while 1:
            token = tok.get().unescape()
            if token.is_eol_or_eof():
                break
            nrdtype = dns.rdatatype.from_text(token.value)
            if nrdtype == 0:
                raise dns.exception.SyntaxError("NSEC with bit 0")
            if nrdtype > 65535:
                raise dns.exception.SyntaxError("NSEC with bit > 65535")
            rdtypes.append(nrdtype)
        rdtypes.sort()
        window = 0
        octets = 0
        prior_rdtype = 0
        bitmap = bytearray(b'\0' * 32)
        windows = []
        for nrdtype in rdtypes:
            if nrdtype == prior_rdtype:
                continue
            prior_rdtype = nrdtype
            new_window = nrdtype // 256
            if new_window != window:
                windows.append((window, bitmap[0:octets]))
                bitmap = bytearray(b'\0' * 32)
                window = new_window
            offset = nrdtype % 256
            byte = offset // 8
            bit = offset % 8
            octets = byte + 1
            bitmap[byte] = bitmap[byte] | (0x80 >> bit)

        windows.append((window, bitmap[0:octets]))
        return cls(rdclass, rdtype, next, windows)

    def to_wire(self, file, compress=None, origin=None):
        self.next.to_wire(file, None, origin)
        for (window, bitmap) in self.windows:
            file.write(struct.pack('!BB', window, len(bitmap)))
            file.write(bitmap)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (next, cused) = dns.name.from_wire(wire[: current + rdlen], current)
        current += cused
        rdlen -= cused
        windows = []
        while rdlen > 0:
            if rdlen < 3:
                raise dns.exception.FormError("NSEC too short")
            window = wire[current]
            octets = wire[current + 1]
            if octets == 0 or octets > 32:
                raise dns.exception.FormError("bad NSEC octets")
            current += 2
            rdlen -= 2
            if rdlen < octets:
                raise dns.exception.FormError("bad NSEC bitmap length")
            bitmap = bytearray(wire[current: current + octets].unwrap())
            current += octets
            rdlen -= octets
            windows.append((window, bitmap))
        if origin is not None:
            next = next.relativize(origin)
        return cls(rdclass, rdtype, next, windows)

    def choose_relativity(self, origin=None, relativize=True):
        self.next = self.next.choose_relativity(origin, relativize)
PKn�\o:Ri
i
rdtypes/ANY/HINFO.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.tokenizer
from dns._compat import text_type


class HINFO(dns.rdata.Rdata):

    """HINFO record

    @ivar cpu: the CPU type
    @type cpu: string
    @ivar os: the OS type
    @type os: string
    @see: RFC 1035"""

    __slots__ = ['cpu', 'os']

    def __init__(self, rdclass, rdtype, cpu, os):
        super(HINFO, self).__init__(rdclass, rdtype)
        if isinstance(cpu, text_type):
            self.cpu = cpu.encode()
        else:
            self.cpu = cpu
        if isinstance(os, text_type):
            self.os = os.encode()
        else:
            self.os = os

    def to_text(self, origin=None, relativize=True, **kw):
        return '"%s" "%s"' % (dns.rdata._escapify(self.cpu),
                              dns.rdata._escapify(self.os))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        cpu = tok.get_string()
        os = tok.get_string()
        tok.get_eol()
        return cls(rdclass, rdtype, cpu, os)

    def to_wire(self, file, compress=None, origin=None):
        l = len(self.cpu)
        assert l < 256
        file.write(struct.pack('!B', l))
        file.write(self.cpu)
        l = len(self.os)
        assert l < 256
        file.write(struct.pack('!B', l))
        file.write(self.os)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        l = wire[current]
        current += 1
        rdlen -= 1
        if l > rdlen:
            raise dns.exception.FormError
        cpu = wire[current:current + l].unwrap()
        current += l
        rdlen -= l
        l = wire[current]
        current += 1
        rdlen -= 1
        if l != rdlen:
            raise dns.exception.FormError
        os = wire[current: current + l].unwrap()
        return cls(rdclass, rdtype, cpu, os)
PKn�\������rdtypes/ANY/RP.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.exception
import dns.rdata
import dns.name


class RP(dns.rdata.Rdata):

    """RP record

    @ivar mbox: The responsible person's mailbox
    @type mbox: dns.name.Name object
    @ivar txt: The owner name of a node with TXT records, or the root name
    if no TXT records are associated with this RP.
    @type txt: dns.name.Name object
    @see: RFC 1183"""

    __slots__ = ['mbox', 'txt']

    def __init__(self, rdclass, rdtype, mbox, txt):
        super(RP, self).__init__(rdclass, rdtype)
        self.mbox = mbox
        self.txt = txt

    def to_text(self, origin=None, relativize=True, **kw):
        mbox = self.mbox.choose_relativity(origin, relativize)
        txt = self.txt.choose_relativity(origin, relativize)
        return "%s %s" % (str(mbox), str(txt))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        mbox = tok.get_name()
        txt = tok.get_name()
        mbox = mbox.choose_relativity(origin, relativize)
        txt = txt.choose_relativity(origin, relativize)
        tok.get_eol()
        return cls(rdclass, rdtype, mbox, txt)

    def to_wire(self, file, compress=None, origin=None):
        self.mbox.to_wire(file, None, origin)
        self.txt.to_wire(file, None, origin)

    def to_digestable(self, origin=None):
        return self.mbox.to_digestable(origin) + \
            self.txt.to_digestable(origin)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (mbox, cused) = dns.name.from_wire(wire[: current + rdlen],
                                           current)
        current += cused
        rdlen -= cused
        if rdlen <= 0:
            raise dns.exception.FormError
        (txt, cused) = dns.name.from_wire(wire[: current + rdlen],
                                          current)
        if cused != rdlen:
            raise dns.exception.FormError
        if origin is not None:
            mbox = mbox.relativize(origin)
            txt = txt.relativize(origin)
        return cls(rdclass, rdtype, mbox, txt)

    def choose_relativity(self, origin=None, relativize=True):
        self.mbox = self.mbox.choose_relativity(origin, relativize)
        self.txt = self.txt.choose_relativity(origin, relativize)
PKn�\�o(
<<rdtypes/ANY/CNAME.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.nsbase


class CNAME(dns.rdtypes.nsbase.NSBase):

    """CNAME record

    Note: although CNAME is officially a singleton type, dnspython allows
    non-singleton CNAME rdatasets because such sets have been commonly
    used by BIND and other nameservers for load balancing."""
PKn�\5_W5��rdtypes/ANY/AVC.pynu�[���# Copyright (C) 2016 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.txtbase


class AVC(dns.rdtypes.txtbase.TXTBase):

    """AVC record

    @see: U{http://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template}"""
PKn�\U�&��rdtypes/ANY/SPF.pynu�[���# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.txtbase


class SPF(dns.rdtypes.txtbase.TXTBase):

    """SPF record

    @see: RFC 4408"""
PKn�\Q�x���rdtypes/ANY/ISDN.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.tokenizer
from dns._compat import text_type


class ISDN(dns.rdata.Rdata):

    """ISDN record

    @ivar address: the ISDN address
    @type address: string
    @ivar subaddress: the ISDN subaddress (or '' if not present)
    @type subaddress: string
    @see: RFC 1183"""

    __slots__ = ['address', 'subaddress']

    def __init__(self, rdclass, rdtype, address, subaddress):
        super(ISDN, self).__init__(rdclass, rdtype)
        if isinstance(address, text_type):
            self.address = address.encode()
        else:
            self.address = address
        if isinstance(address, text_type):
            self.subaddress = subaddress.encode()
        else:
            self.subaddress = subaddress

    def to_text(self, origin=None, relativize=True, **kw):
        if self.subaddress:
            return '"%s" "%s"' % (dns.rdata._escapify(self.address),
                                  dns.rdata._escapify(self.subaddress))
        else:
            return '"%s"' % dns.rdata._escapify(self.address)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        address = tok.get_string()
        t = tok.get()
        if not t.is_eol_or_eof():
            tok.unget(t)
            subaddress = tok.get_string()
        else:
            tok.unget(t)
            subaddress = ''
        tok.get_eol()
        return cls(rdclass, rdtype, address, subaddress)

    def to_wire(self, file, compress=None, origin=None):
        l = len(self.address)
        assert l < 256
        file.write(struct.pack('!B', l))
        file.write(self.address)
        l = len(self.subaddress)
        if l > 0:
            assert l < 256
            file.write(struct.pack('!B', l))
            file.write(self.subaddress)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        l = wire[current]
        current += 1
        rdlen -= 1
        if l > rdlen:
            raise dns.exception.FormError
        address = wire[current: current + l].unwrap()
        current += l
        rdlen -= l
        if rdlen > 0:
            l = wire[current]
            current += 1
            rdlen -= 1
            if l != rdlen:
                raise dns.exception.FormError
            subaddress = wire[current: current + l].unwrap()
        else:
            subaddress = ''
        return cls(rdclass, rdtype, address, subaddress)
PKn�\�[$$$rdtypes/ANY/CSYNC.pynu�[���# Copyright (C) 2004-2007, 2009-2011, 2016 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.rdatatype
import dns.name
from dns._compat import xrange

class CSYNC(dns.rdata.Rdata):

    """CSYNC record

    @ivar serial: the SOA serial number
    @type serial: int
    @ivar flags: the CSYNC flags
    @type flags: int
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples"""

    __slots__ = ['serial', 'flags', 'windows']

    def __init__(self, rdclass, rdtype, serial, flags, windows):
        super(CSYNC, self).__init__(rdclass, rdtype)
        self.serial = serial
        self.flags = flags
        self.windows = windows

    def to_text(self, origin=None, relativize=True, **kw):
        text = ''
        for (window, bitmap) in self.windows:
            bits = []
            for i in xrange(0, len(bitmap)):
                byte = bitmap[i]
                for j in xrange(0, 8):
                    if byte & (0x80 >> j):
                        bits.append(dns.rdatatype.to_text(window * 256 +
                                                          i * 8 + j))
            text += (' ' + ' '.join(bits))
        return '%d %d%s' % (self.serial, self.flags, text)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        serial = tok.get_uint32()
        flags = tok.get_uint16()
        rdtypes = []
        while 1:
            token = tok.get().unescape()
            if token.is_eol_or_eof():
                break
            nrdtype = dns.rdatatype.from_text(token.value)
            if nrdtype == 0:
                raise dns.exception.SyntaxError("CSYNC with bit 0")
            if nrdtype > 65535:
                raise dns.exception.SyntaxError("CSYNC with bit > 65535")
            rdtypes.append(nrdtype)
        rdtypes.sort()
        window = 0
        octets = 0
        prior_rdtype = 0
        bitmap = bytearray(b'\0' * 32)
        windows = []
        for nrdtype in rdtypes:
            if nrdtype == prior_rdtype:
                continue
            prior_rdtype = nrdtype
            new_window = nrdtype // 256
            if new_window != window:
                windows.append((window, bitmap[0:octets]))
                bitmap = bytearray(b'\0' * 32)
                window = new_window
            offset = nrdtype % 256
            byte = offset // 8
            bit = offset % 8
            octets = byte + 1
            bitmap[byte] = bitmap[byte] | (0x80 >> bit)

        windows.append((window, bitmap[0:octets]))
        return cls(rdclass, rdtype, serial, flags, windows)

    def to_wire(self, file, compress=None, origin=None):
        file.write(struct.pack('!IH', self.serial, self.flags))
        for (window, bitmap) in self.windows:
            file.write(struct.pack('!BB', window, len(bitmap)))
            file.write(bitmap)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        if rdlen < 6:
            raise dns.exception.FormError("CSYNC too short")
        (serial, flags) = struct.unpack("!IH", wire[current: current + 6])
        current += 6
        rdlen -= 6
        windows = []
        while rdlen > 0:
            if rdlen < 3:
                raise dns.exception.FormError("CSYNC too short")
            window = wire[current]
            octets = wire[current + 1]
            if octets == 0 or octets > 32:
                raise dns.exception.FormError("bad CSYNC octets")
            current += 2
            rdlen -= 2
            if rdlen < octets:
                raise dns.exception.FormError("bad CSYNC bitmap length")
            bitmap = bytearray(wire[current: current + octets].unwrap())
            current += octets
            rdlen -= octets
            windows.append((window, bitmap))
        return cls(rdclass, rdtype, serial, flags, windows)
PKn�\��,�iirdtypes/ANY/MX.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.mxbase


class MX(dns.rdtypes.mxbase.MXBase):

    """MX record"""
PKn�\k�9�rdtypes/ANY/NSEC3PARAM.pynu�[���# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct
import binascii

import dns.exception
import dns.rdata
from dns._compat import text_type


class NSEC3PARAM(dns.rdata.Rdata):

    """NSEC3PARAM record

    @ivar algorithm: the hash algorithm number
    @type algorithm: int
    @ivar flags: the flags
    @type flags: int
    @ivar iterations: the number of iterations
    @type iterations: int
    @ivar salt: the salt
    @type salt: string"""

    __slots__ = ['algorithm', 'flags', 'iterations', 'salt']

    def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt):
        super(NSEC3PARAM, self).__init__(rdclass, rdtype)
        self.algorithm = algorithm
        self.flags = flags
        self.iterations = iterations
        if isinstance(salt, text_type):
            self.salt = salt.encode()
        else:
            self.salt = salt

    def to_text(self, origin=None, relativize=True, **kw):
        if self.salt == b'':
            salt = '-'
        else:
            salt = binascii.hexlify(self.salt).decode()
        return '%u %u %u %s' % (self.algorithm, self.flags, self.iterations,
                                salt)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        algorithm = tok.get_uint8()
        flags = tok.get_uint8()
        iterations = tok.get_uint16()
        salt = tok.get_string()
        if salt == '-':
            salt = ''
        else:
            salt = binascii.unhexlify(salt.encode())
        tok.get_eol()
        return cls(rdclass, rdtype, algorithm, flags, iterations, salt)

    def to_wire(self, file, compress=None, origin=None):
        l = len(self.salt)
        file.write(struct.pack("!BBHB", self.algorithm, self.flags,
                               self.iterations, l))
        file.write(self.salt)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (algorithm, flags, iterations, slen) = \
             struct.unpack('!BBHB',
                           wire[current: current + 5])
        current += 5
        rdlen -= 5
        salt = wire[current: current + slen].unwrap()
        current += slen
        rdlen -= slen
        if rdlen != 0:
            raise dns.exception.FormError
        return cls(rdclass, rdtype, algorithm, flags, iterations, salt)
PKn�\�&�͡�rdtypes/ANY/NSEC3.pynu�[���# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import base64
import binascii
import string
import struct

import dns.exception
import dns.rdata
import dns.rdatatype
from dns._compat import xrange, text_type

try:
    b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV',
                                         'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
    b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
                                         '0123456789ABCDEFGHIJKLMNOPQRSTUV')
except AttributeError:
    b32_hex_to_normal = bytes.maketrans(b'0123456789ABCDEFGHIJKLMNOPQRSTUV',
                                        b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
    b32_normal_to_hex = bytes.maketrans(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
                                        b'0123456789ABCDEFGHIJKLMNOPQRSTUV')

# hash algorithm constants
SHA1 = 1

# flag constants
OPTOUT = 1


class NSEC3(dns.rdata.Rdata):

    """NSEC3 record

    @ivar algorithm: the hash algorithm number
    @type algorithm: int
    @ivar flags: the flags
    @type flags: int
    @ivar iterations: the number of iterations
    @type iterations: int
    @ivar salt: the salt
    @type salt: string
    @ivar next: the next name hash
    @type next: string
    @ivar windows: the windowed bitmap list
    @type windows: list of (window number, string) tuples"""

    __slots__ = ['algorithm', 'flags', 'iterations', 'salt', 'next', 'windows']

    def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt,
                 next, windows):
        super(NSEC3, self).__init__(rdclass, rdtype)
        self.algorithm = algorithm
        self.flags = flags
        self.iterations = iterations
        if isinstance(salt, text_type):
            self.salt = salt.encode()
        else:
            self.salt = salt
        self.next = next
        self.windows = windows

    def to_text(self, origin=None, relativize=True, **kw):
        next = base64.b32encode(self.next).translate(
            b32_normal_to_hex).lower().decode()
        if self.salt == b'':
            salt = '-'
        else:
            salt = binascii.hexlify(self.salt).decode()
        text = u''
        for (window, bitmap) in self.windows:
            bits = []
            for i in xrange(0, len(bitmap)):
                byte = bitmap[i]
                for j in xrange(0, 8):
                    if byte & (0x80 >> j):
                        bits.append(dns.rdatatype.to_text(window * 256 +
                                                          i * 8 + j))
            text += (u' ' + u' '.join(bits))
        return u'%u %u %u %s %s%s' % (self.algorithm, self.flags,
                                      self.iterations, salt, next, text)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        algorithm = tok.get_uint8()
        flags = tok.get_uint8()
        iterations = tok.get_uint16()
        salt = tok.get_string()
        if salt == u'-':
            salt = b''
        else:
            salt = binascii.unhexlify(salt.encode('ascii'))
        next = tok.get_string().encode(
            'ascii').upper().translate(b32_hex_to_normal)
        next = base64.b32decode(next)
        rdtypes = []
        while 1:
            token = tok.get().unescape()
            if token.is_eol_or_eof():
                break
            nrdtype = dns.rdatatype.from_text(token.value)
            if nrdtype == 0:
                raise dns.exception.SyntaxError("NSEC3 with bit 0")
            if nrdtype > 65535:
                raise dns.exception.SyntaxError("NSEC3 with bit > 65535")
            rdtypes.append(nrdtype)
        rdtypes.sort()
        window = 0
        octets = 0
        prior_rdtype = 0
        bitmap = bytearray(b'\0' * 32)
        windows = []
        for nrdtype in rdtypes:
            if nrdtype == prior_rdtype:
                continue
            prior_rdtype = nrdtype
            new_window = nrdtype // 256
            if new_window != window:
                if octets != 0:
                    windows.append((window, ''.join(bitmap[0:octets])))
                bitmap = bytearray(b'\0' * 32)
                window = new_window
            offset = nrdtype % 256
            byte = offset // 8
            bit = offset % 8
            octets = byte + 1
            bitmap[byte] = bitmap[byte] | (0x80 >> bit)
        if octets != 0:
            windows.append((window, bitmap[0:octets]))
        return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next,
                   windows)

    def to_wire(self, file, compress=None, origin=None):
        l = len(self.salt)
        file.write(struct.pack("!BBHB", self.algorithm, self.flags,
                               self.iterations, l))
        file.write(self.salt)
        l = len(self.next)
        file.write(struct.pack("!B", l))
        file.write(self.next)
        for (window, bitmap) in self.windows:
            file.write(struct.pack("!BB", window, len(bitmap)))
            file.write(bitmap)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (algorithm, flags, iterations, slen) = \
            struct.unpack('!BBHB', wire[current: current + 5])

        current += 5
        rdlen -= 5
        salt = wire[current: current + slen].unwrap()
        current += slen
        rdlen -= slen
        nlen = wire[current]
        current += 1
        rdlen -= 1
        next = wire[current: current + nlen].unwrap()
        current += nlen
        rdlen -= nlen
        windows = []
        while rdlen > 0:
            if rdlen < 3:
                raise dns.exception.FormError("NSEC3 too short")
            window = wire[current]
            octets = wire[current + 1]
            if octets == 0 or octets > 32:
                raise dns.exception.FormError("bad NSEC3 octets")
            current += 2
            rdlen -= 2
            if rdlen < octets:
                raise dns.exception.FormError("bad NSEC3 bitmap length")
            bitmap = bytearray(wire[current: current + octets].unwrap())
            current += octets
            rdlen -= octets
            windows.append((window, bitmap))
        return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next,
                   windows)
PKn�\`0��oordtypes/ANY/CERT.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct
import base64

import dns.exception
import dns.dnssec
import dns.rdata
import dns.tokenizer

_ctype_by_value = {
    1: 'PKIX',
    2: 'SPKI',
    3: 'PGP',
    253: 'URI',
    254: 'OID',
}

_ctype_by_name = {
    'PKIX': 1,
    'SPKI': 2,
    'PGP': 3,
    'URI': 253,
    'OID': 254,
}


def _ctype_from_text(what):
    v = _ctype_by_name.get(what)
    if v is not None:
        return v
    return int(what)


def _ctype_to_text(what):
    v = _ctype_by_value.get(what)
    if v is not None:
        return v
    return str(what)


class CERT(dns.rdata.Rdata):

    """CERT record

    @ivar certificate_type: certificate type
    @type certificate_type: int
    @ivar key_tag: key tag
    @type key_tag: int
    @ivar algorithm: algorithm
    @type algorithm: int
    @ivar certificate: the certificate or CRL
    @type certificate: string
    @see: RFC 2538"""

    __slots__ = ['certificate_type', 'key_tag', 'algorithm', 'certificate']

    def __init__(self, rdclass, rdtype, certificate_type, key_tag, algorithm,
                 certificate):
        super(CERT, self).__init__(rdclass, rdtype)
        self.certificate_type = certificate_type
        self.key_tag = key_tag
        self.algorithm = algorithm
        self.certificate = certificate

    def to_text(self, origin=None, relativize=True, **kw):
        certificate_type = _ctype_to_text(self.certificate_type)
        return "%s %d %s %s" % (certificate_type, self.key_tag,
                                dns.dnssec.algorithm_to_text(self.algorithm),
                                dns.rdata._base64ify(self.certificate))

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        certificate_type = _ctype_from_text(tok.get_string())
        key_tag = tok.get_uint16()
        algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
        if algorithm < 0 or algorithm > 255:
            raise dns.exception.SyntaxError("bad algorithm type")
        chunks = []
        while 1:
            t = tok.get().unescape()
            if t.is_eol_or_eof():
                break
            if not t.is_identifier():
                raise dns.exception.SyntaxError
            chunks.append(t.value.encode())
        b64 = b''.join(chunks)
        certificate = base64.b64decode(b64)
        return cls(rdclass, rdtype, certificate_type, key_tag,
                   algorithm, certificate)

    def to_wire(self, file, compress=None, origin=None):
        prefix = struct.pack("!HHB", self.certificate_type, self.key_tag,
                             self.algorithm)
        file.write(prefix)
        file.write(self.certificate)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        prefix = wire[current: current + 5].unwrap()
        current += 5
        rdlen -= 5
        if rdlen < 0:
            raise dns.exception.FormError
        (certificate_type, key_tag, algorithm) = struct.unpack("!HHB", prefix)
        certificate = wire[current: current + rdlen].unwrap()
        return cls(rdclass, rdtype, certificate_type, key_tag, algorithm,
                   certificate)
PKn�\��``rdtypes/ANY/DLV.pynu�[���# Copyright (C) 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.dsbase


class DLV(dns.rdtypes.dsbase.DSBase):

    """DLV record"""
PKn�\��7�RRrdtypes/ANY/URI.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
# Copyright (C) 2015 Red Hat, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.name
from dns._compat import text_type


class URI(dns.rdata.Rdata):

    """URI record

    @ivar priority: the priority
    @type priority: int
    @ivar weight: the weight
    @type weight: int
    @ivar target: the target host
    @type target: dns.name.Name object
    @see: draft-faltstrom-uri-13"""

    __slots__ = ['priority', 'weight', 'target']

    def __init__(self, rdclass, rdtype, priority, weight, target):
        super(URI, self).__init__(rdclass, rdtype)
        self.priority = priority
        self.weight = weight
        if len(target) < 1:
            raise dns.exception.SyntaxError("URI target cannot be empty")
        if isinstance(target, text_type):
            self.target = target.encode()
        else:
            self.target = target

    def to_text(self, origin=None, relativize=True, **kw):
        return '%d %d "%s"' % (self.priority, self.weight,
                               self.target.decode())

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        priority = tok.get_uint16()
        weight = tok.get_uint16()
        target = tok.get().unescape()
        if not (target.is_quoted_string() or target.is_identifier()):
            raise dns.exception.SyntaxError("URI target must be a string")
        tok.get_eol()
        return cls(rdclass, rdtype, priority, weight, target.value)

    def to_wire(self, file, compress=None, origin=None):
        two_ints = struct.pack("!HH", self.priority, self.weight)
        file.write(two_ints)
        file.write(self.target)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        if rdlen < 5:
            raise dns.exception.FormError('URI RR is shorter than 5 octets')

        (priority, weight) = struct.unpack('!HH', wire[current: current + 4])
        current += 4
        rdlen -= 4
        target = wire[current: current + rdlen]
        current += rdlen

        return cls(rdclass, rdtype, priority, weight, target)
PKn�\��ig��rdtypes/ANY/SOA.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct

import dns.exception
import dns.rdata
import dns.name


class SOA(dns.rdata.Rdata):

    """SOA record

    @ivar mname: the SOA MNAME (master name) field
    @type mname: dns.name.Name object
    @ivar rname: the SOA RNAME (responsible name) field
    @type rname: dns.name.Name object
    @ivar serial: The zone's serial number
    @type serial: int
    @ivar refresh: The zone's refresh value (in seconds)
    @type refresh: int
    @ivar retry: The zone's retry value (in seconds)
    @type retry: int
    @ivar expire: The zone's expiration value (in seconds)
    @type expire: int
    @ivar minimum: The zone's negative caching time (in seconds, called
    "minimum" for historical reasons)
    @type minimum: int
    @see: RFC 1035"""

    __slots__ = ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire',
                 'minimum']

    def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry,
                 expire, minimum):
        super(SOA, self).__init__(rdclass, rdtype)
        self.mname = mname
        self.rname = rname
        self.serial = serial
        self.refresh = refresh
        self.retry = retry
        self.expire = expire
        self.minimum = minimum

    def to_text(self, origin=None, relativize=True, **kw):
        mname = self.mname.choose_relativity(origin, relativize)
        rname = self.rname.choose_relativity(origin, relativize)
        return '%s %s %d %d %d %d %d' % (
            mname, rname, self.serial, self.refresh, self.retry,
            self.expire, self.minimum)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        mname = tok.get_name()
        rname = tok.get_name()
        mname = mname.choose_relativity(origin, relativize)
        rname = rname.choose_relativity(origin, relativize)
        serial = tok.get_uint32()
        refresh = tok.get_ttl()
        retry = tok.get_ttl()
        expire = tok.get_ttl()
        minimum = tok.get_ttl()
        tok.get_eol()
        return cls(rdclass, rdtype, mname, rname, serial, refresh, retry,
                   expire, minimum)

    def to_wire(self, file, compress=None, origin=None):
        self.mname.to_wire(file, compress, origin)
        self.rname.to_wire(file, compress, origin)
        five_ints = struct.pack('!IIIII', self.serial, self.refresh,
                                self.retry, self.expire, self.minimum)
        file.write(five_ints)

    def to_digestable(self, origin=None):
        return self.mname.to_digestable(origin) + \
            self.rname.to_digestable(origin) + \
            struct.pack('!IIIII', self.serial, self.refresh,
                        self.retry, self.expire, self.minimum)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (mname, cused) = dns.name.from_wire(wire[: current + rdlen], current)
        current += cused
        rdlen -= cused
        (rname, cused) = dns.name.from_wire(wire[: current + rdlen], current)
        current += cused
        rdlen -= cused
        if rdlen != 20:
            raise dns.exception.FormError
        five_ints = struct.unpack('!IIIII',
                                  wire[current: current + rdlen])
        if origin is not None:
            mname = mname.relativize(origin)
            rname = rname.relativize(origin)
        return cls(rdclass, rdtype, mname, rname,
                   five_ints[0], five_ints[1], five_ints[2], five_ints[3],
                   five_ints[4])

    def choose_relativity(self, origin=None, relativize=True):
        self.mname = self.mname.choose_relativity(origin, relativize)
        self.rname = self.rname.choose_relativity(origin, relativize)
PKn�\�[Reiirdtypes/ANY/NS.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.nsbase


class NS(dns.rdtypes.nsbase.NSBase):

    """NS record"""
PKn�\Z��S00rdtypes/ANY/HIP.pynu�[���# Copyright (C) 2010, 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import struct
import base64
import binascii

import dns.exception
import dns.rdata
import dns.rdatatype


class HIP(dns.rdata.Rdata):

    """HIP record

    @ivar hit: the host identity tag
    @type hit: string
    @ivar algorithm: the public key cryptographic algorithm
    @type algorithm: int
    @ivar key: the public key
    @type key: string
    @ivar servers: the rendezvous servers
    @type servers: list of dns.name.Name objects
    @see: RFC 5205"""

    __slots__ = ['hit', 'algorithm', 'key', 'servers']

    def __init__(self, rdclass, rdtype, hit, algorithm, key, servers):
        super(HIP, self).__init__(rdclass, rdtype)
        self.hit = hit
        self.algorithm = algorithm
        self.key = key
        self.servers = servers

    def to_text(self, origin=None, relativize=True, **kw):
        hit = binascii.hexlify(self.hit).decode()
        key = base64.b64encode(self.key).replace(b'\n', b'').decode()
        text = u''
        servers = []
        for server in self.servers:
            servers.append(server.choose_relativity(origin, relativize))
        if len(servers) > 0:
            text += (u' ' + u' '.join((x.to_unicode() for x in servers)))
        return u'%u %s %s%s' % (self.algorithm, hit, key, text)

    @classmethod
    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
        algorithm = tok.get_uint8()
        hit = binascii.unhexlify(tok.get_string().encode())
        if len(hit) > 255:
            raise dns.exception.SyntaxError("HIT too long")
        key = base64.b64decode(tok.get_string().encode())
        servers = []
        while 1:
            token = tok.get()
            if token.is_eol_or_eof():
                break
            server = dns.name.from_text(token.value, origin)
            server.choose_relativity(origin, relativize)
            servers.append(server)
        return cls(rdclass, rdtype, hit, algorithm, key, servers)

    def to_wire(self, file, compress=None, origin=None):
        lh = len(self.hit)
        lk = len(self.key)
        file.write(struct.pack("!BBH", lh, self.algorithm, lk))
        file.write(self.hit)
        file.write(self.key)
        for server in self.servers:
            server.to_wire(file, None, origin)

    @classmethod
    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
        (lh, algorithm, lk) = struct.unpack('!BBH',
                                            wire[current: current + 4])
        current += 4
        rdlen -= 4
        hit = wire[current: current + lh].unwrap()
        current += lh
        rdlen -= lh
        key = wire[current: current + lk].unwrap()
        current += lk
        rdlen -= lk
        servers = []
        while rdlen > 0:
            (server, cused) = dns.name.from_wire(wire[: current + rdlen],
                                                 current)
            current += cused
            rdlen -= cused
            if origin is not None:
                server = server.relativize(origin)
            servers.append(server)
        return cls(rdclass, rdtype, hit, algorithm, key, servers)

    def choose_relativity(self, origin=None, relativize=True):
        servers = []
        for server in self.servers:
            server = server.choose_relativity(origin, relativize)
            servers.append(server)
        self.servers = servers
PKn�\ϝs88rdtypes/ANY/AFSDB.pynu�[���# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import dns.rdtypes.mxbase


class AFSDB(dns.rdtypes.mxbase.UncompressedDowncasingMX):

    """AFSDB record

    @ivar subtype: the subtype value
    @type subtype: int
    @ivar hostname: the hostname name
    @type hostname: dns.name.Name object"""

    # Use the property mechanism to make "subtype" an alias for the
    # "preference" attribute, and "hostname" an alias for the "exchange"
    # attribute.
    #
    # This lets us inherit the UncompressedMX implementation but lets
    # the caller use appropriate attribute names for the rdata type.
    #
    # We probably lose some performance vs. a cut-and-paste
    # implementation, but this way we don't copy code, and that's
    # good.

    def get_subtype(self):
        return self.preference

    def set_subtype(self, subtype):
        self.preference = subtype

    subtype = property(get_subtype, set_subtype)

    def get_hostname(self):
        return self.exchange

    def set_hostname(self, hostname):
        self.exchange = hostname

    hostname = property(get_hostname, set_hostname)
PKn�\��%�.�.renderer.pynu�[���# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""Help for building DNS wire format messages"""

from io import BytesIO
import struct
import random
import time

import dns.exception
import dns.tsig
from ._compat import long


QUESTION = 0
ANSWER = 1
AUTHORITY = 2
ADDITIONAL = 3


class Renderer(object):

    """Helper class for building DNS wire-format messages.

    Most applications can use the higher-level L{dns.message.Message}
    class and its to_wire() method to generate wire-format messages.
    This class is for those applications which need finer control
    over the generation of messages.

    Typical use::

        r = dns.renderer.Renderer(id=1, flags=0x80, max_size=512)
        r.add_question(qname, qtype, qclass)
        r.add_rrset(dns.renderer.ANSWER, rrset_1)
        r.add_rrset(dns.renderer.ANSWER, rrset_2)
        r.add_rrset(dns.renderer.AUTHORITY, ns_rrset)
        r.add_edns(0, 0, 4096)
        r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_1)
        r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_2)
        r.write_header()
        r.add_tsig(keyname, secret, 300, 1, 0, '', request_mac)
        wire = r.get_wire()

    @ivar output: where rendering is written
    @type output: BytesIO object
    @ivar id: the message id
    @type id: int
    @ivar flags: the message flags
    @type flags: int
    @ivar max_size: the maximum size of the message
    @type max_size: int
    @ivar origin: the origin to use when rendering relative names
    @type origin: dns.name.Name object
    @ivar compress: the compression table
    @type compress: dict
    @ivar section: the section currently being rendered
    @type section: int (dns.renderer.QUESTION, dns.renderer.ANSWER,
    dns.renderer.AUTHORITY, or dns.renderer.ADDITIONAL)
    @ivar counts: list of the number of RRs in each section
    @type counts: int list of length 4
    @ivar mac: the MAC of the rendered message (if TSIG was used)
    @type mac: string
    """

    def __init__(self, id=None, flags=0, max_size=65535, origin=None):
        """Initialize a new renderer.

        @param id: the message id
        @type id: int
        @param flags: the DNS message flags
        @type flags: int
        @param max_size: the maximum message size; the default is 65535.
        If rendering results in a message greater than I{max_size},
        then L{dns.exception.TooBig} will be raised.
        @type max_size: int
        @param origin: the origin to use when rendering relative names
        @type origin: dns.name.Name or None.
        """

        self.output = BytesIO()
        if id is None:
            self.id = random.randint(0, 65535)
        else:
            self.id = id
        self.flags = flags
        self.max_size = max_size
        self.origin = origin
        self.compress = {}
        self.section = QUESTION
        self.counts = [0, 0, 0, 0]
        self.output.write(b'\x00' * 12)
        self.mac = ''

    def _rollback(self, where):
        """Truncate the output buffer at offset I{where}, and remove any
        compression table entries that pointed beyond the truncation
        point.

        @param where: the offset
        @type where: int
        """

        self.output.seek(where)
        self.output.truncate()
        keys_to_delete = []
        for k, v in self.compress.items():
            if v >= where:
                keys_to_delete.append(k)
        for k in keys_to_delete:
            del self.compress[k]

    def _set_section(self, section):
        """Set the renderer's current section.

        Sections must be rendered order: QUESTION, ANSWER, AUTHORITY,
        ADDITIONAL.  Sections may be empty.

        @param section: the section
        @type section: int
        @raises dns.exception.FormError: an attempt was made to set
        a section value less than the current section.
        """

        if self.section != section:
            if self.section > section:
                raise dns.exception.FormError
            self.section = section

    def add_question(self, qname, rdtype, rdclass=dns.rdataclass.IN):
        """Add a question to the message.

        @param qname: the question name
        @type qname: dns.name.Name
        @param rdtype: the question rdata type
        @type rdtype: int
        @param rdclass: the question rdata class
        @type rdclass: int
        """

        self._set_section(QUESTION)
        before = self.output.tell()
        qname.to_wire(self.output, self.compress, self.origin)
        self.output.write(struct.pack("!HH", rdtype, rdclass))
        after = self.output.tell()
        if after >= self.max_size:
            self._rollback(before)
            raise dns.exception.TooBig
        self.counts[QUESTION] += 1

    def add_rrset(self, section, rrset, **kw):
        """Add the rrset to the specified section.

        Any keyword arguments are passed on to the rdataset's to_wire()
        routine.

        @param section: the section
        @type section: int
        @param rrset: the rrset
        @type rrset: dns.rrset.RRset object
        """

        self._set_section(section)
        before = self.output.tell()
        n = rrset.to_wire(self.output, self.compress, self.origin, **kw)
        after = self.output.tell()
        if after >= self.max_size:
            self._rollback(before)
            raise dns.exception.TooBig
        self.counts[section] += n

    def add_rdataset(self, section, name, rdataset, **kw):
        """Add the rdataset to the specified section, using the specified
        name as the owner name.

        Any keyword arguments are passed on to the rdataset's to_wire()
        routine.

        @param section: the section
        @type section: int
        @param name: the owner name
        @type name: dns.name.Name object
        @param rdataset: the rdataset
        @type rdataset: dns.rdataset.Rdataset object
        """

        self._set_section(section)
        before = self.output.tell()
        n = rdataset.to_wire(name, self.output, self.compress, self.origin,
                             **kw)
        after = self.output.tell()
        if after >= self.max_size:
            self._rollback(before)
            raise dns.exception.TooBig
        self.counts[section] += n

    def add_edns(self, edns, ednsflags, payload, options=None):
        """Add an EDNS OPT record to the message.

        @param edns: The EDNS level to use.
        @type edns: int
        @param ednsflags: EDNS flag values.
        @type ednsflags: int
        @param payload: The EDNS sender's payload field, which is the maximum
        size of UDP datagram the sender can handle.
        @type payload: int
        @param options: The EDNS options list
        @type options: list of dns.edns.Option instances
        @see: RFC 2671
        """

        # make sure the EDNS version in ednsflags agrees with edns
        ednsflags &= long(0xFF00FFFF)
        ednsflags |= (edns << 16)
        self._set_section(ADDITIONAL)
        before = self.output.tell()
        self.output.write(struct.pack('!BHHIH', 0, dns.rdatatype.OPT, payload,
                                      ednsflags, 0))
        if options is not None:
            lstart = self.output.tell()
            for opt in options:
                stuff = struct.pack("!HH", opt.otype, 0)
                self.output.write(stuff)
                start = self.output.tell()
                opt.to_wire(self.output)
                end = self.output.tell()
                assert end - start < 65536
                self.output.seek(start - 2)
                stuff = struct.pack("!H", end - start)
                self.output.write(stuff)
                self.output.seek(0, 2)
            lend = self.output.tell()
            assert lend - lstart < 65536
            self.output.seek(lstart - 2)
            stuff = struct.pack("!H", lend - lstart)
            self.output.write(stuff)
            self.output.seek(0, 2)
        after = self.output.tell()
        if after >= self.max_size:
            self._rollback(before)
            raise dns.exception.TooBig
        self.counts[ADDITIONAL] += 1

    def add_tsig(self, keyname, secret, fudge, id, tsig_error, other_data,
                 request_mac, algorithm=dns.tsig.default_algorithm):
        """Add a TSIG signature to the message.

        @param keyname: the TSIG key name
        @type keyname: dns.name.Name object
        @param secret: the secret to use
        @type secret: string
        @param fudge: TSIG time fudge
        @type fudge: int
        @param id: the message id to encode in the tsig signature
        @type id: int
        @param tsig_error: TSIG error code; default is 0.
        @type tsig_error: int
        @param other_data: TSIG other data.
        @type other_data: string
        @param request_mac: This message is a response to the request which
        had the specified MAC.
        @type request_mac: string
        @param algorithm: the TSIG algorithm to use
        @type algorithm: dns.name.Name object
        """

        self._set_section(ADDITIONAL)
        before = self.output.tell()
        s = self.output.getvalue()
        (tsig_rdata, self.mac, ctx) = dns.tsig.sign(s,
                                                    keyname,
                                                    secret,
                                                    int(time.time()),
                                                    fudge,
                                                    id,
                                                    tsig_error,
                                                    other_data,
                                                    request_mac,
                                                    algorithm=algorithm)
        keyname.to_wire(self.output, self.compress, self.origin)
        self.output.write(struct.pack('!HHIH', dns.rdatatype.TSIG,
                                      dns.rdataclass.ANY, 0, 0))
        rdata_start = self.output.tell()
        self.output.write(tsig_rdata)
        after = self.output.tell()
        assert after - rdata_start < 65536
        if after >= self.max_size:
            self._rollback(before)
            raise dns.exception.TooBig
        self.output.seek(rdata_start - 2)
        self.output.write(struct.pack('!H', after - rdata_start))
        self.counts[ADDITIONAL] += 1
        self.output.seek(10)
        self.output.write(struct.pack('!H', self.counts[ADDITIONAL]))
        self.output.seek(0, 2)

    def write_header(self):
        """Write the DNS message header.

        Writing the DNS message header is done after all sections
        have been rendered, but before the optional TSIG signature
        is added.
        """

        self.output.seek(0)
        self.output.write(struct.pack('!HHHHHH', self.id, self.flags,
                                      self.counts[0], self.counts[1],
                                      self.counts[2], self.counts[3]))
        self.output.seek(0, 2)

    def get_wire(self):
        """Return the wire format message.

        @rtype: string
        """

        return self.output.getvalue()
PKn�\�ĵ�KKe164.pynu�[���# Copyright (C) 2006, 2007, 2009, 2011 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
# provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""DNS E.164 helpers

@var public_enum_domain: The DNS public ENUM domain, e164.arpa.
@type public_enum_domain: dns.name.Name object
"""


import dns.exception
import dns.name
import dns.resolver
from ._compat import string_types

public_enum_domain = dns.name.from_text('e164.arpa.')


def from_e164(text, origin=public_enum_domain):
    """Convert an E.164 number in textual form into a Name object whose
    value is the ENUM domain name for that number.
    @param text: an E.164 number in textual form.
    @type text: str
    @param origin: The domain in which the number should be constructed.
    The default is e164.arpa.
    @type origin: dns.name.Name object or None
    @rtype: dns.name.Name object
    """
    parts = [d for d in text if d.isdigit()]
    parts.reverse()
    return dns.name.from_text('.'.join(parts), origin=origin)


def to_e164(name, origin=public_enum_domain, want_plus_prefix=True):
    """Convert an ENUM domain name into an E.164 number.
    @param name: the ENUM domain name.
    @type name: dns.name.Name object.
    @param origin: A domain containing the ENUM domain name.  The
    name is relativized to this domain before being converted to text.
    @type origin: dns.name.Name object or None
    @param want_plus_prefix: if True, add a '+' to the beginning of the
    returned number.
    @rtype: str
    """
    if origin is not None:
        name = name.relativize(origin)
    dlabels = [d for d in name.labels if d.isdigit() and len(d) == 1]
    if len(dlabels) != len(name.labels):
        raise dns.exception.SyntaxError('non-digit labels in ENUM domain name')
    dlabels.reverse()
    text = b''.join(dlabels)
    if want_plus_prefix:
        text = b'+' + text
    return text


def query(number, domains, resolver=None):
    """Look for NAPTR RRs for the specified number in the specified domains.

    e.g. lookup('16505551212', ['e164.dnspython.org.', 'e164.arpa.'])
    """
    if resolver is None:
        resolver = dns.resolver.get_default_resolver()
    e_nx = dns.resolver.NXDOMAIN()
    for domain in domains:
        if isinstance(domain, string_types):
            domain = dns.name.from_text(domain)
        qname = dns.e164.from_e164(number, domain)
        try:
            return resolver.query(qname, 'NAPTR')
        except dns.resolver.NXDOMAIN as e:
            e_nx += e
    raise e_nx
PKi�\��Yҹu�u%__pycache__/zone.cpython-36.opt-1.pycnu�[���PKi�\:��	�	&v__pycache__/rcode.cpython-36.opt-1.pycnu�[���PKi�\o�o		#�__pycache__/wiredata.cpython-36.pycnu�[���PKi�\�Ja�AA%�__pycache__/tsig.cpython-36.opt-1.pycnu�[���PKi�\�Ja�AA�__pycache__/tsig.cpython-36.pycnu�[���PKi�\��Yҹu�u��__pycache__/zone.cpython-36.pycnu�[���PKi�\�VJ��8�8$�0__pycache__/tokenizer.cpython-36.pycnu�[���PKi�\�8�Yww �i__pycache__/rrset.cpython-36.pycnu�[���PKi�\b�CI(s~__pycache__/_compat.cpython-36.opt-1.pycnu�[���PKi�\��Z��!ރ__pycache__/grange.cpython-36.pycnu�[���PKi�\�=���"�__pycache__/version.cpython-36.pycnu�[���PKi�\���!
!
&�__pycache__/reversename.cpython-36.pycnu�[���PKi�\{��_��$|�__pycache__/set.cpython-36.opt-1.pycnu�[���PKi�\]��)zz ��__pycache__/flags.cpython-36.pycnu�[���PKi�\5�
nn(y�__pycache__/message.cpython-36.opt-1.pycnu�[���PKi�\���"		?<__pycache__/inet.cpython-36.pycnu�[���PKi�\�drNN%�E__pycache__/ipv4.cpython-36.opt-1.pycnu�[���PKi�\���	�	+=K__pycache__/rdataclass.cpython-36.opt-1.pycnu�[���PKi�\-^�L��%dU__pycache__/hash.cpython-36.opt-1.pycnu�[���PKi�\i?N%N%#�W__pycache__/rdataset.cpython-36.pycnu�[���PKi�\z}��&&)5}__pycache__/renderer.cpython-36.opt-1.pycnu�[���PKi�\b�?,��__pycache__/tsigkeyring.cpython-36.opt-1.pycnu�[���PKi�\0
�	��%�__pycache__/node.cpython-36.opt-1.pycnu�[���PKi�\]���5�5 �__pycache__/query.cpython-36.pycnu�[���PKi�\�f5���(�__pycache__/entropy.cpython-36.opt-1.pycnu�[���PKi�\YZ
88 7__pycache__/rdata.cpython-36.pycnu�[���PKi�\�M�����#�9__pycache__/resolver.cpython-36.pycnu�[���PKi�\��M�(($��__pycache__/ttl.cpython-36.opt-1.pycnu�[���PKi�\J,���*�*!)�__pycache__/dnssec.cpython-36.pycnu�[���PKj�\]��)zz&�__pycache__/flags.cpython-36.opt-1.pycnu�[���PKj�\pJ�ն�!�__pycache__/update.cpython-36.pycnu�[���PKj�\A��'�__pycache__/opcode.cpython-36.opt-1.pycnu�[���PKj�\�M�����)M#__pycache__/resolver.cpython-36.opt-1.pycnu�[���PKj�\�_DBII#f�__pycache__/__init__.cpython-36.pycnu�[���PKj�\雅Xc&c&#�__pycache__/renderer.cpython-36.pycnu�[���PKj�\`��	77%��__pycache__/edns.cpython-36.opt-1.pycnu�[���PKj�\�|��g
g
%D�__pycache__/e164.cpython-36.opt-1.pycnu�[���PKj�\�֙O'%'%)�__pycache__/rdataset.cpython-36.opt-1.pycnu�[���PKj�\:��	�	 �__pycache__/rcode.cpython-36.pycnu�[���PKj�\�|��g
g
�$__pycache__/e164.cpython-36.pycnu�[���PKj�\o�o		)=/__pycache__/wiredata.cpython-36.opt-1.pycnu�[���PKj�\�drNN�8__pycache__/ipv4.cpython-36.pycnu�[���PKj�\�f5���"D>__pycache__/entropy.cpython-36.pycnu�[���PKj�\b�CI"iK__pycache__/_compat.cpython-36.pycnu�[���PKj�\pJ�ն�'�P__pycache__/update.cpython-36.opt-1.pycnu�[���PKj�\A��!�l__pycache__/opcode.cpython-36.pycnu�[���PKj�\k���''#.u__pycache__/namedict.cpython-36.pycnu�[���PKj�\0
�	����__pycache__/node.cpython-36.pycnu�[���PKj�\�_DBII)��__pycache__/__init__.cpython-36.opt-1.pycnu�[���PKj�\���	�	%7�__pycache__/rdataclass.cpython-36.pycnu�[���PKj�\�ȟ��%X�__pycache__/ipv6.cpython-36.opt-1.pycnu�[���PKj�\�VJ��8�8*Y�__pycache__/tokenizer.cpython-36.opt-1.pycnu�[���PKj�\k���'')^�__pycache__/namedict.cpython-36.opt-1.pycnu�[���PKj�\����i�i%��__pycache__/name.cpython-36.opt-1.pycnu�[���PKj�\���"		%)^__pycache__/inet.cpython-36.opt-1.pycnu�[���PKj�\��şDD$�g__pycache__/exception.cpython-36.pycnu�[���PKj�\{��_��"w__pycache__/set.cpython-36.pycnu�[���PKj�\]���5�5&O�__pycache__/query.cpython-36.opt-1.pycnu�[���PKj�\��M�((Y�__pycache__/ttl.cpython-36.pycnu�[���PKj�\�8�Yww&��__pycache__/rrset.cpython-36.opt-1.pycnu�[���PKj�\�pp���$��__pycache__/rdatatype.cpython-36.pycnu�[���PKj�\�pp���*��__pycache__/rdatatype.cpython-36.opt-1.pycnu�[���PKj�\-^�L��t
__pycache__/hash.cpython-36.pycnu�[���PKj�\=*ᴈ�'�__pycache__/grange.cpython-36.opt-1.pycnu�[���PKj�\b�?&}__pycache__/tsigkeyring.cpython-36.pycnu�[���PKj�\�0��qq*�__pycache__/exception.cpython-36.opt-1.pycnu�[���PKj�\�zu-\*\*'�#__pycache__/dnssec.cpython-36.opt-1.pycnu�[���PKj�\����i�ipN__pycache__/name.cpython-36.pycnu�[���PKj�\���!
!
,��__pycache__/reversename.cpython-36.opt-1.pycnu�[���PKj�\�ȟ��2�__pycache__/ipv6.cpython-36.pycnu�[���PKj�\5�
nn"-�__pycache__/message.cpython-36.pycnu�[���PKj�\`��	77�N__pycache__/edns.cpython-36.pycnu�[���PKj�\YZ
88&s`__pycache__/rdata.cpython-36.opt-1.pycnu�[���PKj�\�=���(ܘ__pycache__/version.cpython-36.opt-1.pycnu�[���PKj�\��''	��update.pynu�[���PKj�\�^Is��K�tsigkeyring.pynu�[���PKj�\D����9�9	R�dnssec.pynu�[���PKj�\`�oLLR	hash.pynu�[���PKj�\K�炕:�:�	rdata.pynu�[���PKj�\�2Y9���B	inet.pynu�[���PKj�\��9�//�O	__init__.pynu�[���PKj�\�E!o&&�T	tsig.pynu�[���PKj�\���)!!
Js	_compat.pynu�[���PKj�\9R�����x	resolver.pynu�[���PKj�\2�5
##iD
set.pynu�[���PKj�\���ӉG�G�b
tokenizer.pynu�[���PKj�\���	�		��
opcode.pynu�[���PKj�\O�����
ttl.pynu�[���PKj�\��קqq
˽
entropy.pynu�[���PKj�\���	v�
grange.pynu�[���PKj�\��Qy�y�
d�
message.pynu�[���PKk�\��EG�exception.pynu�[���PKk�\��V��e�ipv6.pynu�[���PKk�\4V�f��
I�version.pynu�[���PKk�\�5�t��m�wiredata.pynu�[���PKk�\�H>��;�rdatatype.pynu�[���PKk�\�޻$-$-R�rdataset.pynu�[���PKk�\�/�L�L��query.pynu�[���PKk�\˸�����Jipv4.pynu�[���PKk�\Cy�x  �Redns.pynu�[���PKk�\/XO��#dnode.pynu�[���PKk�\���kk|rrset.pynu�[���PKk�\7�D�r�r��name.pynu�[���PKk�\�X2���
reversename.pynu�[���PKk�\ų4�h
h
�
flags.pynu�[���PKk�\������
�
rdataclass.pynu�[���PKk�\D��|Z�Z��+
zone.pynu�[���PKk�\�j�i]]"�
namedict.pynu�[���PKk�\���3  ��
rcode.pynu�[���PKk�\�����)�
rdtypes/IN/__pycache__/SRV.cpython-36.pycnu�[���PKk�\T���``.^�
rdtypes/IN/__pycache__/KX.cpython-36.opt-1.pycnu�[���PKk�\\m9Mrr.�
rdtypes/IN/__pycache__/NSAP_PTR.cpython-36.pycnu�[���PKk�\6�Pb.��
rdtypes/IN/__pycache__/IPSECKEY.cpython-36.pycnu�[���PKk�\�����/d�
rdtypes/IN/__pycache__/APL.cpython-36.opt-1.pycnu�[���PKk�\������+~
rdtypes/IN/__pycache__/NAPTR.cpython-36.pycnu�[���PKk�\=����1�rdtypes/IN/__pycache__/DHCID.cpython-36.opt-1.pycnu�[���PKk�\٣��0�!rdtypes/IN/__pycache__/AAAA.cpython-36.opt-1.pycnu�[���PKk�\T���``(6(rdtypes/IN/__pycache__/KX.cpython-36.pycnu�[���PKk�\S
�.�)rdtypes/IN/__pycache__/__init__.cpython-36.pycnu�[���PKk�\g���0\+rdtypes/IN/__pycache__/NSAP.cpython-36.opt-1.pycnu�[���PKk�\�r�O��1n2rdtypes/IN/__pycache__/NAPTR.cpython-36.opt-1.pycnu�[���PKk�\6�Pb4�?rdtypes/IN/__pycache__/IPSECKEY.cpython-36.opt-1.pycnu�[���PKk�\"����)Nrdtypes/IN/__pycache__/APL.cpython-36.pycnu�[���PKl�\=����+H]rdtypes/IN/__pycache__/DHCID.cpython-36.pycnu�[���PKl�\\m9Mrr44drdtypes/IN/__pycache__/NSAP_PTR.cpython-36.opt-1.pycnu�[���PKl�\
����-
frdtypes/IN/__pycache__/A.cpython-36.opt-1.pycnu�[���PKl�\S
�4[lrdtypes/IN/__pycache__/__init__.cpython-36.opt-1.pycnu�[���PKl�\��g��
�
/�mrdtypes/IN/__pycache__/WKS.cpython-36.opt-1.pycnu�[���PKl�\٣��*�xrdtypes/IN/__pycache__/AAAA.cpython-36.pycnu�[���PKl�\��g��
�
)erdtypes/IN/__pycache__/WKS.cpython-36.pycnu�[���PKl�\"�ݯ!	!	(|�rdtypes/IN/__pycache__/PX.cpython-36.pycnu�[���PKl�\�����/��rdtypes/IN/__pycache__/SRV.cpython-36.opt-1.pycnu�[���PKl�\"�ݯ!	!	.G�rdtypes/IN/__pycache__/PX.cpython-36.opt-1.pycnu�[���PKl�\g���*Ʀrdtypes/IN/__pycache__/NSAP.cpython-36.pycnu�[���PKl�\
����'ҭrdtypes/IN/__pycache__/A.cpython-36.pycnu�[���PKl�\/"��tt�rdtypes/IN/APL.pynu�[���PKl�\RJ6r����rdtypes/IN/__init__.pynu�[���PKl�\��2�11��rdtypes/IN/IPSECKEY.pynu�[���PKl�\����T�rdtypes/IN/DHCID.pynu�[���PKl�\��4==z�rdtypes/IN/A.pynu�[���PKl�\m��B
B
��rdtypes/IN/PX.pynu�[���PKl�\�qQ��xrdtypes/IN/WKS.pynu�[���PKl�\�2����rdtypes/IN/SRV.pynu�[���PKl�\�W��vv�rdtypes/IN/NAPTR.pynu�[���PKl�\�;�J�-rdtypes/IN/NSAP.pynu�[���PKl�\������5rdtypes/IN/AAAA.pynu�[���PKl�\�7��qq�=rdtypes/IN/KX.pynu�[���PKl�\�0}}jArdtypes/IN/NSAP_PTR.pynu�[���PKl�\��V�553-Erdtypes/__pycache__/dnskeybase.cpython-36.opt-1.pycnu�[���PKl�\v�~u
u
/�Srdtypes/__pycache__/nsbase.cpython-36.opt-1.pycnu�[���PKl�\t���0�^rdtypes/__pycache__/txtbase.cpython-36.opt-1.pycnu�[���PKl�\��C�
�
)�grdtypes/__pycache__/mxbase.cpython-36.pycnu�[���PKl�\��C�
�
/�urdtypes/__pycache__/mxbase.cpython-36.opt-1.pycnu�[���PKl�\��B1		*؃rdtypes/__pycache__/txtbase.cpython-36.pycnu�[���PKl�\��acc0N�rdtypes/__pycache__/euibase.cpython-36.opt-1.pycnu�[���PKl�\�E�� 	 	/�rdtypes/__pycache__/dsbase.cpython-36.opt-1.pycnu�[���PKl�\z�\J��+��rdtypes/__pycache__/__init__.cpython-36.pycnu�[���PKl�\v�~u
u
)��rdtypes/__pycache__/nsbase.cpython-36.pycnu�[���PKl�\z�\J��1��rdtypes/__pycache__/__init__.cpython-36.opt-1.pycnu�[���PKl�\��acc*Ƭrdtypes/__pycache__/euibase.cpython-36.pycnu�[���PKl�\��V�55-��rdtypes/__pycache__/dnskeybase.cpython-36.pycnu�[���PKl�\�E�� 	 	)�rdtypes/__pycache__/dsbase.cpython-36.pycnu�[���PKl�\�$�##��rdtypes/dnskeybase.pynu�[���PKl�\j_[���rdtypes/__init__.pynu�[���PKl�\@�eLL��rdtypes/mxbase.pynu�[���PKl�\e�B�E�rdtypes/dsbase.pynu�[���PKl�\!������rdtypes/txtbase.pynu�[���PKl�\z<�##�	rdtypes/nsbase.pynu�[���PKl�\���
�
rdtypes/euibase.pynu�[���PKl�\CN�cGG. rdtypes/ANY/X25.pynu�[���PKl�\y1s���(rdtypes/ANY/GPOS.pynu�[���PKl�\ab4[[*�=rdtypes/ANY/__pycache__/DLV.cpython-36.pycnu�[���PKl�\����1�?rdtypes/ANY/__pycache__/TLSA.cpython-36.opt-1.pycnu�[���PKl�\ab4[[0�Hrdtypes/ANY/__pycache__/DLV.cpython-36.opt-1.pycnu�[���PKl�\I��pp2�Jrdtypes/ANY/__pycache__/CSYNC.cpython-36.opt-1.pycnu�[���PKl�\�UXTXX/tWrdtypes/ANY/__pycache__/DS.cpython-36.opt-1.pycnu�[���PKl�\^��0+Yrdtypes/ANY/__pycache__/CAA.cpython-36.opt-1.pycnu�[���PKl�\[[QXX/�ardtypes/ANY/__pycache__/NS.cpython-36.opt-1.pycnu�[���PKl�\�}��<<+Gcrdtypes/ANY/__pycache__/GPOS.cpython-36.pycnu�[���PKl�\�;[[*�srdtypes/ANY/__pycache__/PTR.cpython-36.pycnu�[���PKl�\�ݹSXX)�urdtypes/ANY/__pycache__/MX.cpython-36.pycnu�[���PKl�\���r��1Dwrdtypes/ANY/__pycache__/NSEC.cpython-36.opt-1.pycnu�[���PKl�\u���[[,N�rdtypes/ANY/__pycache__/SSHFP.cpython-36.pycnu�[���PKl�\?�['��0�rdtypes/ANY/__pycache__/URI.cpython-36.opt-1.pycnu�[���PKl�\I��pp,8�rdtypes/ANY/__pycache__/CSYNC.cpython-36.pycnu�[���PKl�\��h��*�rdtypes/ANY/__pycache__/SOA.cpython-36.pycnu�[���PKl�\�	{���2>�rdtypes/ANY/__pycache__/NSEC3.cpython-36.opt-1.pycnu�[���PKl�\w-��2v�rdtypes/ANY/__pycache__/EUI48.cpython-36.opt-1.pycnu�[���PKl�\u���[[2��rdtypes/ANY/__pycache__/SSHFP.cpython-36.opt-1.pycnu�[���PKl�\��,���+��rdtypes/ANY/__pycache__/ISDN.cpython-36.pycnu�[���PKl�\����2��rdtypes/ANY/__pycache__/EUI64.cpython-36.opt-1.pycnu�[���PKl�\��ǃ^^*T�rdtypes/ANY/__pycache__/TXT.cpython-36.pycnu�[���PKl�\�j+���1�rdtypes/ANY/__pycache__/CERT.cpython-36.opt-1.pycnu�[���PKl�\o�DB��2K�rdtypes/ANY/__pycache__/HINFO.cpython-36.opt-1.pycnu�[���PKm�\�	{���,v�rdtypes/ANY/__pycache__/NSEC3.cpython-36.pycnu�[���PKm�\�eQ??2�rdtypes/ANY/__pycache__/AFSDB.cpython-36.opt-1.pycnu�[���PKm�\����.Irdtypes/ANY/__pycache__/CDNSKEY.cpython-36.pycnu�[���PKm�\5�rr*}rdtypes/ANY/__pycache__/SPF.cpython-36.pycnu�[���PKm�\r���,I
rdtypes/ANY/__pycache__/HINFO.cpython-36.pycnu�[���PKm�\�\m
��0�rdtypes/ANY/__pycache__/HIP.cpython-36.opt-1.pycnu�[���PKm�\����4�rdtypes/ANY/__pycache__/CDNSKEY.cpython-36.opt-1.pycnu�[���PKm�\��ǃ^^0�!rdtypes/ANY/__pycache__/TXT.cpython-36.opt-1.pycnu�[���PKm�\���__,�#rdtypes/ANY/__pycache__/RRSIG.cpython-36.pycnu�[���PKm�\��M��)N5rdtypes/ANY/__pycache__/RP.cpython-36.pycnu�[���PKm�\&c��1�>rdtypes/ANY/__pycache__/GPOS.cpython-36.opt-1.pycnu�[���PKm�\���r��+Ordtypes/ANY/__pycache__/NSEC.cpython-36.pycnu�[���PKm�\�>���*\rdtypes/ANY/__pycache__/AVC.cpython-36.pycnu�[���PKm�\����,^rdtypes/ANY/__pycache__/EUI64.cpython-36.pycnu�[���PKm�\��)	)	1�`rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-36.pycnu�[���PKm�\����+jrdtypes/ANY/__pycache__/TLSA.cpython-36.pycnu�[���PKm�\!�F0��-Isrdtypes/ANY/__pycache__/DNSKEY.cpython-36.pycnu�[���PKm�\��h��0yurdtypes/ANY/__pycache__/SOA.cpython-36.opt-1.pycnu�[���PKm�\UΔ���/��rdtypes/ANY/__pycache__/__init__.cpython-36.pycnu�[���PKm�\w-��,�rdtypes/ANY/__pycache__/EUI48.cpython-36.pycnu�[���PKm�\�ݹSXX/n�rdtypes/ANY/__pycache__/MX.cpython-36.opt-1.pycnu�[���PKm�\!�F0��3%�rdtypes/ANY/__pycache__/DNSKEY.cpython-36.opt-1.pycnu�[���PKm�\�eQ??,[�rdtypes/ANY/__pycache__/AFSDB.cpython-36.pycnu�[���PKm�\#c� ..2��rdtypes/ANY/__pycache__/CNAME.cpython-36.opt-1.pycnu�[���PKm�\T/��[[0��rdtypes/ANY/__pycache__/CDS.cpython-36.opt-1.pycnu�[���PKm�\�UXTXX)A�rdtypes/ANY/__pycache__/DS.cpython-36.pycnu�[���PKm�\��+�((*�rdtypes/ANY/__pycache__/CAA.cpython-36.pycnu�[���PKm�\5�rr0t�rdtypes/ANY/__pycache__/SPF.cpython-36.opt-1.pycnu�[���PKm�\UΔ���5F�rdtypes/ANY/__pycache__/__init__.cpython-36.opt-1.pycnu�[���PKm�\���__2��rdtypes/ANY/__pycache__/RRSIG.cpython-36.opt-1.pycnu�[���PKm�\��?rjj/T�rdtypes/ANY/__pycache__/RT.cpython-36.opt-1.pycnu�[���PKm�\T/��[[*�rdtypes/ANY/__pycache__/CDS.cpython-36.pycnu�[���PKm�\[[QXX)ҷrdtypes/ANY/__pycache__/NS.cpython-36.pycnu�[���PKm�\��?rjj)��rdtypes/ANY/__pycache__/RT.cpython-36.pycnu�[���PKm�\�.�M��*F�rdtypes/ANY/__pycache__/X25.cpython-36.pycnu�[���PKm�\j/�jk k 0j�rdtypes/ANY/__pycache__/LOC.cpython-36.opt-1.pycnu�[���PKm�\�\m
��*5�rdtypes/ANY/__pycache__/HIP.cpython-36.pycnu�[���PKm�\j/�jk k *+�rdtypes/ANY/__pycache__/LOC.cpython-36.pycnu�[���PKm�\�!s,�rdtypes/ANY/__pycache__/DNAME.cpython-36.pycnu�[���PKm�\�j+���+Ordtypes/ANY/__pycache__/CERT.cpython-36.pycnu�[���PKm�\��M��/�rdtypes/ANY/__pycache__/RP.cpython-36.opt-1.pycnu�[���PKm�\�;[[0�(rdtypes/ANY/__pycache__/PTR.cpython-36.opt-1.pycnu�[���PKm�\��)	)	7�*rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-36.opt-1.pycnu�[���PKm�\ޑj��114rdtypes/ANY/__pycache__/ISDN.cpython-36.opt-1.pycnu�[���PKm�\������0?=rdtypes/ANY/__pycache__/X25.cpython-36.opt-1.pycnu�[���PKm�\#c� ..,FDrdtypes/ANY/__pycache__/CNAME.cpython-36.pycnu�[���PKm�\�>���0�Frdtypes/ANY/__pycache__/AVC.cpython-36.opt-1.pycnu�[���PKm�\?�['��*�Hrdtypes/ANY/__pycache__/URI.cpython-36.pycnu�[���PKm�\�!s2Rrdtypes/ANY/__pycache__/DNAME.cpython-36.opt-1.pycnu�[���PKm�\Bd����xTrdtypes/ANY/DNAME.pynu�[���PKm�\�?dd�Xrdtypes/ANY/EUI48.pynu�[���PKm�\�C�nn7]rdtypes/ANY/TXT.pynu�[���PKm�\�x
>
>
�`rdtypes/ANY/CAA.pynu�[���PKm�\�EAVkkgkrdtypes/ANY/PTR.pynu�[���PKm�\΍JBiiordtypes/ANY/DS.pynu�[���PKm�\�0���rrdtypes/ANY/__init__.pynu�[���PKm�\°���wrdtypes/ANY/SSHFP.pynu�[���PKm�\�c#����rdtypes/ANY/TLSA.pynu�[���PKm�\�� 2�/�/�rdtypes/ANY/LOC.pynu�[���PKm�\�3�,nn�rdtypes/ANY/EUI64.pynu�[���PKm�\���n{{��rdtypes/ANY/RT.pynu�[���PKm�\�X����rdtypes/ANY/RRSIG.pynu�[���PKn�\о����rdtypes/ANY/DNSKEY.pynu�[���PKn�\-��kk)�rdtypes/ANY/CDS.pynu�[���PKn�\�����rdtypes/ANY/CDNSKEY.pynu�[���PKn�\��GRR�rdtypes/ANY/NSEC.pynu�[���PKn�\o:Ri
i
��rdtypes/ANY/HINFO.pynu�[���PKn�\������`rdtypes/ANY/RP.pynu�[���PKn�\�o(
<<�rdtypes/ANY/CNAME.pynu�[���PKn�\5_W5��rdtypes/ANY/AVC.pynu�[���PKn�\U�&��rdtypes/ANY/SPF.pynu�[���PKn�\Q�x����rdtypes/ANY/ISDN.pynu�[���PKn�\�[$$$�,rdtypes/ANY/CSYNC.pynu�[���PKn�\��,�iiL?rdtypes/ANY/MX.pynu�[���PKn�\k�9��Brdtypes/ANY/NSEC3PARAM.pynu�[���PKn�\�&�͡�YOrdtypes/ANY/NSEC3.pynu�[���PKn�\`0��oo>krdtypes/ANY/CERT.pynu�[���PKn�\��``�zrdtypes/ANY/DLV.pynu�[���PKn�\��7�RR�~rdtypes/ANY/URI.pynu�[���PKn�\��ig��&�rdtypes/ANY/SOA.pynu�[���PKn�\�[Reii�rdtypes/ANY/NS.pynu�[���PKn�\Z��S00��rdtypes/ANY/HIP.pynu�[���PKn�\ϝs88,�rdtypes/ANY/AFSDB.pynu�[���PKn�\��%�.�.��renderer.pynu�[���PKn�\�ĵ�KKv�e164.pynu�[���PK�i��