U mfh@sfdZddlZddlZddlZddlZddlZddlmZmZm Z m Z m Z ddl Z ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlZ ddlmZddlmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#e"rddl$Z$e j%j&Z'ddZ(d6dd Z)d7e j*j+e e j,j-e.fee e/e e0e/fd d d Z1d8e j*j+e ee e/e2e2e ee j3j4e j5j6fe e.e2e2e2e e j,j-ed ddZ7d9e j,j-e8e e/e0e e8e0e2e2e2e2e e j*j+e e j*j9e2e j,j-dddZ:d:e j,j-e8e e/e0e e8e0e2e2e2e e j*j+e e j*j;e e j*j9e2e e j,j-e2fdddZde j,j-e8e e/e0e e8e0e2e2e e j*j;e e j*j9e e#jAe e8e e2e8fe j,j-d&d'd(ZBdd)ddd d dd*d%d%ddejCf e j,j-e8e e/e0e e8e0e2e2e d+e8e2e e2e8fe e8e d,e e0e j,j-d-d.d/ZDddddddejEdfe8e jFjGe e j,j-e0e e/e e/e e8e0ee e j*j9dd0 d1d2ZHd?e j,j-e8e e/e0e e8e0e2e2e e jIjJe e2e8fe e j*j9e e8e j,j-d3 d4d5ZIdS)@zTalk to a DNS server.N)AnyDictOptionalTupleUnion) NullContext) BadResponseNoDOHNoDOQUDPMode_compute_times_make_dot_ssl_context_matches_destination _remaininghave_dohsslcCsN|s|rF|dkr>|tjkr d}n|tjkr0d}ntd|||fSdSdS)Nz0.0.0.0z::zunknown address family )socketAF_INETAF_INET6NotImplementedError)afaddressportr begin_timerrr#cmstupledtuplesrAr@_rrrudps@       rY)rErFrGrrHrIr/r0r3udp_socktcp_sockrJr5r$c svz0t|||||||||d| | | IdH} | dfWStjjk rpt||||||||| | IdH} | dfYSXdS)aReturn the response to the query, trying UDP first and falling back to TCP if UDP results in a truncated response. *udp_sock*, a ``dns.asyncbackend.DatagramSocket``, or ``None``, the socket to use for the UDP query. If ``None``, the default, a socket is created. Note that if a socket is provided the *source*, *source_port*, and *backend* are ignored for the UDP query. *tcp_sock*, a ``dns.asyncbackend.StreamSocket``, or ``None``, the socket to use for the TCP query. If ``None``, the default, a socket is created. Note that if a socket is provided *where*, *source*, *source_port*, and *backend* are ignored for the TCP query. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.udp_with_fallback()` for the documentation of the other parameters, exceptions, and return type of this method. TNF)rYr&r'r;tcp)rErFrGrrHrIr/r0r3rZr[rJr5responserrrudp_with_fallbacks>#   r^)r!r"rr$cs\t|tjjr|jdd}nt|dd|}t}||t ||IdHt||fS)zSend a DNS message to the specified TCP socket. *sock*, a ``dns.asyncbackend.StreamSocket``. See :py:func:`dns.query.send_tcp()` for the documentation of the other parameters, exceptions, and return type of this method. T)Zprepend_lengthbigN) r%r&r'r(r)lento_bytesrsendallr )r!r"rtcpmsgr+rrrsend_tcp4s recsHd}|dkrD||t|IdH}|dkr.t|t|}||}q|S)z|Read the specified number of bytes from stream. Keep trying until we either get the desired amount, or we hit EOF. r.rN)recvr EOFErrorra)r!countrrWr,rrr _read_exactlyMs  ri)r!rr0r1r2r3r$c sXt|d|IdH}td|\}t|||IdH}t} tjj|||||d} | | fS)zRead a DNS message from a TCP socket. *sock*, a ``dns.asyncbackend.StreamSocket``. See :py:func:`dns.query.receive_tcp()` for the documentation of the other parameters, exceptions, and return type of this method. r_N!Hr1r2r0r3)ristructunpackrr&r'r:) r!rr0r1r2r3ldatalr>r@rArrr receive_tcp[srp) rErFrGrrHrIr0r3r!rJr$c  s|} t|\} } |r0|IdHt|} nJtj|}t|||}||f}| s^tj } | |t j d|||IdH} | 4IdHb}t || | IdHt|| ||j|j|IdH\}}|| |_||st|W5QIdHRSQIdHRXdS)aOReturn the response obtained after sending a query via TCP. *sock*, a ``dns.asyncbacket.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided *where*, *port*, *source*, *source_port*, and *backend* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.tcp()` for the documentation of the other parameters, exceptions, and return type of this method. Nr)r)r getpeernamerr&rKrLrrNrOrPr SOCK_STREAMrerpr1rRrr<r)rErFrGrrHrIr0r3r!rJr>rSrrTrrUrVrWrAr@rrrr\ys@        r\UT)rErFrGrrHrIr0r3r!rJ ssl_contextserver_hostnameverifyr$c  st|\} }|rt|}n`| dkr,t| | } tj|}t|||}||f}| sZtj} | |t j d|||| | IdH}|4IdHR}t |}t |||||||||| IdH}t}|| |_|W5QIdHRSQIdHRXdS)aReturn the response obtained after sending a query via TLS. *sock*, an ``asyncbackend.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, it must be a connected SSL stream socket, and *where*, *port*, *source*, *source_port*, *backend*, *ssl_context*, and *server_hostname* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.tls()` for the documentation of the other parameters, exceptions, and return type of this method. Nr)r rr r&rKrLrrNrOrPrrrr r\r)rErFrGrrHrIr0r3r!rJrtrurvrSrrTrrUrVrWr]Zend_timerrrtlssJ         rwiz /dns-queryzhttpx.AsyncClientzdns.asyncresolver.Resolver)rErFrGrrHrIr0r3clientpathpostrvbootstrap_addressresolverr9r$c s tst|r t|tjs td|}ztj |}Wntk rPd}YnXd}ddi}|dk rtj |r|t j krd ||| }q|t jkrd ||| }n|}tj}|dkrd}d}n|}|}||dd| || | |d }|rt|}ntjdd| |d }|4IdH~}| rV|dtt|d ||j|||d |IdH}n:t|d }|}||j||d|id|IdH}W5QIdHRX|jdks|jdkrtd ||j|jtjj |j|j!|j"||d}|j#$|_%|&|st'|S)aReturn the response obtained after sending a query via DNS-over-HTTPS. *client*, a ``httpx.AsyncClient``. If provided, the client to use for the query. Unlike the other dnspython async functions, a backend cannot be provided in this function because httpx always auto-detects the async backend. See :py:func:`dns.query.https()` for the documentation of the other parameters, exceptions, and return type of this method. z.session parameter must be an httpx.AsyncClientNacceptzapplication/dns-messagezhttps://{}:{}{}zhttps://[{}]:{}{}rT) local_addresshttp1http2rv local_portr{r|r9)rrrv transport)z content-typezcontent-length)headerscontent=r&)rparamsi+z4{} responded with status code {} Response body: {!r}rk)(rr r%httpxZ AsyncClient ValueErrorr)r&rKrLZ is_addressrrformatrrNrOZget_transport_classrupdatestrrawait_forrzbase64urlsafe_b64encoderstripdecodeget status_coderr'r:r1r2elapsed total_secondsrr<r)rErFrGrrHrIr0r3rxryrzrvr{r|r9r>rrrurlrJr~rrTZ the_clientr]ZtwirerArrrhttpss          r) rF txn_managerr6rrGlifetimerHrIudp_moderJr$c # s|dkrtj|\}} n tj|} |jdj} | tjjk} |} | }tj |}t |||}||f}t |\}}d}|rd}| r|tjkrtj}d}n tj}d}| stj} | ||d||t|IdH}|4IdH|r|||t|IdHn&tdt||}|||IdHtj|| | |p}d}d}|st |\}}|dks||dk r||kr|}|rt||f|}t|}|d|IdH\}}t|||drqqn2t |d|IdH} t!d| \}!t ||!|IdH}| tjjk} tj"j#||j$|j%d| || | d}"z|&|"}WnFtjj'k r|sZt(|tj)krhd}d}tj}YqLYnX|"j*}qL|s|j$r|"j+stj,-d W5QRXW5QIdHRXq~dS) amConduct an inbound transfer and apply it via a transaction from the txn_manager. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.inbound_xfr()` for the documentation of the other parameters, exceptions, and return type of this method. NrTFrjr7r_)r1r2xfrorigintsig_ctxmultir0z missing TSIG).r&rZ make_queryZextract_serial_from_queryquestionrdtypeZ rdatatypeZIXFRZfrom_wire_originr)rKrLrr r NEVERrrQrrrNrOrPr r*rlpackrarcZInboundrMr8rrirmr'r:r1rRZprocess_messageZUseTCPAssertionErrorZONLYrZhad_tsig exceptionZ FormError)#rFrr6rrGrrHrIrrJserialrZis_ixfrrr>rrUrVrXrretryZ sock_typeZis_udprWrdZinbounddonerZ mexpirationr#Zrwirer?rnrorArrr inbound_xfrls                 r) rErFrGrrHrIr0r3 connectionrvrJrur$c  sJtjjstdd|_|} |r8tjj} tjj}|}ntj| \} }| 4IdH}||| | d4IdH}|s|||||}t |\}}| |IdH}|4IdH,| | dIdH| t |IdH} W5QIdHRXt}W5QIdHRXtjj| |j|j||d}W5QIdHRXt||d|_||sFt|S)aiReturn the response obtained after sending an asynchronous query via DNS-over-QUIC. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.quic()` for the documentation of the other parameters, exceptions, and return type of this method. zDNS-over-QUIC is not available.rN) verify_modeZ server_nameTrkg)r&quicZ have_quicr idr)Z null_factoryZfactories_for_backendconnectr Z make_streamsendZreceiverrr'r:r1r2rr<r)rErFrGrrHrIr0r3rrvrJrur>ZcfactoryZmfactoryZthe_connectioncontextZ the_managerstartrstreamfinishrArrrrsF $ r)N)N) NNFFNr.FFFN) NrDNrFFFFNNF) NrDNrFFFNNNF)N)NFNr.F)NrDNrFFNN) NrsNrFFNNNNT) NrsNrFFNTNN)K__doc__r contextlibrrlrtypingrrrrrZdns.asyncbackendr&Z dns.exceptionZdns.inetZ dns.messageZdns.nameZdns.quicZ dns.rcodeZdns.rdataclassZ dns.rdatatypeZdns.transactionZdns._asyncbackendrZ dns.queryrr r r r r rrrrrrKZlow_level_address_tuplerMrr rNZDatagramSocketr'r(bytesfloatintr-boolnameNameZtsigKeyrCrBackendrYZ StreamSocketr^rerirpr\ SSLContextrw AF_UNSPECrrZ transactionZTransactionManagerrrZAsyncQuicConnectionrrrrs 0     @   E    G  !   ;    I  x   h