o
    y.e.                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Zzd dl
Z
W n ey5   dZ
Y nw ejdkrEd dlmZ d dlZejdZdd Zdd Zd"d	d
Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdadd Zdd Zdd Zd d! Z dS )#    Nwin32socket_utilc                 C   s   | d u rd S t j| } t j| }t dd}tddD ]I}d|tdd|f }zt || t	j
| t j|t j| W   S  tyf } z|jtjkr\W Y d }~ tdW Y d }~qd }~ww td)NTMPDIRz/tmpr   i  z%s/ovs-un-py-%d-%di'  z"Failed to create temporary symlink)ospathabspathdirnamegetenvrangerandomrandintsymlinkovsfatal_signaladd_file_to_unlinkjoinbasenameOSErrorerrnoEEXIST	Exception)	long_namelong_dirnametmpdirx	link_namee r   1/usr/lib/python3/dist-packages/ovs/socket_util.pymake_short_name&   s(   r   c                 C   s(   | d u rd S t j| }tj| d S )N)r   r   r   r   r   unlink_file_now)
short_namer   r   r   r   free_short_name9   s   r"   Fc                 C   s  z	t  t j| }W n t jy" } zt|dfW  Y d}~S d}~ww z|r*t| |duryzt| W n$ tyY } z|jtj	krO|jdfW  Y d}~W S W Y d}~nd}~ww t
j| || z
t| d W n	 tyx   Y nw |durz|| W n t jy } zt|tjkr W Y d}~nd}~ww d|fW S  t jy } zY|  |durtj|rt
j| t
j|}|dkrt d dkrd}d}	d}
d}|dur"tj|}tj|}zt|tjtjB }
W n ty } zt|dfW  Y d}~W  Y d}~S d}~ww d|
|f }|duretj|}tj|}zt|tjtjB }W n ty^ } zt|dfW  Y d}~W  Y d}~S d}~ww d||f }	z)t| ||	|W |
durwt|
 |durt| W  Y d}~S W  Y d}~S |
durt|
 |durt| w w |dkr|rt|dfW  Y d}~S d}	z
t|}	t|}W n   t|	 tj df Y W  Y d}~S zt| ||	|ddW t|	 t| W  Y d}~S t|	 t| w t|dfW  Y d}~S d}~ww )	a  Creates a Unix domain socket in the given 'style' (either
    socket.SOCK_DGRAM or socket.SOCK_STREAM) that is bound to 'bind_path' (if
    'bind_path' is not None) and connected to 'connect_path' (if 'connect_path'
    is not None).  If 'nonblock' is true, the socket is made non-blocking.

    Returns (error, socket): on success 'error' is 0 and 'socket' is a new
    socket object, on failure 'error' is a positive errno value and 'socket' is
    None.Ni  r   zAF_UNIX path too longLinuxz/proc/self/fd/%d/%sT)short)!socketAF_UNIXerrorget_exception_errnoset_nonblockingr   unlinkr   r   ENOENTr   r   r   bindfchmodfilenoconnectEINPROGRESScloser   existsr    r   unamer   r   openO_DIRECTORYO_RDONLYmake_unix_socketr   r"   ENAMETOOLONG)stylenonblock	bind_pathconnect_pathr$   sockr   enoshort_connect_pathshort_bind_pathconnect_dirfd
bind_dirfdr   r   errr   r   r   r7   @   s   






$
$







r7   c              
   C   s$  t jdkr)tj }td ddd }t| |tj	tj
B tjB  ||tjj ntj }|| tjj |d}t|dkr|d d }|tjj@ sS|tjj@ rz"trdt| tjrd| d  n	| d tj td tjW S  tjy } z
t|W  Y d }~S d }~ww dS tj S )Nr   FTr       z&poll return POLLERR but send succeeded)!sysplatformr   poller
SelectPollwinutilsget_new_event	win32fileWSAEventSelectFD_WRITE
FD_CONNECTFD_CLOSEregisterPOLLOUTget_system_pollpolllenPOLLERRPOLLHUPssl
isinstance	SSLSocketsendencoder%   MSG_DONTWAITvlogrC   r   EPROTOr'   r(   EAGAIN)r=   peventpfdsreventsr   r   r   r   check_connection_completion   s:   




re   c                 C   sd   z
t t j|  W dS  ty'   z	t |  W Y dS  t jy&   Y Y dS w  t jy1   Y dS w )NFT)r%   	inet_ptonAF_INETAttributeError	inet_atonr'   )addressr   r   r   is_valid_ipv4_address   s   	rk   c                 C   sx   |  d}t|dkr!d|dd dd}t|d }n|r&|}ntd|  |d }|s8td|  ||fS )	N:   r   []z!%s: port number must be specifiedz%s: bad peer name format)splitrU   r   lstriprstripint
ValueError)targetdefault_portrj   	host_nameportr   r   r   inet_parse_active   s   
rz   c              
   C   s   z)t |d }|rttj| d}tj}nttj| d}tj}W ||fS W ||fS  tjyB } zt|d fW  Y d }~S d }~ww Nr   )rk   r%   rg   AF_INET6r'   r(   )r9   rj   is_addr_inetr=   familyr   r   r   r   inet_create_socket_active   s   r   c              
   C   s|   z"t |  t| || | |}|dtjtjfvr |   |W S W dS  tjy= } z|   t	|W  Y d }~S d }~ww r{   )
r)   set_dscp
connect_exr   r0   EWOULDBLOCKr1   r%   r'   r(   )r=   rj   r~   dscpr'   r   r   r   r   inet_connect_active   s   
r   c                 C   sJ   t ||}t| |\}}|d u r||fS t||||}|r!|d fS d|fS r{   )rz   r   r   )r9   rv   rw   r   rj   r~   r=   r'   r   r   r   inet_open_active  s   
r   c                 C   s   t | jtr| jd S tjS )zA lot of methods on Python socket objects raise socket.error, but that
    exception is documented as having two completely different forms of
    arguments: either a string or a (errno, string) tuple.  We only want the
    errno.r   )rY   argstupler   r_   r   r   r   r   r(     s   
r(   rn   c               
   C   sl   t dk r4zttjtja W t S  ty3 }  ztdtjt| j	f  | j	 W  Y d} ~ S d} ~ ww t S )zReturns a readable and writable fd for /dev/null, if successful,
    otherwise a negative errno value.  The caller must not close the returned
    fd (because the same fd will be handed out to subsequent callers).r   zcould not open %s: %sN)
null_fdr   r4   devnullO_RDWRr   r^   rC   strerrorr   r   r   r   r   get_null_fd!  s   

r   c              
   C   s   d}t |dkr
dS t|tst|d}	 z6t| |}|dks"J |t |kr1d|t | fW S |dkr@td tj|fW S ||7 }|d| }W n t	yb } z|j|fW  Y d}~S d}~ww q)a  Returns an (error, bytes_written) tuple where 'error' is 0 on success,
    otherwise a positive errno value, and 'bytes_written' is the number of
    bytes that were written before the error occurred.  'error' is 0 if and
    only if 'bytes_written' is len(buf).r   )r   r   zutf-8Tzwrite returned 0N)
rU   rY   bytesr   writer^   warnr   r_   r   )fdbufbytes_writtenretvalr   r   r   r   write_fully2  s*   


r   c              
   C   sR   z|  d W d S  tjy( } ztdtt|  W Y d }~d S d }~ww )Nr   z,could not set nonblocking mode on socket: %s)setblockingr%   r'   r^   rC   r   r   r(   )r=   r   r   r   r   r)   L  s   r)   c                 C   sh   |dkr
t d| |d> }|tjkr| tjtj| d S |tjkr.| tjtj| d S t d| )N?   zInvalid dscp %drm   zInvalid family %d)	ru   r%   rg   
setsockopt
IPPROTO_IPIP_TOSr|   IPPROTO_IPV6IPV6_TCLASS)r=   r~   r   valr   r   r   r   T  s   

r   )F)!r   r   os.pathr   r%   rF   ovs.fatal_signalr   
ovs.pollerovs.vlogrX   ImportErrorrG   ovs.winutilsrJ   rL   r^   Vlogr   r"   r7   re   rk   rz   r   r   r   r(   r   r   r   r)   r   r   r   r   r   <module>   sB   

f'