here are some files that are showing the issue. 

when i run the server in one terminal and the client in another

the server output wold be:

Serving on ('127.0.0.1', 8443)
my transport None
my backlog len 2
my backlog size 4200

here is the important part of the server handler

@asyncio.coroutine
def handle_echo(reader, writer):
    global total
    yield from asyncio.sleep(0.2)
    total +=1
    writer.write(b'I AM WRITING NOWHERE1' * 100)
    writer.write(b'I AM WRITING NOWHERE2' * 100)
    print('my transport', writer.transport._ssl_protocol._transport)
    print('my backlog len', len(writer.transport._ssl_protocol._write_backlog))
    print('my backlog size',writer.transport._ssl_protocol._write_buffer_size)



and here is client side, 

@asyncio.coroutine
def communicate():
    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    context.verify_mode = ssl.CERT_NONE
    context.check_hostname = False
    reader, writer = yield from asyncio.open_connection('127.0.0.1', 8443, 
ssl=context)
    writer.close()


client is purposely misbehaving, and closing connection as soon as it can.


i am going to file a bug, as  Andrew Svetlov suggested.
 


On Sunday, September 20, 2015 at 1:00:57 AM UTC-4, Guido van Rossum wrote:
>
> You have not given a scrap of evidence that there is a bug in the 
> handshake code.
>
> On Saturday, September 19, 2015, Oleg K <[email protected] <javascript:>> 
> wrote:
>
>> in this particular case  - i know why, i am doing it on purpose to 
>> emulate what we have in real environment. 
>> right now we have a live system written in gevent, and i am looking into 
>> possibility of migrating it to asyncio.
>> (i am building test cases and benchmarks)
>>
>> it just happens, and there are many scenarios why connection may be cut 
>> in the middle of handshake.
>> (including malicious ddos attempts and other sorts of weird network 
>> issues. )
>>
>>  
>>
>> On Saturday, September 19, 2015 at 11:39:43 PM UTC-4, Guido van Rossum 
>> wrote:
>>>
>>> You should try to figure out first why the connection is lost. Perhaps 
>>> an error message is being logged somewhere? A possible cause could be that 
>>> the remote end of the connection doesn't like the settings in the SSL 
>>> context.
>>>
>>> On Sat, Sep 19, 2015 at 5:40 PM, Oleg K <[email protected]> wrote:
>>>
>>>> Hello, 
>>>>
>>>> i have suspicion that there is a bug in ssl handshake implementation. 
>>>> can someone tell me email or any other contact of author of that file?
>>>> asyncio/sslproto.py i wonder if they can help me to fix it?
>>>>
>>>>
>>>> to make long story short: 
>>>> i am developing application with ssl websockets and have found a case 
>>>> when sslproto gets into broken state. 
>>>>
>>>> there is a function 
>>>> which suppose to write into socket 
>>>>
>>>> def _write_appdata(self, data):
>>>>     self._write_backlog.append((data, 0))
>>>>     self._write_buffer_size += len(data)
>>>>     self._process_write_backlog()
>>>>
>>>>
>>>> actually - it just populates write backlog.  and later it calls:  
>>>>
>>>> def _process_write_backlog(self):
>>>>     # Try to make progress on the write backlog.
>>>>     if self._transport is None:
>>>>         return
>>>>
>>>>
>>>> which is silently exits doing nothing, because transport is *already 
>>>> gone*. 
>>>> and backlog keeps growing producing memory leak.  no error is ever 
>>>> raised.
>>>>
>>>> so what i found is: that it is happening when connection is just 
>>>> established, 
>>>> and immediately lost so lost_connection handler manages to set None to 
>>>> self._transport.
>>>>
>>>> and whole proto just thinks it finished a handshake but same time it 
>>>> lost the transport.
>>>>
>>>>
>>>>
>>>>
>>>> Regards, 
>>>> Oleg.
>>>>
>>>
>>>
>>>
>>> -- 
>>> --Guido van Rossum (python.org/~guido)
>>>
>>
>
> -- 
> --Guido van Rossum (on iPad)
>

Attachment: server.crt
Description: application/x509-ca-cert

Attachment: server.key
Description: application/iwork-keynote-sffkey

import asyncio
import ssl

@asyncio.coroutine
def communicate():
    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    context.verify_mode = ssl.CERT_NONE
    context.check_hostname = False
    reader, writer = yield from asyncio.open_connection('127.0.0.1', 8443, ssl=context)
    writer.close()


loop = asyncio.get_event_loop()
tasks = []

loop.run_until_complete(communicate())
# loop.run_forever()
loop.close()

import asyncio
import ssl
loop = asyncio.get_event_loop()
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
sslcontext.load_cert_chain('server.crt', 'server.key')
loop.set_debug(True)

total = 0
@asyncio.coroutine
def handle_echo(reader, writer):
    global total
    yield from asyncio.sleep(0.2)
    total +=1
    writer.write(b'I AM WRITING NOWHERE1' * 100)
    writer.write(b'I AM WRITING NOWHERE2' * 100)
    print('my transport', writer.transport._ssl_protocol._transport)
    print('my backlog len', len(writer.transport._ssl_protocol._write_backlog))
    print('my backlog size',writer.transport._ssl_protocol._write_buffer_size)


coro = asyncio.start_server(handle_echo, '127.0.0.1', 8443, ssl=sslcontext,loop=loop)
server = loop.run_until_complete(coro)
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()

Reply via email to