* TCP Connection teardown seems to violate TCP specification @ 2013-08-14 19:21 Damian Lukowski 2013-08-14 19:50 ` Yuchung Cheng 0 siblings, 1 reply; 8+ messages in thread From: Damian Lukowski @ 2013-08-14 19:21 UTC (permalink / raw) To: netdev Hi, the TCP specification states that an endpoint has to accept packets from the other side even after it has half-closed the connection locally. This does not seem to be the case under Linux? For example, when I wget -O /dev/null https://www.verisign.com/ --max-redir 0, the local TCP stack sends an FIN,ACK close to the end. However, the webserver has more data to send (Encrypted Alert). Instead of ACKing the packet, the local side sends a RST. This seems wrong to me. Regards Damian ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: TCP Connection teardown seems to violate TCP specification 2013-08-14 19:21 TCP Connection teardown seems to violate TCP specification Damian Lukowski @ 2013-08-14 19:50 ` Yuchung Cheng 2013-08-14 20:14 ` Rick Jones 2013-08-14 20:46 ` Damian Lukowski 0 siblings, 2 replies; 8+ messages in thread From: Yuchung Cheng @ 2013-08-14 19:50 UTC (permalink / raw) To: Damian Lukowski; +Cc: netdev On Wed, Aug 14, 2013 at 12:21 PM, Damian Lukowski <damian@tvk.rwth-aachen.de> wrote: > Hi, > > the TCP specification states that an endpoint has to accept > packets from the other side even after it has half-closed the > connection locally. This does not seem to be the case > under Linux? > > For example, when I wget -O /dev/null https://www.verisign.com/ > --max-redir 0, the local TCP stack sends an FIN,ACK close to the end. > However, the webserver has more data to send (Encrypted Alert). > Instead of ACKing the packet, the local side sends a RST. > This seems wrong to me. Which wget are you using? it's not doing half-close (i.e., shutdown(SHUT_WR)) on my wget version 1.13.4 > > Regards > Damian > > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: TCP Connection teardown seems to violate TCP specification 2013-08-14 19:50 ` Yuchung Cheng @ 2013-08-14 20:14 ` Rick Jones 2013-08-14 21:18 ` Damian Lukowski 2013-08-14 20:46 ` Damian Lukowski 1 sibling, 1 reply; 8+ messages in thread From: Rick Jones @ 2013-08-14 20:14 UTC (permalink / raw) To: Yuchung Cheng; +Cc: Damian Lukowski, netdev On 08/14/2013 12:50 PM, Yuchung Cheng wrote: > On Wed, Aug 14, 2013 at 12:21 PM, Damian Lukowski > <damian@tvk.rwth-aachen.de> wrote: >> Hi, >> >> the TCP specification states that an endpoint has to accept >> packets from the other side even after it has half-closed the >> connection locally. This does not seem to be the case >> under Linux? >> >> For example, when I wget -O /dev/null https://www.verisign.com/ >> --max-redir 0, the local TCP stack sends an FIN,ACK close to the end. >> However, the webserver has more data to send (Encrypted Alert). >> Instead of ACKing the packet, the local side sends a RST. >> This seems wrong to me. > > Which wget are you using? it's not doing half-close (i.e., > shutdown(SHUT_WR)) on my wget version 1.13.4 I suspect that when Damian system call traces his wget he will find it is doing either: close() or shutdown(SHUT_WR) close() without waiting for the read return of zero from the remote. it may even be just exiting after getting the last bytes of the URL, which would be an implicit close() Over the years I've seen examples of all three behaviours. rick jones > > >> >> Regards >> Damian >> >> -- >> To unsubscribe from this list: send the line "unsubscribe netdev" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: TCP Connection teardown seems to violate TCP specification 2013-08-14 20:14 ` Rick Jones @ 2013-08-14 21:18 ` Damian Lukowski 2013-08-14 21:38 ` Rick Jones 2013-08-15 0:19 ` David Miller 0 siblings, 2 replies; 8+ messages in thread From: Damian Lukowski @ 2013-08-14 21:18 UTC (permalink / raw) To: Rick Jones; +Cc: Yuchung Cheng, netdev At least in curl, the close() seems to be implicit as it occurs at the very end of the trace: close(3) = 0 exit_group(0) = ? +++ exited with 0 +++ Nevertheless, shouldn't the stack keep on reading the input even if the local application is not interested in it? The other side might rely on it, and I've seen webserver logs which indicate SSL read errors likely because of this. Kind regards Damian Am Mittwoch, den 14.08.2013, 13:14 -0700 schrieb Rick Jones: > On 08/14/2013 12:50 PM, Yuchung Cheng wrote: > > On Wed, Aug 14, 2013 at 12:21 PM, Damian Lukowski > > <damian@tvk.rwth-aachen.de> wrote: > >> Hi, > >> > >> the TCP specification states that an endpoint has to accept > >> packets from the other side even after it has half-closed the > >> connection locally. This does not seem to be the case > >> under Linux? > >> > >> For example, when I wget -O /dev/null https://www.verisign.com/ > >> --max-redir 0, the local TCP stack sends an FIN,ACK close to the end. > >> However, the webserver has more data to send (Encrypted Alert). > >> Instead of ACKing the packet, the local side sends a RST. > >> This seems wrong to me. > > > > Which wget are you using? it's not doing half-close (i.e., > > shutdown(SHUT_WR)) on my wget version 1.13.4 > > I suspect that when Damian system call traces his wget he will find it > is doing either: > > close() > > or > shutdown(SHUT_WR) > close() > without waiting for the read return of zero from the remote. > > it may even be just exiting after getting the last bytes of the URL, > which would be an implicit close() > > Over the years I've seen examples of all three behaviours. > > rick jones > > > > > > >> > >> Regards > >> Damian > >> > >> -- > >> To unsubscribe from this list: send the line "unsubscribe netdev" in > >> the body of a message to majordomo@vger.kernel.org > >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > > To unsubscribe from this list: send the line "unsubscribe netdev" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: TCP Connection teardown seems to violate TCP specification 2013-08-14 21:18 ` Damian Lukowski @ 2013-08-14 21:38 ` Rick Jones 2013-08-15 5:32 ` Damian Lukowski 2013-08-15 0:19 ` David Miller 1 sibling, 1 reply; 8+ messages in thread From: Rick Jones @ 2013-08-14 21:38 UTC (permalink / raw) To: Damian Lukowski; +Cc: Yuchung Cheng, netdev On 08/14/2013 02:18 PM, Damian Lukowski wrote: > At least in curl, the close() seems to be implicit as it occurs > at the very end of the trace: > > close(3) = 0 > exit_group(0) = ? > +++ exited with 0 +++ > > Nevertheless, shouldn't the stack keep on reading the input > even if the local application is not interested in it? > The other side might rely on it, and I've seen webserver logs > which indicate SSL read errors likely because of this. Ignoring for a moment the SSL matter, if you get a tutorial on (BSD) sockets or a copy of the works of the likes of the late W. Richard Stevens you will find that the semantics of close() are such that there is no way for the received data to be consumed by an application - it no longer has a reference to the socket, so to where can the data go? If then data arrives, what is TCP to do? Clearly, from the standpoint of TCP, something is amiss. The local application has indicated it is not expecting any more data (by calling close()) and more data has arrived. TCP could discard the data and not ACK it, which would simply leave the remote TCP retransmitting until a limit was reached at the remote. TCP could bit-bucket the data and send-back ACKs, but that is giving a false sense of "success" to the remote application. So, TCP does the only thing it can do - it sends a Reset (RST) segment back to the sender. This then is an indication that something went wrong - in this case there was an application-layer error. Sadly, TCP has no way to say that rather than some other TCP-level error - it has just the one RST bit. If the other side relies on the data it is sending being consumed, and the local side close()es, that is an indication of an application-layer failure - they did not "handshake" their goodbye correctly. Also, close() is not the half-close of which you read in the TCP RFC. In the BSD Sockets interface (not to be confused with the "sockets" mentioned in the RFC) the call one makes to effect a half-close of a connection is shutdown(SHUT_WR). In that case, the application retains a reference to the socket, and so can consume data until the remote end itself then calls either SHUTDOWN(SHUT_WR) or close() (close() being OK here at the remote because the connection is already half-closed so the remote isn't going to be receiving any data in the first place). So, at the client side or more accurately the side initiating TCP connection shutdown the sequence should be something like: 1) shutdown(SHUT_WR) - this will cause TCP to send a FINished segment to the remote TCP, and the remote TCP will indicate this to the remote application via a read return of zero. 2) wait for a read return of zero, perhaps bit bucketing data - this read return of zero will indicate that the remote application has gotten the notification and has itself closed 3) close() Now, step two can be ever so slightly problematic - how long to wait? As for SSL... I cannot begin to pretend to be an SSL protocol expert, but in looking at some traces recently, and at one of the more recent RFCs, I think they have a slight hole in their specification. The (current?) spec says that an SSL Close Notify alert message is to be sent (exchanged?) when terminating the SSL session. The specs also say that a client can just send the Close Notify and go away. (eg a close - implicit or explicit) Trouble is, the remote side will want to send a Close Notify of its own. If the client has Close Notified and scooted, or even just close()ed without a Close Notify sent, the remote/server's Close Notify will hit the client's TCP stack and elicit a RST segment. Even better is when there is a statefull firewall between client and server, which then closes-off the four-tuple. If that RST is lost on the way back to the server, the server TCP will continue retransmitting the Close Notify message, which will hit the firewall and be dropped. The firewall may then log "Hey, I dropped this packet trying to get in" entries for each of those retransmissions, which then may cause people looking at said logs to become "concerned..." rick jones ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: TCP Connection teardown seems to violate TCP specification 2013-08-14 21:38 ` Rick Jones @ 2013-08-15 5:32 ` Damian Lukowski 0 siblings, 0 replies; 8+ messages in thread From: Damian Lukowski @ 2013-08-15 5:32 UTC (permalink / raw) To: Rick Jones; +Cc: Yuchung Cheng, netdev Hi, thanks for the elaborate answer. I put too much focus on the TCP state diagram. Now I also found the passages in the RFCs. RFC-793 states that "users must keep reading connections they close for sending until the TCP says no more data", and RFC-1122 says "If such a host issues a CLOSE call while received data is still pending in TCP, or if new data is received after CLOSE is called, its TCP SHOULD send a RST to show that data was lost". So those RSTs are valid, and wget/curl don't read outstanding data where they should. Best regards Damian Am Mittwoch, den 14.08.2013, 14:38 -0700 schrieb Rick Jones: > On 08/14/2013 02:18 PM, Damian Lukowski wrote: > > At least in curl, the close() seems to be implicit as it occurs > > at the very end of the trace: > > > > close(3) = 0 > > exit_group(0) = ? > > +++ exited with 0 +++ > > > > Nevertheless, shouldn't the stack keep on reading the input > > even if the local application is not interested in it? > > The other side might rely on it, and I've seen webserver logs > > which indicate SSL read errors likely because of this. > > Ignoring for a moment the SSL matter, if you get a tutorial on (BSD) > sockets or a copy of the works of the likes of the late W. Richard > Stevens you will find that the semantics of close() are such that there > is no way for the received data to be consumed by an application - it no > longer has a reference to the socket, so to where can the data go? > > If then data arrives, what is TCP to do? Clearly, from the standpoint > of TCP, something is amiss. The local application has indicated it is > not expecting any more data (by calling close()) and more data has > arrived. TCP could discard the data and not ACK it, which would simply > leave the remote TCP retransmitting until a limit was reached at the > remote. TCP could bit-bucket the data and send-back ACKs, but that is > giving a false sense of "success" to the remote application. So, TCP > does the only thing it can do - it sends a Reset (RST) segment back to > the sender. This then is an indication that something went wrong - in > this case there was an application-layer error. Sadly, TCP has no way > to say that rather than some other TCP-level error - it has just the one > RST bit. > > If the other side relies on the data it is sending being consumed, and > the local side close()es, that is an indication of an application-layer > failure - they did not "handshake" their goodbye correctly. > > Also, close() is not the half-close of which you read in the TCP RFC. > In the BSD Sockets interface (not to be confused with the "sockets" > mentioned in the RFC) the call one makes to effect a half-close of a > connection is shutdown(SHUT_WR). In that case, the application retains > a reference to the socket, and so can consume data until the remote end > itself then calls either SHUTDOWN(SHUT_WR) or close() (close() being OK > here at the remote because the connection is already half-closed so the > remote isn't going to be receiving any data in the first place). > > So, at the client side or more accurately the side initiating TCP > connection shutdown the sequence should be something like: > > 1) shutdown(SHUT_WR) - this will cause TCP to send a FINished segment to > the remote TCP, and the remote TCP will indicate this to the remote > application via a read return of zero. > 2) wait for a read return of zero, perhaps bit bucketing data - this > read return of zero will indicate that the remote application has gotten > the notification and has itself closed > 3) close() > > Now, step two can be ever so slightly problematic - how long to wait? > > As for SSL... I cannot begin to pretend to be an SSL protocol expert, > but in looking at some traces recently, and at one of the more recent > RFCs, I think they have a slight hole in their specification. The > (current?) spec says that an SSL Close Notify alert message is to be > sent (exchanged?) when terminating the SSL session. The specs also say > that a client can just send the Close Notify and go away. (eg a close - > implicit or explicit) > > Trouble is, the remote side will want to send a Close Notify of its own. > If the client has Close Notified and scooted, or even just close()ed > without a Close Notify sent, the remote/server's Close Notify will hit > the client's TCP stack and elicit a RST segment. Even better is when > there is a statefull firewall between client and server, which then > closes-off the four-tuple. If that RST is lost on the way back to the > server, the server TCP will continue retransmitting the Close Notify > message, which will hit the firewall and be dropped. The firewall may > then log "Hey, I dropped this packet trying to get in" entries for each > of those retransmissions, which then may cause people looking at said > logs to become "concerned..." > > rick jones > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: TCP Connection teardown seems to violate TCP specification 2013-08-14 21:18 ` Damian Lukowski 2013-08-14 21:38 ` Rick Jones @ 2013-08-15 0:19 ` David Miller 1 sibling, 0 replies; 8+ messages in thread From: David Miller @ 2013-08-15 0:19 UTC (permalink / raw) To: damian; +Cc: rick.jones2, ycheng, netdev From: Damian Lukowski <damian@tvk.rwth-aachen.de> Date: Wed, 14 Aug 2013 23:18:17 +0200 > Nevertheless, shouldn't the stack keep on reading the input > even if the local application is not interested in it? Absolutely, positively, not. It is a loss of data, and therefore TCP responds with a reset when pending read data is not consumed by the application. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: TCP Connection teardown seems to violate TCP specification 2013-08-14 19:50 ` Yuchung Cheng 2013-08-14 20:14 ` Rick Jones @ 2013-08-14 20:46 ` Damian Lukowski 1 sibling, 0 replies; 8+ messages in thread From: Damian Lukowski @ 2013-08-14 20:46 UTC (permalink / raw) To: Yuchung Cheng; +Cc: netdev Hi, I've seen this with wget 1.14 and curl 7.30.0 on 3.11-rc5 (Gentoo), with wget 1.15 and curl 7.26.0 on 3.5.7 (other Gentoo machine), with wget 1.12 and curl 7.19.7 on 2.6.32 (Centos 6.4), Regards Damian Am Mittwoch, den 14.08.2013, 12:50 -0700 schrieb Yuchung Cheng: > On Wed, Aug 14, 2013 at 12:21 PM, Damian Lukowski > <damian@tvk.rwth-aachen.de> wrote: > > Hi, > > > > the TCP specification states that an endpoint has to accept > > packets from the other side even after it has half-closed the > > connection locally. This does not seem to be the case > > under Linux? > > > > For example, when I wget -O /dev/null https://www.verisign.com/ > > --max-redir 0, the local TCP stack sends an FIN,ACK close to the end. > > However, the webserver has more data to send (Encrypted Alert). > > Instead of ACKing the packet, the local side sends a RST. > > This seems wrong to me. > > Which wget are you using? it's not doing half-close (i.e., > shutdown(SHUT_WR)) on my wget version 1.13.4 > > > > > > Regards > > Damian > > > > -- > > To unsubscribe from this list: send the line "unsubscribe netdev" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-08-15 5:32 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-08-14 19:21 TCP Connection teardown seems to violate TCP specification Damian Lukowski 2013-08-14 19:50 ` Yuchung Cheng 2013-08-14 20:14 ` Rick Jones 2013-08-14 21:18 ` Damian Lukowski 2013-08-14 21:38 ` Rick Jones 2013-08-15 5:32 ` Damian Lukowski 2013-08-15 0:19 ` David Miller 2013-08-14 20:46 ` Damian Lukowski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).