Changeset 3673

Show
Ignore:
Timestamp:
27/11/08 17:30:39 (6 weeks ago)
Author:
dmeyer
Message:

handle pre-handshake data sending

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/base/src/net/tls.py

    r3672 r3673  
    139139        self.signals += ('tls',) 
    140140        self._handshake = False 
     141        self._pre_handshake_write_queue = [] 
    141142 
    142143    def _is_read_connected(self): 
     
    153154    def _handle_write(self): 
    154155        if self._handshake: 
    155             # During the handshake stage, we don't want to write user data 
    156             # to the socket.  It's still queued; we return immediately 
    157             # and retry later. 
    158             return 
    159         return super(TLSSocket, self)._handle_write() 
     156            # Before starting the TLS handshake we created a new write 
     157            # queue. The data send before TLS was started 
     158            # (_pre_handshake_write_queue) must be send, after that we 
     159            # give control over the socket to the TLS layer. Data 
     160            # written while doing the handshake is send after it. 
     161            if not self._pre_handshake_write_queue: 
     162                # No data to send before the handshake 
     163                return 
     164            try: 
     165                # Switch queues and send pre handshake data 
     166                queue = self._write_queue 
     167                self._write_queue = self._pre_handshake_write_queue 
     168                super(TLSSocket, self)._handle_write() 
     169            finally: 
     170                self._write_queue = queue 
     171        else: 
     172            # normal operation 
     173            super(TLSSocket, self)._handle_write() 
     174 
     175    @kaa.coroutine() 
     176    def _prepare_tls(self): 
     177        """ 
     178        Prepare TLS handshake. Flush the data currently in the write buffer 
     179        and return the TLS connection object 
     180        """ 
     181        self._handshake = True 
     182        # Store current write queue and create a new one 
     183        self._pre_handshake_write_queue = self._write_queue 
     184        self._write_queue = [] 
     185        if self._pre_handshake_write_queue: 
     186            # flush pre handshake write data 
     187            yield self._pre_handshake_write_queue[-1][1] 
     188        # create TLS connection object and unregister the read monitor 
     189        c = TLSConnection(self._channel) 
     190        c.ignoreAbruptClose = True 
     191        self._rmon.unregister() 
     192        yield c 
    160193 
    161194    @kaa.coroutine() 
     
    176209            raise RuntimeError('Socket not connected') 
    177210        try: 
    178             self._handshake = True 
    179211            if session is None: 
    180212                session = tlslite.api.Session() 
    181             c = TLSConnection(self._channel) 
    182             c.ignoreAbruptClose = True 
    183             self._rmon.unregister() 
     213            tlscon = yield self._prepare_tls() 
    184214            if key: 
    185                 yield c.handshakeClientCert(session=session, checker=checker, 
     215                yield tlscon.handshakeClientCert(session=session, checker=checker, 
    186216                          privateKey=key.private, certChain=key.certificate.chain) 
    187217            elif srp: 
    188                 yield c.handshakeClientSRP(session=session, checker=checker, 
     218                yield tlscon.handshakeClientSRP(session=session, checker=checker, 
    189219                          username=srp[0], password=srp[1]) 
    190220                pass 
    191221            else: 
    192                 yield c.handshakeClientCert(session=session, checker=checker) 
    193             self._channel  = c 
     222                yield tlscon.handshakeClientCert(session=session, checker=checker) 
     223            self._channel  = tlscon 
    194224            self.signals['tls'].emit() 
    195225            self._update_read_monitor() 
     
    214244        """ 
    215245        try: 
    216             self._handshake = True 
    217             c = TLSConnection(self._channel) 
    218             c.ignoreAbruptClose = True 
    219             self._rmon.unregister() 
     246            tlscon = yield self._prepare_tls() 
    220247            kwargs = {} 
    221248            if key: 
     
    226253            if request_cert: 
    227254                kwargs['reqCert'] = True 
    228             yield c.handshakeServer(checker=checker, **kwargs) 
    229             self._channel  = c 
     255            yield tlscon.handshakeServer(checker=checker, **kwargs) 
     256            self._channel  = tlscon 
    230257            self.signals['tls'].emit() 
    231258            self._update_read_monitor()