U
    °®•_­  ã                   @   s²   d Z ddlZddlmZmZmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlZddlZddlZddlZddlmZmZ ddlZe d¡ZG dd	„ d	eƒZedd
œdd„ZdS )z
Inter-bridge links.
é    N)ÚProtoÚMessageÚOutPortÚConfigÚChannelÚServiceMessageÚJoinMessageÚPartMessage)ÚBridge)ÚTuple)ÚStreamReaderÚStreamWriterÚlinkc                   @   sD   e Zd Zeeeddœdd„Zeeddœdd„Z	e
eddœd	d
„ZdS )ÚLinkN)ÚbridgeÚout_portÚinstance_cfgÚreturnc              
   Ã   sV  t  d¡ || _|| _|| _|d }| d¡\| _| _t| jƒ| _|d }| d¡\| _	| _
t| j
ƒ| _
zžt  d¡ t ¡ | _| j tjtjd¡ | j tjtjd¡ | j | j	| j
f¡ | j d¡ | j | j| jf¡ tj| jdI d H \}}t |  ||¡¡ W nJ tjttfk
rP   t  d	¡ tj| j| j	| j
d
d
dI d H | _Y nX d S )Nzstarting link...Úremoteú:Úlocalz"trying to connect to remote host..é   é
   )Úsockz?timed out waiting to connect to remote host, starting server...T)ÚhostÚportÚreuse_addressÚ
reuse_port)ÚloggerÚinfor   r   r   ÚsplitÚremote_hostZremote_portÚintZ
local_hostZ
local_portÚsocketÚ_sockÚ
setsockoptÚ
SOL_SOCKETÚSO_REUSEADDRÚSO_REUSEPORTÚbindÚ
settimeoutÚconnectÚasyncioÚopen_connectionÚcreate_taskÚhandle_connectionÚtimeoutÚConnectionRefusedErrorÚOSErrorÚstart_serverÚserver)Úselfr   r   r   r   r   ÚreaderÚwriter© r8   ú/opt/tsbridge/plugins/link.pyÚstart   s.    



z
Link.start)r6   r7   r   c              
   Ã   s  t  d||f› ¡ || | _| _zht  d¡ t d| j d¡I d H ¡^}}t  d|› ¡ t | j |¡I d H ¡}| j	 
|¡I d H  q$W n| tjk
r   t  d¡ t| dƒrÎ| j ¡  | j ¡ I d H  n| j ¡  | j ¡ I d H  t |  | j| j	| j¡¡ Y nX d S )Nzreceived connection: z
reading...ú!Ié   z
got size: z@read was incomplete, assuming other end died. restarting link...r4   )r   r   r6   r7   ÚstructÚunpackÚreadexactlyÚpickleÚloadsr   Úput_messager,   ÚIncompleteReadErrorÚhasattrr4   ÚcloseÚwait_closedr.   r:   r   r   )r5   r6   r7   ÚsizeÚ_Úpayloadr8   r8   r9   r/   .   s     




zLink.handle_connection)Ú
to_channelÚmessager   c                 Ã   sZ   t  d|› ¡ t |¡}t|ƒ}t d|¡}| j |¡ | j |¡ | j 	¡ I d H  d S )NzSending message r;   )
r   r   r@   ÚdumpsÚlenr=   Úpackr7   ÚwriteÚdrain)r5   rJ   rK   ÚdatarG   Zsize_encodedr8   r8   r9   Úsend_messageC   s    
zLink.send_message)Ú__name__Ú
__module__Ú__qualname__r
   r   r   r:   r   r   r/   r   r   rR   r8   r8   r8   r9   r      s   r   )r   r   c                 C   s   |   dt¡ d S )Nr   )Úadd_protocolr   )r   r8   r8   r9   ÚinitL   s    rW   )Ú__doc__Ú
core.typesÚcorer   r   r   r   r   r   r   r	   Úcore.bridger
   Útypingr   r=   r@   Úloggingr,   r   r   r#   Ú	getLoggerr   r   rW   r8   r8   r8   r9   Ú<module>   s   (
;