This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Strange behavior when I logout() with IMAP4_SSL
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: giampaolo.rodola, pitrou, r.david.murray, toelke
Priority: normal Keywords:

Created on 2009-03-26 07:12 by toelke, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (6)
msg84175 - (view) Author: Philipp Tölke (toelke) Date: 2009-03-26 07:12
While researching some strange logs from out firewall and narrowing it
down to a biff-like imap-client written in python we found the following:

To reproduce:

Start a network-sniffer like wireshark on the loopback-interface
In one shell start some network-listener:
$ nc -l -p 12345

In python, connect to it and send some data:
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.connect(("127.0.0.1", 12345))
>>> s.send("Hallo\n");
6

The other shell now looks like:
$ nc -l -p 12345
Hallo

Type in anything and press <Enter> to send. Then quit the nc with C-c.

Then:
>>> s.close()

What I see here is the following:
The two messages are exchanged and nc sends his FIN-Package when
quitting. Python ACKnowledges this package (though intrestingly enough,
with a ack-number one to far (8 instead of 7 in my example)). At the
Moment of the s.close(), it sends another package, containing the same
ACK-Number, the same SEQ-Number(!) and this time the RST-Flag as well.

If I understand correctly, it sends RST, because not everything from the
connection was read by python. Why does it resend the ACK? Why is the
ACK-Number one to high? Why does it reuse the SEQ-Number?

And now to imaplib.IMAP4_SSL. The behavior here seems to me even more
strange:

If I invoke .logout(), the server sends his "BYE" message and after that
a FIN, which python ACKnowledges. At the moment, that the
IMAP4_SSL-object gets out of scope, a RST/ACK-Package is send, that
again re-ACKs the FIN and has the same sequence-number, that the ACK
package had!

Why does .logout() not send a FIN? Why does it not read the complete
Buffer, so that the Socket could close with FIN? And, why does it wait
until getting out of scope with sending this RST? (I assume, that is
when the Object is garbage-collected)

Thank you!
msg85176 - (view) Author: Philipp Tölke (toelke) Date: 2009-04-02 07:14
Just FYI, this issue is in python2.6, too.

Only, that in 2.6 the GC does not collect the objects immediately, so
that very soon I have a galore of connections in the CLOSE_WAIT-State.

And I checked, I can not read anymore data out of the socket.

Is this a bug in the ssl-implemantation?
msg104371 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-04-27 21:46
Do you still witness the issue?
Could you post a small code sample showing the problem with IMAP4_SSL?

(it's not obvious it's a Python problem at all; details of the TCP implementation are obviously handled by the OS, and Python only uses the standard C socket API -- recv(), send() and friends)
msg104820 - (view) Author: Philipp Tölke (toelke) Date: 2010-05-03 07:28
The TCP-issues from my post are all resolved. I now know how TCP works; the behaviour of python seems to be correct.

About the imap-behaviour:
me@harga ~$ python
Python 2.5.5 (r255:77872, Apr 21 2010, 08:40:04) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imaplib
>>> c = imaplib.IMAP4_SSL("post.in.tum.de")
>>> c.login("toelke", "XXX")
('OK', ['LOGIN Ok.'])
>>> c.logout()
('BYE', ['Courier-IMAP server shutting down'])
>>> <C-d>
me@harga ~$

At the time of the logout() the server closes his connection and sends a FIN-packet. If python is closed, it sends not a FIN-Packet but a RST-paket.

The "problem" I have with this is, that the Linux-Packetfilter-Firewall does not expect this RST-Packet either and in out configuration logs this as a connection in the wrong state which is generally a security-problem.

Our workaround for the last year has been

iptables -A OUTPUT  -p tcp --tcp-flags ACK,RST ACK,RST -d 131.159.22.43 -j DROP

Thanks for the help!
msg104821 - (view) Author: Philipp Tölke (toelke) Date: 2010-05-03 07:30
The TCP-issues from my post are all resolved. I now know how TCP works; the behaviour of python seems to be correct.

About the imap-behaviour:
me@harga ~$ python
Python 2.5.5 (r255:77872, Apr 21 2010, 08:40:04) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imaplib
>>> c = imaplib.IMAP4_SSL("post.in.tum.de")
>>> c.login("toelke", "XXX")
('OK', ['LOGIN Ok.'])
>>> c.logout()
('BYE', ['Courier-IMAP server shutting down'])
>>> <C-d>
me@harga ~$

At the time of the logout() the server closes his connection and sends a FIN-packet. If python is closed, it sends not a FIN-Packet but a RST-paket.

The "problem" I have with this is, that the Linux-Packetfilter-Firewall does not expect this RST-Packet either and in out configuration logs this as a connection in the wrong state which is generally a security-problem.

Our workaround for the last year has been

iptables -A OUTPUT  -p tcp --tcp-flags ACK,RST ACK,RST -d 131.159.22.43 -j DROP

Thanks for the help!
msg104846 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-05-03 15:18
FWIW on my cisco firewalls the logs contain a lot of 'deny, no connection' messages for RST packets, probably coming from similar scenarios.
History
Date User Action Args
2022-04-11 14:56:46adminsetgithub: 49815
2010-05-03 15:18:03r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg104846

resolution: not a bug
stage: resolved
2010-05-03 07:30:33toelkesetmessages: + msg104821
2010-05-03 07:28:42toelkesetmessages: + msg104820
2010-04-28 10:02:11giampaolo.rodolasetnosy: + giampaolo.rodola
2010-04-27 21:46:15pitrousetversions: - Python 2.5
nosy: + pitrou

messages: + msg104371

type: behavior
2009-04-02 07:14:23toelkesetmessages: + msg85176
versions: + Python 2.6
2009-03-26 07:12:24toelkecreate