HEX
Server: LiteSpeed
System: Linux srv146.niagahoster.com 4.18.0-553.30.1.lve.el8.x86_64 #1 SMP Tue Dec 3 01:21:19 UTC 2024 x86_64
User: kodi1989 (1633)
PHP: 8.1.34
Disabled: symlink,shell_exec,exec,popen,system,dl,passthru,escapeshellarg,escapeshellcmd,show_source,pcntl_exec
Upload Files
File: //opt/alt/python37/lib/python3.7/site-packages/pyroute2/netlink/__pycache__/nlsocket.cpython-37.pyc
B

��f=��@sRdZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlm
Z
ddlmZmZmZmZmZmZmZddlmZddlmZmZddlmZddlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/dd	l0m1Z1m2Z2m3Z3m4Z4m5Z5ydd
l6m6Z6Wn"e7k
�rRdd
l8m6Z6YnXe�9e:�Z;e�<dd�Z=d
Z>Gdd�d�Z?Gdd�d�Z@edddd�ZAGdd�d�ZBGdd�d�ZCGdd�d�ZDGdd�deD�ZEGdd�deD�ZFGdd �d �ZGGd!d"�d"�ZHGd#d$�d$eI�ZJGd%d&�d&eK�ZLGd'd(�d(eG�ZMGd)d*�d*eG�ZNGd+d,�d,eN�ZOdS)-a�

Base netlink socket and marshal
===============================

All the netlink providers are derived from the socket
class, so they provide normal socket API, including
`getsockopt()`, `setsockopt()`, they can be used in
poll/select I/O loops etc.

asynchronous I/O
----------------

To run async reader thread, one should call
`NetlinkSocket.bind(async_cache=True)`. In that case
a background thread will be launched. The thread will
automatically collect all the messages and store
into a userspace buffer.

.. note::
    There is no need to turn on async I/O, if you
    don't plan to receive broadcast messages.

ENOBUF and async I/O
--------------------

When Netlink messages arrive faster than a program
reads then from the socket, the messages overflow
the socket buffer and one gets ENOBUF on `recv()`::

    ... self.recv(bufsize)
    error: [Errno 105] No buffer space available

One way to avoid ENOBUF, is to use async I/O. Then the
library not only reads and buffers all the messages, but
also re-prioritizes threads. Suppressing the parser
activity, the library increases the response delay, but
spares CPU to read and enqueue arriving messages as
fast, as it is possible.

With logging level DEBUG you can notice messages, that
the library started to calm down the parser thread::

    DEBUG:root:Packet burst: the reader thread priority
        is increased, beware of delays on netlink calls
        Counters: delta=25 qsize=25 delay=0.1

This state requires no immediate action, but just some
more attention. When the delay between messages on the
parser thread exceeds 1 second, DEBUG messages become
WARNING ones::

    WARNING:root:Packet burst: the reader thread priority
        is increased, beware of delays on netlink calls
        Counters: delta=2525 qsize=213536 delay=3

This state means, that almost all the CPU resources are
dedicated to the reader thread. It doesn't mean, that
the reader thread consumes 100% CPU -- it means, that the
CPU is reserved for the case of more intensive bursts. The
library will return to the normal state only when the
broadcast storm will be over, and then the CPU will be
100% loaded with the parser for some time, when it will
process all the messages queued so far.

when async I/O doesn't help
---------------------------

Sometimes, even turning async I/O doesn't fix ENOBUF.
Mostly it means, that in this particular case the Python
performance is not enough even to read and store the raw
data from the socket. There is no workaround for such
cases, except of using something *not* Python-based.

One can still play around with SO_RCVBUF socket option,
but it doesn't help much. So keep it in mind, and if you
expect massive broadcast Netlink storms, perform stress
testing prior to deploy a solution in the production.

classes
-------
�N)�partial)�MSG_DONTWAIT�MSG_PEEK�	MSG_TRUNC�	SO_RCVBUF�	SO_SNDBUF�
SOCK_DGRAM�
SOL_SOCKET)�config)�DEFAULT_RCVBUF�AddrPool)�
AF_NETLINK)�NETLINK_ADD_MEMBERSHIP�NETLINK_DROP_MEMBERSHIP�NETLINK_EXT_ACK�NETLINK_GENERIC�NETLINK_GET_STRICT_CHK�NETLINK_LISTEN_ALL_NSID�	NLM_F_ACK�NLM_F_ACK_TLVS�
NLM_F_DUMP�NLM_F_DUMP_INTR�NLM_F_MULTI�
NLM_F_REQUEST�
NLMSG_DONE�NLMSG_ERROR�SOL_NETLINK�mtypes�nlmsg�nlmsgerr)�ChaoticException�NetlinkDecodeError�NetlinkDumpInterrupted�NetlinkError�NetlinkHeaderDecodeError)�Queue�Stats)�qsize�delta�delayi�c@s,eZdZdd�Zdd�Zdd�Zdd�Zd	S)
�CompileContextcCs||_g|j_dS)N)�netlink_socket�compiled)�selfr+�r.�J/opt/alt/python37/lib/python3.7/site-packages/pyroute2/netlink/nlsocket.py�__init__�szCompileContext.__init__cCs|S)Nr.)r-r.r.r/�	__enter__�szCompileContext.__enter__cCs|��dS)N)�close)r-�exc_type�	exc_value�	tracebackr.r.r/�__exit__�szCompileContext.__exit__cCsd|j_dS)N)r+r,)r-r.r.r/r2�szCompileContext.closeN)�__name__�
__module__�__qualname__r0r1r6r2r.r.r.r/r*�sr*c@sZeZdZdZiZdZdZdZdZdZ	e
ZeZ
dd�Zdd�Zdd	�Zdd
d�Zdd
�ZdS)�Marshalz#
    Generic marshalling class
    NFcCs&t��|_|j��|_i|_i|_dS)N)�	threading�Lock�lock�msg_map�copy�seq_mapZdefragmentation)r-r.r.r/r0�s
zMarshal.__init__c
CsDd}d}|j�||j�}	||jks2|tkr@|t@r@t||d�}n|	||d�}y|��Wn`tk
r�}
zt	�}|
|dd<Wdd}
~
XYn.t
k
r�}
z|
|dd<Wdd}
~
XYnXt|t��r4|ddk�r4tt
|d�|�d��}t�d||d�d}|j�|t	�}|||dd�}
|
��|
|dd	<||dd<|S)
N)�offset�header�errorrZNLMSGERR_ATTR_MSG�H���errmsg)r>�get�default_message_class�
error_typerrr�decoder$rr!�
isinstancer#�absZget_attr�struct�unpack_from)r-�key�flags�sequence_number�datarA�length�msgrC�	msg_class�eZenc_typeZ	enc_class�encr.r.r/�parse_one_message�s0
zMarshal.parse_one_messagecCs|j�|t|j|||��S)N)r@rHrrY)r-rPrQrRr.r.r/�
get_parser�szMarshal.get_parserc
cs<d}�x0|t|�dk�r6t�d||�\}}}}	|r>|	|kr>qd|krVt|�ksZnP|jdk	r�t�|j|||j�\}|jdk	r�||jM}|�|||	�}
|
|||�}||7}|dkr�qt|�r�||	kr�y||�r�wWntk
r�YnX|d�	dd�}|dk�r$d|k�r$t
�	|d	�|d<|�|�|VqWdS)
z�
        Parse string data.

        At this moment all transport, except of the native
        Netlink is deprecated in this library, so we should
        not support any defragmentation on that level
        r�ZIHHINrB�type)�����event�none)�lenrNrO�
key_format�
key_offset�key_maskrZ�callable�	ExceptionrHr�fix_message)
r-rS�seq�callbackZskip_alien_seqrArTrPrQrR�parserrU�mtyper.r.r/�parse�s:



z
Marshal.parsecCsdS)Nr.)r-rUr.r.r/riszMarshal.fix_message)NNF)r7r8r9�__doc__r>r@rerdrf�debugrrIrrJr0rYrZrnrir.r.r.r/r:�s$
1r:i�T)�minaddr�maxaddr�reversec@s4eZdZdd�Zdd�Zdd�Zdd�Zd	d
�ZdS)�	LockProxycCs*||_d|_||_t��|_|��|_dS)Nr)�factory�refcountrPr;r<�internal�klassr=)r-rurPr.r.r/r0#s

zLockProxy.__init__c	Os*|j�|jd7_|j��SQRXdS)Nr])rwrvr=�acquire)r-�argv�kwargr.r.r/ry*szLockProxy.acquirec	Csd|j�T|jd8_|jdkrP|jdkrPy|jj|j=Wntk
rNYnX|j��SQRXdS)Nr]r)rwrvrPru�locks�KeyErrorr=�release)r-r.r.r/r~/szLockProxy.releasecCs|��dS)N)ry)r-r.r.r/r19szLockProxy.__enter__cCs|��dS)N)r~)r-r3r4r5r.r.r/r6<szLockProxy.__exit__N)r7r8r9r0ryr~r1r6r.r.r.r/rt"s

rtc@s:eZdZejfdd�Zdd�Zdd�Zdd�Zd	d
�Z	dS)�LockFactorycCs||_dt|d�i|_dS)Nr)rxrtr|)r-rxr.r.r/r0AszLockFactory.__init__cCs|jd��dS)Nr)r|ry)r-r.r.r/r1EszLockFactory.__enter__cCs|jd��dS)Nr)r|r~)r-r3r4r5r.r.r/r6HszLockFactory.__exit__cCs0|dkrd}||jkr&t||�|j|<|j|S)Nr)r|rt)r-rPr.r.r/�__getitem__Ks

zLockFactory.__getitem__cCs|j|=dS)N)r|)r-rPr.r.r/�__delitem__RszLockFactory.__delitem__N)
r7r8r9r;�RLockr0r1r6r�r�r.r.r.r/r@s
rc@s�eZdZdd�Zedd��Zedd��Zedd��Zed	d
��Zedd��Z	ed
d��Z
edd��Zedd��Zedd��Z
dS)�
EngineBasecCs0||_d|_d|_t��|_t��|_d|_dS)N�r)	�socket�get_timeout�get_timeout_exceptionr;�Event�
change_masterr<�	read_lockr')r-r�r.r.r/r0Ws

zEngineBase.__init__cCs|jjS)N)r��marshal)r-r.r.r/r�_szEngineBase.marshalcCs|jjS)N)r��backlog)r-r.r.r/r�cszEngineBase.backlogcCs|jjS)N)r��backlog_lock)r-r.r.r/r�gszEngineBase.backlog_lockcCs|jjS)N)r��error_deque)r-r.r.r/r�kszEngineBase.error_dequecCs|jjS)N)r�r=)r-r.r.r/r=oszEngineBase.lockcCs|jjS)N)r��buffer_queue)r-r.r.r/r�sszEngineBase.buffer_queuecCs|jjS)N)r��epid)r-r.r.r/r�wszEngineBase.epidcCs|jjS)N)r��target)r-r.r.r/r�{szEngineBase.targetcCs|jjS)N)r��	callbacks)r-r.r.r/r�szEngineBase.callbacksN)r7r8r9r0�propertyr�r�r�r�r=r�r�r�r�r.r.r.r/r�Vsr�c@s6eZdZdZedddfdd�Zeddddfdd	�ZdS)
�EngineThreadSafez�
    Thread-safe engine for netlink sockets. It buffers all
    incoming messages regardless sequence numbers, and returns
    only messages with requested numbers. This is done using
    synchronization primitives in a quite complicated manner.
    )rrrNcCs�|dkr|j|��z�y�||jkr.g|j|<t|t�sL|jj|}||�}|dkrb|jp`t�	�}||dd<||dd<||dd<||dd<|j
�||�Wn�YnXWd|dkr�|j|��XdS)aR
        Construct a message from a dictionary and send it to
        the socket. Parameters:

            - msg -- the message in the dictionary format
            - msg_type -- the message type
            - msg_flags -- the message flags to use in the request
            - addr -- `sendto()` addr, default `(0, 0)`
            - msg_seq -- sequence number to use
            - msg_pid -- pid to use, if `None` -- use os.getpid()

        Example::

            s = IPRSocket()
            s.bind()
            s.put({'index': 1}, RTM_GETLINK)
            s.get()
            s.close()

        Please notice, that the return value of `s.get()` can be
        not the result of `s.put()`, but any broadcast message.
        To fix that, use `msg_seq` -- the response must contain the
        same `msg['header']['sequence_number']` value.
        rNrBr\rQrR�pid)
r=ryr�rLrr�r>r��os�getpidr��sendto_gater~)r-rU�msg_type�	msg_flags�addr�msg_seq�msg_pidrVr.r.r/�put�s&!


zEngineThreadSafe.putFc
cs�t��}|j|��h|dkr8t�d|�dt��d}n|dkrP|�tt�d}d}d}d}	�z�x�|�s`|j	�
�d}	|dkr�t|j�
��r�x>|j��D]0\}
}|r�x|D]
}|Vq�Wg|j|
<d}Pq�Wqd|dk�r|jd�rx|jdD]
}|Vq�Wg|jd<Pqd|dk�r,t|j�|g���r,x�t|j|�D]�}|j|�|�|d	d
dk	�r�|�s�|j�|j|�|j|=|d	d
�|dk	�r�||�}t|t��r�|V|d	dtk�s�|�r�d}|�s�|d	dt@�s�d}|V|�r<|jd�|j|�|j|=P�q<W|j	��d}	qd|j	��d}	|dk�r�t��||jk�r�|jd�|j|�|j|=|j�r�|���ndS|j�
d��rR�z�|j��|j�|�}
t|jj �!|
||��}t��}|j"�#�}||j#}d}|d
k�rDt$dt%dt&|�d��}d|||f}|dk�r0t'�(|�n
t'�)|�t�*|�||_#|j	��x�|D]�}|j+|d	d<t,|||�|d	d<|d	d}
|
|jk�r�|d	dt-k�r��qXd}
xd|j.D]Z}y(|d|��r�|d|f|d��Wn*t'j)}|d|�|t/�0��YnX�q�W|j|
�1|��qXWWdQRX|j�2�Wd|j��Xqd|j�3d�qdWWd|	�rv|j	��XWdQRXdS)aA
        Get parsed messages list. If `msg_seq` is given, return
        only messages with that `msg['header']['sequence_number']`,
        saving all other messages into `self.backlog`.

        The routine is thread-safe.

        The `bufsize` parameter can be:

            - -1: bufsize will be calculated from the first 4 bytes of
                the network data
            - 0: bufsize will be calculated from SO_RCVBUF sockopt
            - int >= 0: just a bufsize

        If `noraise` is true, error messages will be treated as any
        other message.
        ����Ir`rr^NFTrBrCr\rQ�
r_g{�G�z�?i`�z(Packet burst: delta=%s qsize=%s delay=%sr]r��statsrRzCallback fail: %s)4�timer=rN�unpack�recvr�
getsockoptr	rr�ry�anyr��values�itemsrcrH�tuple�remover��extendrLrrrr~r�r�r�r��clearr�r�rnr�r'�min�max�float�logrp�warning�sleepr�r&rr�r5�
format_exc�append�set�wait)r-�bufsizer��	terminaterk�noraise�ctime�tmsg�enoughZbacklog_acquiredrjr�rUrS�msgs�currentr(r)�message�crZlwr.r.r/rH�s�

	



















 zEngineThreadSafe.get)r7r8r9rorr�rrHr.r.r.r/r��s1r�c@s6eZdZdZedddfdd�Zeddddfdd	�ZdS)
�EngineThreadUnsafez�
    Thread unsafe nlsocket base class. Does not implement any locks
    on message processing. Discards any message if the sequence number
    does not match.
    )rrrNcCstt|t�s|jj|}||�}|dkr4|jp2t��}||dd<||dd<||dd<||dd<|�||�dS)NrBr\rQrRr�)rLrr�r>r�r�r�r�)r-rUr�r�r�r�r�rVr.r.r/r��s	
zEngineThreadUnsafe.putFccs�|dkr"t�d|�dt��d}n|dkr:|�tt�d}d}x�|s�|�|�}t|j�	|||���^}}	x4|D],}
|j
|
dd<tddd�|
dd	<|
VqnW|	dd
tkr�P|dks�|	ddt
@r�t|�r�||	�r�d}|	Vq@WdS)
Nr�r�r`rr^FrBr�r�r\rQT)rNr�r�rr�r	rr�r�rnr�r&rrrg)r-r�r�r�rkr�r�rS�messages�lastrUr.r.r/rH�s(


zEngineThreadUnsafe.get)r7r8r9rorr�rrHr.r.r.r/r��sr�c@s0eZdZdZdZedddddddddddddfdd�Zd	d
�Zdd�Ze	d
ddfdd�Z
eddddfdd�Ze
jfdd�Zdd�Zdd�Zdd�Zdd�dfdd�Zdd�Zd:d d!�Zd"d#�Zd;d$d%�Zd&d'�Zd(d)�Zd<d*d+�Zd,d-�Zd.d/�Zd0d1�Zd=d2d3�Zd4d5�Zd>d6d7�Z e	e!Bdddfd8d9�Z"dS)?�NetlinkSocketBasez!
    Generic netlink socket.
    FNi�	localhostrcs|||||||||
|	|||
|d��_tddd��_d�_d�_d�_|�_|�_|�_|�_	d�_
dgi�_tj
dd��_g�_d�_d	�_d�_tj�_|
�_|
�_tjd
ddgktjd
ddgkdtjddkd��_t���_t���_t��_d�_t �!�\�_"�_#|dk�rtj$}|�_$|	dk�r0tj%}	|	�_%t&|d
��_'g�_(|�_)|�_*|�_+|dk�r�t �,�d@�_-|�_�jdk	�_n|dk�r�t �,��_-n|�_-t.��_/|	�s��fdd�}�fdd�}�j0�_1�j2�_3|�_0|�_2�fdd�}�j4�_5|�_4��6�t7���_8dS)N)�family�portr��fileno�sndbuf�rcvbuf�all_ns�async_qsizer��
nlm_generator�ext_ack�strict_check�groups�nlm_echo�i��)rqrrrTi�)�maxlenFr_r^)Z
create_bridgeZcreate_bondZcreate_dummyZprovide_master)�maxsizei��?cst�j||��S)N)r��_genlm_request)rzr{)r-r.r/�nlm_requestesz/NetlinkSocketBase.__init__.<locals>.nlm_requestcst�j||��S)N)r��
_genlm_get)rzr{)r-r.r/rHhsz'NetlinkSocketBase.__init__.<locals>.getcst�j||��S)N)r��_genlm_request_batch)rzr{)r-r.r/�nlm_request_batchqsz5NetlinkSocketBase.__init__.<locals>.nlm_request_batch)9r
r�	addr_poolr�r��fixedr��_fileno�_sndbuf�_rcvbuf�	_use_peekr��collections�dequer�r��
buffer_thread�closedr,�unamer�r��kernelZcapabilitiesr;r<r�r��sys_lockrr=�_sockr��pipe�
_ctrl_read�_ctrl_writer�r�r%r�r�r�r�r�r�r�r:r�r�r�rHr�r�r��	post_initr��engine)r-r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rHr�r.)r-r/r0
s�







zNetlinkSocketBase.__init__cCsdS)Nr.)r-r.r.r/r�{szNetlinkSocketBase.post_initcCst|�f|j�S)N)r\r
)r-r.r.r/�clone~szNetlinkSocketBase.clone�rrcCs|j�||||||�S)N)r�r�)r-rUr�r�r�r�r�r.r.r/r��s	zNetlinkSocketBase.putcCs|j�|||||�S)N)r�rH)r-r�r�r�rkr�r.r.r/rH�szNetlinkSocketBase.getcCsd|dkr.|jr.|j�t�ddddd|dd��yt�|j�t�|j�Wnt	k
r^YnXdS)NrZIHHQIQQ�r^)
�input_from_buffer_queuer�r�rN�packr�r2r�r��OSError)r-�coder.r.r/r2�szNetlinkSocketBase.closecCs|S)Nr.)r-r.r.r/r1�szNetlinkSocketBase.__enter__cCs|��dS)N)r2)r-r3r4r5r.r.r/r6�szNetlinkSocketBase.__exit__cCst�dt�|��dS)Nzdeprecated, use close() instead)�warnings�warn�DeprecationWarningr2)r-r.r.r/r~�szNetlinkSocketBase.releasecCsdS)NTr.)�xr.r.r/�<lambda>��zNetlinkSocketBase.<lambda>cCs"|dkrg}|j�|||f�dS)a�
        Register a callback to run on a message arrival.

        Callback is the function that will be called with the
        message as the first argument. Predicate is the optional
        callable object, that returns True or False. Upon True,
        the callback will be called. Upon False it will not.
        Args is a list or tuple of arguments.

        Simplest example, assume ipr is the IPRoute() instance::

            # create a simplest callback that will print messages
            def cb(msg):
                print(msg)

            # register callback for any message:
            ipr.register_callback(cb)

        More complex example, with filtering::

            # Set object's attribute after the message key
            def cb(msg, obj):
                obj.some_attr = msg["some key"]

            # Register the callback only for the loopback device, index 1:
            ipr.register_callback(cb,
                                  lambda x: x.get('index', None) == 1,
                                  (self, ))

        Please note: you do **not** need to register the default 0 queue
        to invoke callbacks on broadcast messages. Callbacks are
        iterated **before** messages get enqueued.
        N)r�r�)r-rk�	predicate�argsr.r.r/�register_callback�s"z#NetlinkSocketBase.register_callbackcCs>t|j�}x.|D]&}|d|kr|j�|�|��dSqWdS)z_
        Remove the first reference to the function from the callback
        register
        r]N)r�r��pop�index)r-rk�cbr�r.r.r/�unregister_callback�s


z%NetlinkSocketBase.unregister_callbackcCsRt|t�r|dk	r||i}t|t�s,td��x|D]}|||jj|<q2W|jjS)a�
        Register netlink encoding/decoding policy. Can
        be specified in two ways:
        `nlsocket.register_policy(MSG_ID, msg_class)`
        to register one particular rule, or
        `nlsocket.register_policy({MSG_ID1: msg_class})`
        to register several rules at once.
        E.g.::

            policy = {RTM_NEWLINK: ifinfmsg,
                      RTM_DELLINK: ifinfmsg,
                      RTM_NEWADDR: ifaddrmsg,
                      RTM_DELADDR: ifaddrmsg}
            nlsocket.register_policy(policy)

        One can call `register_policy()` as many times,
        as one want to -- it will just extend the current
        policy scheme, not replace it.
        Nzwrong policy type)rL�int�dict�	TypeErrorr�r>)r-�policyrVrPr.r.r/�register_policy�s

z!NetlinkSocketBase.register_policycCs\t|t�r|g}nt|t�r$t|�}t|tttf�s<td��x|D]}|jj|=qBW|jjS)a�
        Unregister policy. Policy can be:

            - int -- then it will just remove one policy
            - list or tuple of ints -- remove all given
            - dict -- remove policies by keys from dict

        In the last case the routine will ignore dict values,
        it is implemented so just to make it compatible with
        `get_policy_map()` return value.
        zwrong policy type)	rLrr�listr�r�rr�r>)r-rrPr.r.r/�unregister_policy�s


z#NetlinkSocketBase.unregister_policycCs^|dkr|jjSt|t�r |g}t|tttf�s8td��i}x|D]}|jj|||<qBW|S)z�
        Return policy for a given message type or for all
        message types. Policy parameter can be either int,
        or a list of ints. Always return dictionary.
        Nzwrong policy type)r�r>rLrrr�r�r)r-r�retrPr.r.r/�get_policy_maps

z NetlinkSocketBase.get_policy_mapcCsTt�}y|�|dttBtB�\}}Wn*tk
rNd|_|�tt	�d}YnX|S)NrFr^)
�	bytearray�
recvfrom_intorrr�BlockingIOErrorr�r�r	r)r-Zsocket_descriptorrSr��_r.r.r/�
_peek_bufsize+szNetlinkSocketBase._peek_bufsizecOs|j||�S)N)�_sendto)r-rzr{r.r.r/�sendto6szNetlinkSocketBase.sendtocCsB|jr"|j��}t|t�r|�|S|j�|jr:|�|j�n||�S)N)	r�r�rHrLrhr�r�r�r)r-r�rQ�data_inr.r.r/r�9s

zNetlinkSocketBase.recvcOsF|jr2|j��}t|t�r|�||dd�<t|�S|jj|f|�|�S)N)r�r�rHrLrhrcr��	recv_into)r-rSrzr{rr.r.r/rDs

zNetlinkSocketBase.recv_intocCs�t��}|�|jtjtjB�|�|jtjtjB�|j��}x�|��}xt|D]l\}}||kr�y&td�}|j�	|d�|j
�|�Wq�tk
r�}z|j
�
|�dSd}~XYq�XqNdSqNWq@WdS)Ni�)�select�poll�registerr��POLLIN�POLLPRIr�r�rrr��
put_nowaitrhr�)r-rZsockfd�events�fdrarSrWr.r.r/�buffer_thread_routineMs 
z'NetlinkSocketBase.buffer_thread_routinecCst|�S)N)r*)r-r.r.r/�compile`szNetlinkSocketBase.compilec	Cs�|j�&x|D]}g|j|dd<qWWdQRXt�}xL|D]D}t|t�sh|jj|dd}||�}|��|��||j	7}q>W|j
dk	r�|j
�|�S|j�
||�dS)NrBrRr\)r�r�rrLrr�r>�reset�encoderSr,r�r�r)r-r�r�rUrSrVr.r.r/�_send_batchcs
 


zNetlinkSocketBase._send_batchcCs8|��|��|jdk	r(|j�|j�S|j�|j|�S)N)rrr,r�rSr�r)r-rUr�r.r.r/r�ts

zNetlinkSocketBase.sendto_gatec	cs�g}d}|j�t|��}�zx"|D]}|j|��|d7}q"Wxnt||�D]`\}}||dd<d|dkr�|jpxt��|dd<|ddt	@s�|ddt
@rL|�|�qLW|�|�|j
dk	r�xZ|j
D]
}|Vq�WnDxB|D]:}x4|j||d�D]"}|ddt@�rt��|Vq�Wq�WWdx*||ddd	�D]}|j|���q8W|j�:x2|D]*}||jk�rv|j|=|jj|d
d��q^WWdQRXXdS)z�
        This function is for messages which are expected to have side effects.
        Do not blindly retry in case of errors as this might duplicate them.
        rr]rBrRr�rQN)r�r�r�r�)�ban)r�Zalloc_multircr=ry�zipr�r�r�rrr�r r,rHrr"r~r�r��free)	r-r�r�Zexpected_responsesZacquiredZseqsrjrUrSr.r.r/r�{s<




z#NetlinkSocketBase.nlm_request_batchccsz|j��}d}t|�r"||jj|<|j|��Bd}	z�x�yx|j||||d�|jdk	rnxT|jD]
}
|
Vq^Wn>x<|j|||d�D](}|dkr�|ddt	@r�t
�}|Vq�WPWq8tk
�r}z@|jt
jkr҂|	dkr܂t�d�|	��t�d�|	d	7}	w8Wdd}~XYq8tk
�r&�Yq8Xq8WWd|jj|d
d�||jjk�r\|jj�|�X|dk	�rl|�WdQRXdS)Nr)r�)r�r�rkrBrQr�zError 16, retry {}.g333333�?r]r�)r!)r��allocrgr�r@r=r�r,rHrr"r#r��errnoZEBUSYr�r��formatr�r�rhr#r�)r-rUr�r�r�rkrlr��deferZretry_countrSrWr.r.r/r��sN	





zNetlinkSocketBase.nlm_request)N)N)r)r�)F)#r7r8r9ror�rr0r�r�rr�rrHr%�
ECONNRESETr2r1r6r~r�rrrr
rrr�rrrr r�r�rr�r.r.r.r/r�sb_&


	

0r�c@seZdZdd�Zdd�ZdS)�
BatchAddrPoolcOsdS)Nrr.)r-rzr{r.r.r/r$�szBatchAddrPool.alloccOsdS)Nr.)r-rzr{r.r.r/r#�szBatchAddrPool.freeN)r7r8r9r$r#r.r.r.r/r)�sr)c@seZdZdd�Zdd�ZdS)�BatchBacklogQueuecOsdS)Nr.)r-rzr{r.r.r/r��szBatchBacklogQueue.appendcOsdS)Nr.)r-rzr{r.r.r/r��szBatchBacklogQueue.popN)r7r8r9r�r�r.r.r.r/r*�sr*c@s$eZdZdd�Zdd�Zdd�ZdS)�BatchBacklogcCst�S)N)r*)r-rPr.r.r/r��szBatchBacklog.__getitem__cCsdS)Nr.)r-rP�valuer.r.r/�__setitem__szBatchBacklog.__setitem__cCsdS)Nr.)r-rPr.r.r/r�szBatchBacklog.__delitem__N)r7r8r9r�r-r�r.r.r.r/r+�sr+c@s8eZdZdd�Zdd�ZeeBddfdd�Zdd	�ZdS)
�BatchSocketcCs"t�|_t�|_d|_|��dS)N)r+r�r)r�r�r)r-r.r.r/r�szBatchSocket.post_initcCst�|_dS)N)r�batch)r-r.r.r/rszBatchSocket.resetNcCsh|j��}|jpt��}||dd<||dd<||dd<||dd<|j|_t|j�|_|�	�gS)NrBr\rQrRr�)
r�r$r�r�r�r/rSrcrAr)r-rUr�r�r�rkr�r�r.r.r/r�s
zBatchSocket.nlm_requestcOsdS)Nr.)r-rzr{r.r.r/rH%szBatchSocket.get)	r7r8r9r�rrrr�rHr.r.r.r/r.sr.csLeZdZdd�Zdd�Zddd�Zd	d
�Zdd�Zej	f�fd
d�	Z
�ZS)�
NetlinkSocketc	Cs�|j��|jdk	r|j��t�tt|j|j�|_|�	t
t|j�|�	t
t
|j�|jrf|�	ttd�|jrz|�	ttd�|jr�|�	ttd�WdQRXdS)Nr])r�r�r2r
Z
SocketBaser
rr�r��
setsockoptr	rr�rr�r�rrr�rr�r)r-r.r.r/r�*s

zNetlinkSocket.post_initcCs:|dkrt|j|�S|dkr.t|j|�d��St|��dS)N)�getsocknamer��makefiler1�setblocking�
settimeout�
gettimeout�shutdown�recvfromrr�)rZ_recvZ
_recv_intor)�getattrr��lstrip�AttributeError)r-�attrr.r.r/�__getattr__;szNetlinkSocket.__getattr__rNc	Ks|dk	r"d|_d|_|pt��|_d|kr4t�d�|�d�pF|�d�}||_|jr||j|jd>|_	|j
�|j	|jf�njxhtd�D]T}y2||_|j|jd>|_	|j
�|j	|jf�PWq�t
k
r�|��Yq�Xq�Wtd	��|�rtjd
|jd�|_d|_d|j_|j��dS)z�
        Bind the socket to given multicast groups, using
        given pid.

            - If pid is None, use automatic port allocation
            - If pid == 0, use process' pid
            - If pid == <int>, use the value instead of pid
        NrT�asynczJuse "async_cache" instead of "async", "async" is a keyword from Python 3.7�async_cache�izno free address availablezNetlink async cache)�namer�)r�r�r�r�r�r�r�rHr�r�r��bind�rangerhr�r}r;�Threadrr�r��daemon�start)r-r�r�r{r?r�r.r.r/rBOs6	zNetlinkSocket.bindcCs|�tt|�dS)N)r1rr)r-�groupr.r.r/�add_membership�szNetlinkSocket.add_membershipcCs|�tt|�dS)N)r1rr)r-rGr.r.r/�drop_membership�szNetlinkSocket.drop_membershipc	s`|j�|jrdSd|_WdQRX|jr@t�|jd�|j��tt|�j	|d�|j
�	�dS)zD
        Correctly close the socket and free all resources.
        NTsexit)r�)r�r�r�r��writer��join�superr0r2r�)r-r�)�	__class__r.r/r2�s
zNetlinkSocket.close)rN)r7r8r9r�r=rBrHrIr%r(r2�
__classcell__r.r.)rMr/r0)s
3r0cs,eZdZdZ�fdd�Z�fdd�Z�ZS)�ChaoticNetlinkSocketr]cs$|�dd�|_tt|�j||�dS)N�success_rategffffff�?)r�rPrLrOr0)r-rzr{)rMr.r/r0�szChaoticNetlinkSocket.__init__cs&t��|jkrt��tt|�j||�S)N)�randomrPr rLrOrH)r-rzr{)rMr.r/rH�szChaoticNetlinkSocket.get)r7r8r9rPr0rHrNr.r.)rMr/rO�srO)Pror�r%�loggingr�rQrrNr;r�r5r��	functoolsrr�rrrrrrr	Zpyroute2r
Zpyroute2.commonrrZpyroute2.configr
Zpyroute2.netlinkrrrrrrrrrrrrrrrrrrZpyroute2.netlink.exceptionsr r!r"r#r$r%�ImportError�queue�	getLoggerr7r��
namedtupler&Z
NL_BUFSIZEr*r:Zsocketsrtrr�r�r�r�r)rr*rr+r.r0rOr.r.r.r/�<module>QsZ$
P
|.D@i"q