
>Mc           @   s$  d  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 m	 Z	 m
 Z
 m Z m Z m Z d d l m Z d d l m Z m Z d d l m Z m Z m Z m Z d d l m Z m Z d d	 l m Z d d
 l m  Z  d d l m! Z! d d l m" Z" d d l m# Z# d d l m$ Z$ y d d l% m& Z& m' Z' Wn! e( k
 rod Z' Z& d Z* n Xe	 j+ f Z* i e j, e# 6e j- e$ 6Z. d e/ f d     YZ0 d e j1 e f d     YZ2 d e2 f d     YZ3 d e2 f d     YZ4 d e f d     YZ d e f d     YZ5 d S(   s   
TCP support for IOCP reactor
iN(   t
   implementst   directlyProvides(   t
   interfacest   errort   addresst   maint   defer(   t   isIPAddress(   t   _SocketClosert	   Connector(   t   logt   failuret   reflectt   util(   t   iocpsupportt   abstract(   t   IReadWriteHandle(   t   ERROR_IO_PENDING(   t   SO_UPDATE_CONNECT_CONTEXT(   t   SO_UPDATE_ACCEPT_CONTEXT(   t   ERROR_CONNECTION_REFUSED(   t   ERROR_NETWORK_UNREACHABLE(   t   TLSMemoryBIOFactoryt   TLSMemoryBIOProtocolt
   _BypassTLSc           B   s>   e  Z d  Z d   Z d   Z d   Z d   Z d d  Z RS(   s0  
    L{_BypassTLS} is used as the transport object for the TLS protocol object
    used to implement C{startTLS}.  Its methods skip any TLS logic which
    C{startTLS} enables.

    @ivar _connection: A L{Connection} which TLS has been started on which will
        be proxied to by this object.  Any method which has its behavior
        altered after C{startTLS} will be skipped in favor of the base class's
        implementation.  This allows the TLS protocol object to have direct
        access to the transport, necessary to actually implement TLS.
    c         C   s   | |  _  d  S(   N(   t   _connection(   t   selft
   connection(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   __init__4   s    c         C   s   t  |  j |  S(   N(   t   getattrR   (   R   t   name(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   __getattr__8   s    c         C   s   t  j j |  j |  S(   N(   R   t
   FileHandlet   writeR   (   R   t   data(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR!   <   s    c         C   s   t  j j |  j |  S(   N(   R   R    t   writeSequenceR   (   R   t   iovec(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR#   @   s    c         C   s   t  j j |  j |  S(   N(   R   R    t   loseConnectionR   (   R   t   reason(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR%   D   s    N(	   t   __name__t
   __module__t   __doc__R   R   R!   R#   t   NoneR%   (    (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR   (   s   				t
   Connectionc           B   s   e  Z d  Z e e e j e j e  e	 Z
 d 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 e d k	 r e d  Z n  d   Z d   Z d d  Z RS(   s  
    @ivar _tls: C{False} to indicate the connection is in normal TCP mode,
        C{True} to indicate that TLS has been started and that operations must
        be routed through the L{TLSMemoryBIOProtocol} instance.

    @ivar _tlsClientDefault: A flag which must be set by a subclass.  If set to
        C{True}, L{startTLS} will default to initiating SSL as a client.  If
        set to C{False}, L{startTLS} will default to initiating SSL as a
        server.
    c         C   s5   t  j j |  |  | |  _ | j |  _ | |  _ d  S(   N(   R   R    R   t   sockett   filenot   getFileHandlet   protocol(   R   t   sockt   protot   reactor(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR   Y   s    	c         C   s   |  j  S(   N(   R,   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt	   getHandle`   s    c         C   s   |  j  j t |   d  S(   N(   R/   t   dataReceivedt   str(   R   t   rbuffer(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR4   d   s    c         C   s   t  j |  j   | |  S(   N(   t   _iocpt   recvR.   (   R   t   bufflistt   evt(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   readFromHandlei   s    c         C   s(   t  j |  j   t | d |  j  |  S(   s   
        Send C{buff} to current file handle using C{_iocp.send}. The buffer
        sent is limited to a size of C{self.SEND_LIMIT}.
        i    (   R7   t   sendR.   t   buffert
   SEND_LIMIT(   R   t   buffR:   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   writeToHandlem   s    c         C   s   y t  |  j |  j  d  Wn t j k
 r3 n Xt j |  j d   } | r y | j   Wq t	 j
   } t j   |  j |  q Xn  d  S(   Ni   (   R   R,   t   _socketShutdownMethodR   R   t   IHalfCloseableProtocolR/   R*   t   writeConnectionLostR   t   FailureR
   t   errt   connectionLost(   R   t   pt   f(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   _closeWriteConnectionv   s    
c         C   sd   t  j |  j d   } | rS y | j   Wq` t j   |  j t j	    q` Xn |  j |  d  S(   N(
   R   RB   R/   R*   t   readConnectionLostR
   RE   RF   R   RD   (   R   R&   RG   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyRJ      s    
c         C   sI   t  j j |  |  |  j   |  j } |  ` |  ` |  ` | j |  d  S(   N(   R   R    RF   t   _closeSocketR/   R,   R.   (   R   R&   R/   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyRF      s    
	c         C   s   |  j  S(   sN   
        Return the prefix to log with when I own the logging thread.
        (   t   logstr(   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt	   logPrefix   s    c         C   s"   t  j |  j j t j t j   S(   N(   t   operatort   truthR,   t
   getsockoptt   IPPROTO_TCPt   TCP_NODELAY(   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   getTcpNoDelay   s    c         C   s    |  j  j t  j t  j |  d  S(   N(   R,   t
   setsockoptRQ   RR   (   R   t   enabled(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   setTcpNoDelay   s    c         C   s"   t  j |  j j t j t j   S(   N(   RN   RO   R,   RP   t
   SOL_SOCKETt   SO_KEEPALIVE(   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   getTcpKeepAlive   s    c         C   s    |  j  j t  j t  j |  d  S(   N(   R,   RT   RW   RX   (   R   RU   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   setTcpKeepAlive   s    c         C   s   | r |  j  } n
 |  j  } t | | d  } t | |  j t  } | |  _ | j |  _ | j |  _ t |  t	 j
  t |  _ |  j j t |    d S(   s9   
            @see: L{ITLSTransport.startTLS}
            N(   t   _tlsClientDefaultR   R*   R   R/   t   FalseR3   t   getPeerCertificateR   R   t   ISSLTransportt   Truet   _tlst   makeConnectionR   (   R   t   contextFactoryt   normalt   clientt
   tlsFactoryt   tlsProtocol(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   startTLS   s    
		c         C   s3   |  j  r |  j j |  n t j j |  |  d S(   s   
        Write some data, either directly to the underlying handle or, if TLS
        has been started, to the L{TLSMemoryBIOProtocol} for it to encrypt and
        send.

        @see: L{ITCPTransport.write}
        N(   R`   R/   R!   R   R    (   R   R"   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR!      s    	c         C   s3   |  j  r |  j j |  n t j j |  |  d S(   s   
        Write some data, either directly to the underlying handle or, if TLS
        has been started, to the L{TLSMemoryBIOProtocol} for it to encrypt and
        send.

        @see: L{ITCPTransport.writeSequence}
        N(   R`   R/   R#   R   R    (   R   R$   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR#      s    	c         C   sF   |  j  r/ |  j rB |  j rB |  j j   qB n t j j |  |  d S(   s   
        Close the underlying handle or, if TLS has been started, first shut it
        down.

        @see: L{ITCPTransport.loseConnection}
        N(   R`   t	   connectedt   disconnectingR/   R%   R   R    (   R   R&   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR%      s    	N(   R'   R(   R)   R    R   R   t   ITCPTransportt   ISystemHandlet   _extraInterfacesR\   R`   R*   R   R3   R4   R;   R@   RI   RJ   RF   RM   RS   RV   RY   RZ   R   R_   Rg   R!   R#   R%   (    (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR+   I   s,   
								
							t   Clientc           B   s   e  Z e j Z e j Z e Z d    Z	 d   Z
 d   Z d   Z d   Z d   Z d   Z d   Z d   Z d	   Z d
   Z RS(   c   	      C   s2  | |  _  | | f |  _ | |  _ | d  k r6 d } n  y y | j |  j |  j  } Wn0 t j k
 r } t j	 | d | d   nw Xy | j
 |  Wn0 t j k
 r } t j	 | d | d   n X| |  _ t j |  | d  |  | j d |  j  Wn, t j	 k
 r-} | j d |  j |  n Xd  S(   Nt    i    i   (   Rn   i    (   t	   connectort   addrR2   R*   t   createSockett   addressFamilyt
   socketTypeR,   R   t   ConnectBindErrort   bindR+   R   t	   callLatert   resolveAddresst   failIfNotConnected(	   R   t   hostt   portt   bindAddressRo   R2   t   sktt   seRE   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s&    				c         C   s]   t  |  j d  r* |  j |  j d  n/ |  j j |  j d  } | j |  j |  j  d  S(   Ni    (   R   Rp   t   _setRealAddressR2   t   resolvet   addCallbacksRx   (   R   t   d(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyRw     s    c         C   s$   | |  j  d f |  _ |  j   d  S(   Ni   (   Rp   t   realAddresst	   doConnect(   R   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR~   &  s    c         C   s   |  j  s" |  j s" t |  d  r& d  Sy |  j   Wn t k
 rG n X|  ` |  ` |  j j |   |  j	 j
 t j |   |  `	 d  S(   NRo   (   Rh   t   disconnectedt   hasattrRK   t   AttributeErrorR,   R.   R2   t   removeActiveHandleRo   t   connectionFailedR   RD   (   R   RE   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyRx   +  s    c         C   s   |  j  t j    d S(   s*   
        Stop attempt to connect.
        N(   Rx   R   t	   UserError(   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   stopConnecting<  s    c         C   s   | rF t  j | |  } |  j t j | t j j | d  f   n |  j j t j	 t
 t j d |  j j     |  j j |  j    |  _ t |  _ |  j j j d |  _ |  j j |   |  j   d  S(   Ns   Unknown errort   Is   ,client(   t   connectExErrorst   getRx   R   t   getConnectErrort   errnot	   errorcodeR,   RT   RW   R   t   structt   packR-   Ro   t   buildProtocolt   getPeerR/   R_   Rh   t	   __class__R'   RL   Ra   t   startReading(   R   t   rct   bytesR:   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt	   cbConnectC  s    	c         C   s   t  |  d  s d  St j s" t  |  j j |   t j |  j |   } t j |  j	 j
   |  j |  } | r | t k r |  j | d d |  n  d  S(   NRo   i    (   R   R7   t   have_connectext   AssertionErrorR2   t   addActiveHandlet   EventR   t   connectR,   R-   R   R   (   R   R:   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR   S  s    !c         C   s   t  j d |  j j    S(   si   
        Returns an IPv4Address.

        This indicates the address from which I am connecting.
        t   TCP(   R   t   IPv4AddressR,   t   getsockname(   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   getHosta  s    c         C   s   t  j d |  j  S(   se   
        Returns an IPv4Address.

        This indicates the address that I am connected to.
        R   (   R   R   R   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR   j  s    c         C   s&   d |  j  |  j t j |   f } | S(   Ns   <%s to %s at %x>(   R   Rp   R   t
   unsignedID(   R   t   s(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   __repr__s  s    c         C   sI   |  j  s% |  j t j d |   n  t j |  |  |  j j |  d  S(   Nt   string(   Rh   Rx   R   t   ConnectErrorR+   RF   Ro   (   R   R&   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyRF   y  s    	(   R'   R(   R,   t   AF_INETRr   t   SOCK_STREAMRs   R_   R[   R   Rw   R~   Rx   R   R   R   R   R   R   RF   (    (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyRm      s   														t   Serverc           B   s8   e  Z d  Z e Z d   Z d   Z d   Z d   Z RS(   s   
    Serverside socket-stream connection class.

    I am a serverside network connection transport; a socket which came from an
    accept() on a server.
    c         C   s   t  j |  | | |  | |  _ | |  _ | |  _ d |  j j j | |  j j f |  _	 d |  j j j |  j |  j j
 f |  _ t |  _ |  j   d S(   s  
        Server(sock, protocol, client, server, sessionno)

        Initialize me with a socket, a protocol, a descriptor for my peer (a
        tuple of host, port describing the other end of the connection), an
        instance of Port, and a session number.
        s   %s,%s,%ss   <%s #%s on %s>N(   R+   R   t
   serverAddrt
   clientAddrt	   sessionnoR/   R   R'   Ry   RL   Rz   t   repstrR_   Rh   R   (   R   R0   R/   R   R   R   R2   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s    				c         C   s   |  j  S(   s=   
        A string representation of this connection.
        (   R   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s    c         C   s   |  j  S(   sW   
        Returns an IPv4Address.

        This indicates the server's address.
        (   R   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s    c         C   s   |  j  S(   sW   
        Returns an IPv4Address.

        This indicates the client's address.
        (   R   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s    (	   R'   R(   R)   R\   R[   R   R   R   R   (    (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s   				R	   c           B   s   e  Z d    Z RS(   c         C   s"   t  |  j |  j |  j |  |  j  S(   N(   Rm   Ry   Rz   R{   R2   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   _makeTransport  s    (   R'   R(   R   (    (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR	     s   t   Portc           B   s   e  Z e e j  e Z e Z e Z e	 j
 Z e	 j Z d  Z d Z d d d d  Z d   Z d   Z e j e j  d  Z e Z d   Z d   Z d	   Z d
   Z d   Z d   Z d   Z  RS(   i    i2   Rn   c         C   s1   | |  _  | |  _ | |  _ | |  _ | |  _ d  S(   N(   Rz   t   factoryt   backlogt	   interfaceR2   (   R   Rz   R   R   R   R2   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s
    				c         C   sG   |  j  d  k	 r, d |  j |  j j |  j  f Sd |  j |  j j f Sd  S(   Ns   <%s of %s on %s>s   <%s of %s (not listening)>(   t   _realPortNumberR*   R   R   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s    			c         C   s  y8 |  j  j |  j |  j  } | j |  j |  j f  Wn1 t j k
 rk } t j	 |  j |  j | f  n Xt
 j | j    |  _ | j   d |  _ t j d |  j j |  j f  |  j j   | j |  j  t |  _ t |  _ |  j  j |   | |  _ |  j j |  _ |  j   d  S(   Ni   s   %s starting on %s(   R2   Rq   Rr   Rs   Ru   R   Rz   R,   R   t   CannotListenErrorR7   t
   maxAddrLenR-   t   addrLenR   R   R
   t   msgR   R   t   doStartt   listenR   R_   Rh   R\   R   R   R.   t   doAccept(   R   R|   t   le(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   startListening  s$    			c         C   sE   t  |  _ |  j rA t j   |  _ |  j j d |  j |  |  j Sd S(   s   
        Stop accepting connections on this port.

        This will shut down my socket and call self.connectionLost().
        It returns a deferred which will fire successfully when the
        port is actually closed.
        i    N(	   R_   Ri   Rh   R   t   Deferredt   deferredR2   Rv   RF   (   R   t   connDone(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR%      s
    		c         C   s   t  j d |  j f  d S(   s.   
        Log message for closing port
        s   (TCP Port %s Closed)N(   R
   R   R   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   _logConnectionLostMsg  s    c         C   s   |  j    d |  _ d } t |  d  r: |  j } |  ` n  t |  _ |  j j |   t	 |  _
 |  j   |  ` |  ` y |  j j   Wn5 t	 |  _ | d k	 r | j t j    q   n& Xt	 |  _ | d k	 r | j d  n  d S(   s'   
        Cleans up the socket.
        R   N(   R   R*   R   R   R   R_   R   R2   R   R\   Rh   RK   R,   R.   R   t   doStopRi   t   errbackR   RD   t   callback(   R   R&   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyRF     s,    
					
		c         C   s   t  j |  j j  S(   sK   
        Returns the name of my class, to prefix log entries with.
        (   R   t   qualR   R   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyRM   8  s    c         C   s   t  j d |  j j    S(   sW   
        Returns an IPv4Address.

        This indicates the server's address.
        R   (   R   R   R,   R   (   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR   ?  s    c         C   s3   |  j  | |  |  j p |  j s/ |  j   n  d  S(   N(   t   handleAcceptRi   R   R   (   R   R   R   R:   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   cbAcceptH  s    c   	   
   C   so  |  j  s |  j r t S| rF t j d t j j | d  | f  t S| j j	 t
 j t t j d |  j
 j     t j | j j   | j  \ } } } | |  j k s t  |  j j t j d | d | d   } | d  k r | j j   nr |  j } | d |  _ t | j | t j d | d | d  t j d | d | d  | |  j  } | j |  t  Sd  S(   Ns*   Could not accept new connection -- %s (%s)s   unknown errorR   R   i    i   (!   Ri   R   R\   R
   R   R   R   R   t   newsktRT   R,   RW   R   R   R   R-   R7   t   get_accept_addrsR?   Rr   R   R   R   R   t   _ServerFactoryIPv4AddressR*   t   closeR   R   R   R2   Ra   R_   (	   R   R   R:   t   familyt   lAddrt   rAddrR/   R   t	   transport(    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR   N  s.    		 	c         C   s   t  j |  j |   } t  j d |  j d  | _ } |  j j |  j |  j	  | _
 } t  j |  j j   | j   | |  } | r | t k r |  j | |  n  d  S(   Ni   i   (   R7   R   R   t   AllocateReadBufferR   R?   R2   Rq   Rr   Rs   R   t   acceptR,   R-   R   R   (   R   R:   R?   R   R   (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR   n  s    !'N(!   R'   R(   R    R   t   IListeningPortR\   Rh   R   Ri   R,   R   Rr   R   Rs   R   R*   R   R   R   R   R   RD   R   t   CONNECTION_DONER%   t   stopListeningR   RF   RM   R   R   R   R   (    (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyR     s(   			
			 					 (    (6   R)   R,   RN   R   R   t   zope.interfaceR    R   t   twisted.internetR   R   R   R   R   t   twisted.internet.abstractR   t   twisted.internet.tcpR   R	   t   TCPConnectort   twisted.pythonR
   R   R   R   t   twisted.internet.iocpreactorR   R7   R   t'   twisted.internet.iocpreactor.interfacesR   t"   twisted.internet.iocpreactor.constR   R   R   R   R   t   twisted.protocols.tlsR   R   t   ImportErrorR*   Rl   t   ITLSTransportt   WSAECONNREFUSEDt   WSAENETUNREACHR   t   objectR   R    R+   Rm   R   R   (    (    (    sD   /usr/lib/python2.7/dist-packages/twisted/internet/iocpreactor/tcp.pyt   <module>   s8   0("


!9