* Client receives TCP packets but does not ACK @ 2001-06-13 0:26 Robert Kleemann 2001-06-15 3:50 ` Robert Kleemann 2001-06-16 23:56 ` Robert Kleemann 0 siblings, 2 replies; 29+ messages in thread From: Robert Kleemann @ 2001-06-13 0:26 UTC (permalink / raw) To: linux-kernel I have a client server program that opens a tcp connection between two machines. Everything is fine until a certain type of data is sent across the socket at which point the client refuses to ACK and the server continues to resend the packets to no avail. I've verified that the client is blocking on a socket read (and not coming out) I've also run "tcpdump -lxa -s 5000" on each machine and verified that each packet sent by each machine is received by the other. I diffed the data and there appears to be no corruption. I first saw this with the server running 2.4.2 and the client running 2.2.16 but I have since upgraded the server first to 2.4.5 and then also added a patch from 1.4.6-pre2 that had to do with tcp acks. The bug still repros. I have also upgraded the client to 2.4.2, 2.4.5, and 2.4.5 + ack patch with no luck. There have been quite a few other people who have experienced these symptoms and posted to the list over the past 5 months or so. I haven't seen a resolution for any of them except for requests to try the latest kernel since there have been a lot of networking fixes in the latest kernels. I have appened links to these other postings at the end of this email in case their data might help. I can consistently reproduce this problem on my machines (10mbs ethernet lan) and would really like to narrow this bug down to the source instead of trying the latest kernels and hoping that they solve the problem. The networking code (net/ipv4/tcp*.c) is daunting to me but if someone has any suggestions on good places to add debug code, building a debug version, or whatever, I can try it on my local system and investigate further. This bug is driving me crazy and I want to find it and fix it! Are there any other details that would help? My hardware configuration? Network settings? etc? Here is the analysis of one of the tcpdump logs for glottis. glottis is the client and manny is the server. Note that the large packet 11006:1254(1448) is received by glottis and an ack is never sent to manny. 20:07:45.043640 glottis->manny ack 11006 20:07:45.047120 manny->glottis 11006:12454(1448) ack 408 probably contains the remainder of ClientMap 20:07:45.047571 manny->glottis 12454:12936(482) ack 408 20:07:45.047673 glottis->manny ack 11006 20:07:45.272042 manny->glottis 11006:12454(1448) ack 408 resend 20:07:45.732049 manny->glottis 11006:12454(1448) ack 408 resend 20:07:46.652015 manny->glottis 11006:12454(1448) ack 408 resend 20:07:48.491986 manny->glottis 11006:12454(1448) ack 408 resend 20:07:52.171937 manny->glottis 11006:12454(1448) ack 408 resend 20:07:59.531850 manny->glottis 11006:12454(1448) ack 408 resend web packets as manny is probably pinging session server 20:08:14.251656 manny->glottis 11006:12454(1448) ack 408 resend 20:08:24.078088 glottis->manny 408:437(29) ack 11006 text request in same packet 20:08:24.110417 manny->glottis ack 437 20:08:27.539778 glottis->manny 437:470(33) ack 11006 quit message 20:08:27.540158 manny->glottis 12936:12936(0) ack 470 20:08:27.541574 glottis->manny 470:472(2) ack 11006 20:08:27.542069 manny->glottis 12936:12936(0) ack 472 20:08:27.637385 manny->glottis 12936:12936(0) ack 473 web packets ntp packets 20:08:43.691285 manny->glottis 11006:12454(1448) ack 473 resend arp packets Here are some other threads on the list that may be related to this problem: http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=ca50bd5b6fab99dd,2&seekm=linux.kernel.3A806260.BB77D017%40denise.shiny.it#p http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=c2b75d883be146f6,2&seekm=linux.kernel.5.0.2.1.2.20010115152847.00a8a380%40pop.we.mediaone.net#p http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=5a94424eaed764df,21&seekm=linux.kernel.3A6F3C4A.27E148E9%40colorfullife.com#p http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=d74b104bfe2da967,14&seekm=200104101738.VAA21467%40ms2.inr.ac.ru#p http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=c15161c8342be0a0,7&seekm=linux.kernel.Pine.LNX.4.30.0012311601410.9994-100000%40shodan.irccrew.org#p http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=7268b77eb1e07a38,3&seekm=20010419200905.A2970%40ping.be#p http://groups.google.com/groups?hl=en&lr=&safe=off&ic=1&th=160b098279e28ca9,8&seekm=linux.kernel.F57chplw8IfbyyOxmQp000170f7%40hotmail.com#p Please cc me on any replies. thanx! Robert ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-13 0:26 Client receives TCP packets but does not ACK Robert Kleemann @ 2001-06-15 3:50 ` Robert Kleemann 2001-06-15 12:44 ` Mike Black 2001-06-16 23:56 ` Robert Kleemann 1 sibling, 1 reply; 29+ messages in thread From: Robert Kleemann @ 2001-06-15 3:50 UTC (permalink / raw) To: linux-kernel A couple people have requested a test case. The problem first showed up in a very large java app. Since then I wrote a small perl program to duplicate the behavior of the large app by sending the same data, in the same order, in the same sized blocks, from the server to the client. If you want to test this on your configuration then download the following two files: http://www.kleemann.org/crap/clientserver http://www.kleemann.org/crap/log1e1.txt Place a copy of the files in the same directory on both the client and the server and run the program the following way: [server]$ ./clientserver -s log1e1.txt listening on port 20001 [client]$ ./clientserver -c serverhostname log1e1.txt The server will attempt to send the data to the client which then verifies each byte received. My client generally stops ack-ing between messages 15 and 25. Robert. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 3:50 ` Robert Kleemann @ 2001-06-15 12:44 ` Mike Black 2001-06-15 18:29 ` Albert D. Cahalan 0 siblings, 1 reply; 29+ messages in thread From: Mike Black @ 2001-06-15 12:44 UTC (permalink / raw) To: Robert Kleemann, linux-kernel Here's the end of my run -- I assume this means my config works OK? I'm on a dual PIII/600 linux-2.4.6-pre3 -- ran it all on the local host. received msg#90, name pad1, 1 blocks, 12 total bytes received msg#91, name pad1, 1 blocks, 12 total bytes received msg#92, name class tande.server.ClientMap, 1624 blocks, 3244 total bytes received msg#93, name pad1, 1 blocks, 12 total bytes received msg#94, name pad1, 1 blocks, 12 total bytes received msg#95, name pad1, 1 blocks, 12 total bytes received msg#96, name class tande.server.ClientMap, 1624 blocks, 3244 total bytes successfully read all blocks I'm concerned that you're probably just overruning your IP stack: foreach $block (@blocks) { print $client $block; $bytes += length($block); } TCP is NOT a guaranteed protocol -- you can't just blast data from one port to another and expect it to work. a tcp-write is NOT guaranteed -- and as you've seen -- a recv() isn't either (that's why you need timeouts). You're probably overrunning the tcp buffer on your "print" statement and truncating a block. I don't see where you're checking for EAGAIN or EWOULDBLOCK (see man send). Not real sure how to do this in perl... You need a layer-7 protocol that will guarantee your transactions -- once you're client acks/naks your server I'll bet everything works hunky-dory. If you're not familiar with the OSI model http://www.csihq.com/~mike/students/networking/iso/isomodel.html ________________________________________ Michael D. Black Principal Engineer mblack@csihq.com 321-676-2923,x203 http://www.csihq.com Computer Science Innovations http://www.csihq.com/~mike My home page FAX 321-676-2355 ----- Original Message ----- From: "Robert Kleemann" <robert@kleemann.org> To: <linux-kernel@vger.kernel.org> Sent: Thursday, June 14, 2001 11:50 PM Subject: Re: Client receives TCP packets but does not ACK A couple people have requested a test case. The problem first showed up in a very large java app. Since then I wrote a small perl program to duplicate the behavior of the large app by sending the same data, in the same order, in the same sized blocks, from the server to the client. If you want to test this on your configuration then download the following two files: http://www.kleemann.org/crap/clientserver http://www.kleemann.org/crap/log1e1.txt Place a copy of the files in the same directory on both the client and the server and run the program the following way: [server]$ ./clientserver -s log1e1.txt listening on port 20001 [client]$ ./clientserver -c serverhostname log1e1.txt The server will attempt to send the data to the client which then verifies each byte received. My client generally stops ack-ing between messages 15 and 25. Robert. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 12:44 ` Mike Black @ 2001-06-15 18:29 ` Albert D. Cahalan 2001-06-15 23:10 ` Robert Kleemann 2001-06-16 11:55 ` Mike Black 0 siblings, 2 replies; 29+ messages in thread From: Albert D. Cahalan @ 2001-06-15 18:29 UTC (permalink / raw) To: Mike Black; +Cc: Robert Kleemann, linux-kernel Mike Black writes: > I'm concerned that you're probably just overruning your IP stack: ... > TCP is NOT a guaranteed protocol -- you can't just blast data from one port > to another and expect it to work. Yes you can. This is why we have TCP in fact. > a tcp-write is NOT guaranteed -- and as you've seen -- a recv() isn't either > (that's why you need timeouts). > You're probably overrunning the tcp buffer on your "print" statement and > truncating a block. > I don't see where you're checking for EAGAIN or EWOULDBLOCK (see man > send). You do have to check for partial writes due to the UNIX API. Then check for EAGAIN and EINTR at least. > You need a layer-7 protocol that will guarantee your transactions -- once > you're client acks/naks your server I'll bet everything works hunky-dory. > If you're not familiar with the OSI model > http://www.csihq.com/~mike/students/networking/iso/isomodel.html You don't need that crap. TCP/IP doesn't even fit the OSI model, and we're missing much of the OSI stack AFAIK. (Do we have that thing with 10-byte addresses? I think not.) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 18:29 ` Albert D. Cahalan @ 2001-06-15 23:10 ` Robert Kleemann 2001-06-16 11:55 ` Mike Black 1 sibling, 0 replies; 29+ messages in thread From: Robert Kleemann @ 2001-06-15 23:10 UTC (permalink / raw) To: Albert D. Cahalan; +Cc: Mike Black, linux-kernel First a little more data on the problem. 1) I've never seen it with the client and server program on the same computer. 2) It only repros on some systems. If I can repro it on some systems and then make the client the server and the server the client the bug will often fail to repro. 3) Once it repros it _consistently_ repros seemingly independent of kernel versions. Second, I really don't think it is a problem with the server. Running the test a few times I get the following behavior. The client reads up to message #19 before failing to ack, the server program keeps executing "prints" until the send buffer fills and then blocks on the next print at message #25. "netstat -t" on the server shows the following tcp 0 8688 manny-out:20001 glottis:33193 ESTABLISHED If I run the test a few more times, the client will block on a different message (6,5,10,etc) and the server program will continue to fill the buffer with the same amount of data before blocking. What is more interesting to me is that if I add print statements before and after the client "recv" call then it appears that the client is blocking within the receive call. If I packet sniff the client then I see lots of packets from the server with happy acks from the client until one packet does not receive an ack. The server then does the right thing and resends the non-acked packet at increasing time intervals. Eventually the client sends an ack for the previously received packet (not the most recent that is being resent. This exchange continues indefinitely. I've appended a commented packet log to the end of this email. So the client app is in the recv call waiting for data and the interface is receiving the packet that should satisfy that block. Why would the client not be sending an ack? If the buffer is full then shouldn't the thread be returning from the recv call and releasing some of that data? One person emailed me a possible gotcha is that SIGINT is being triggered somehow by the system call but I added a trap to the original java app and now to the little perl script and it seems to never be triggered. Any other ideas for areas to investigate? Robert. Here are the logs. packet A sent 20:15:21.703718 < manny.20001 > glottis-in.33088: P 14729:14984(255) ack 1 win 5792 <nop,nop,timestamp 925740 16355479> (DF) packet B sent 20:15:21.713719 < manny.20001 > glottis-in.33088: . 14984:16432(1448) ack 1 win 5792 <nop,nop,timestamp 925741 16355479> (DF) ack up to packet B 20:15:21.713719 > glottis-in.33088 > manny.20001: . 1:1(0) ack 16432 win 34752 <nop,nop,timestamp 16355480 925740> (DF) packet C sent 20:15:21.713719 < manny.20001 > glottis-in.33088: P 16432:16714(282) ack 1 win 5792 <nop,nop,timestamp 925741 16355480> (DF) packet D sent 20:15:21.713719 < manny.20001 > glottis-in.33088: . 16714:18162(1448) ack 1 win 5792 <nop,nop,timestamp 925742 16355480> (DF) ack up to packet D 20:15:21.713719 > glottis-in.33088 > manny.20001: . 1:1(0) ack 18162 win 37648 <nop,nop,timestamp 16355480 925741> (DF) packet E sent 20:15:21.723719 < manny.20001 > glottis-in.33088: P 18162:18420(258) ack 1 win 5792 <nop,nop,timestamp 925742 16355480> (DF) packet F sent 20:15:21.733719 < manny.20001 > glottis-in.33088: . 18420:19868(1448) ack 1 win 5792 <nop,nop,timestamp 925743 16355480> (DF) packet G sent 20:15:21.743719 < manny.20001 > glottis-in.33088: . 19868:21316(1448) ack 1 win 5792 <nop,nop,timestamp 925744 16355480> (DF) ack up to packet E 20:15:21.743719 > glottis-in.33088 > manny.20001: . 1:1(0) ack 18420 win 37648 <nop,nop,timestamp 16355483 925742,nop,nop, sack 1 {19868:21316} > (DF) packet H sent 20:15:21.743719 < manny.20001 > glottis-in.33088: P 21316:22139(823) ack 1 win 5792 <nop,nop,timestamp 925744 16355483> (DF) ack up to packet E 20:15:21.743719 > glottis-in.33088 > manny.20001: . 1:1(0) ack 18420 win 37648 <nop,nop,timestamp 16355483 925742,nop,nop, sack 1 {19868:22139} > (DF) packet I sent 20:15:21.763720 < manny.20001 > glottis-in.33088: . 22139:23587(1448) ack 1 win 5792 <nop,nop,timestamp 925746 16355483> (DF) ack up to packet E 20:15:21.763720 > glottis-in.33088 > manny.20001: . 1:1(0) ack 18420 win 37648 <nop,nop,timestamp 16355485 925742,nop,nop, sack 1 {19868:23587} > (DF) resend packet F many times in increasing time intervals. Why does the client not ack this? 20:15:21.763720 < manny.20001 > glottis-in.33088: . 18420:19868(1448) ack 1 win 5792 <nop,nop,timestamp 925746 16355485> (DF) 20:15:21.973726 < manny.20001 > glottis-in.33088: . 18420:19868(1448) ack 1 win 5792 <nop,nop,timestamp 925768 16355485> (DF) 20:15:22.413738 < manny.20001 > glottis-in.33088: . 18420:19868(1448) ack 1 win 5792 <nop,nop,timestamp 925812 16355485> (DF) 20:15:23.293761 < manny.20001 > glottis-in.33088: . 18420:19868(1448) ack 1 win 5792 <nop,nop,timestamp 925900 16355485> (DF) 20:15:25.053809 < manny.20001 > glottis-in.33088: . 18420:19868(1448) ack 1 win 5792 <nop,nop,timestamp 926076 16355485> (DF) 20:15:28.573905 < manny.20001 > glottis-in.33088: . 18420:19868(1448) ack 1 win 5792 <nop,nop,timestamp 926428 16355485> (DF) 20:15:35.614095 < manny.20001 > glottis-in.33088: . 18420:19868(1448) ack 1 win 5792 <nop,nop,timestamp 927132 16355485> (DF) ack up to packet E 20:15:41.964268 > glottis-in.33088 > manny.20001: F 1:1(0) ack 18420 win 37648 <nop,nop,timestamp 16357505 925742,nop,nop, sack 1 {19868:23587} > (DF) Not sure what this is for... 20:15:41.964268 < manny.20001 > glottis-in.33088: . 23587:23587(0) ack 2 win 5792 <nop,nop,timestamp 927767 16357505> (DF) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 18:29 ` Albert D. Cahalan 2001-06-15 23:10 ` Robert Kleemann @ 2001-06-16 11:55 ` Mike Black 1 sibling, 0 replies; 29+ messages in thread From: Mike Black @ 2001-06-16 11:55 UTC (permalink / raw) To: linux-kernel OK guys -- how much money are you willing to be that TCP is guaranteed?? Since you don't want to talk OSI that's OK -- that's just to educate some people. Try this: (this is what I ran into years ago and had to argue to death). #1 Client1 has tcp connection to Server1. Both machines are setup to retry connections if they fail. #2 Server1 has power outage (note that Client1 has absolutely NO idea what happens until Server1 is back up again no RST -- no nothin'). #3 Client1 finally times out and is able to reconnect to Server1 and thinks everything is OK (as do all the programmers at our customer who think TCP is a guaranteed protocol). #4 Analysis shows numerous transacations have been lost (complete panic by the customer). Here's the big question. Who's fault is it? Our customer tried to claim that the TCP stack was at fault on our server (a Windows 3.1 box) because it "dropped packets" and didn't know about it. Then they thought that the TCP stack on their client was at fault because it never showed an error trying to write to the socket. After much argument I finally was able to show them (from the author of TCP whom I emailed for support) that TCP is NOT guaranteed -- it's up to what you guys are calling the "API" layer (OSI Layer 7) to ENSURE that data ACTUALLY gets to it's intended target. I was brought in late on this contract but I never would've implemented the brain-dead protocol (or actually complete lack of one) for sending transactions across a socket. You're right in that TCP will work just fine AS LONG AS THERE ARE NO PROBLEMS!!!! You can write a program that just opens a socket and blasts data to the recipient without an error. And as long as your protocol is session oriented you'll be fine. If the session aborts you just resend the whole thing. But that does NOT make a robust solution for a transaction oriented protocol (like the one that started this thread) (contrary to what many people think AND code up). P.S. My reference to TCP being at OSI layer 5 is because that's what the API is for sockets -- Session Layer -- and that's all that people generally think is needed. Big mistake if you're transaction-oriented. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-13 0:26 Client receives TCP packets but does not ACK Robert Kleemann 2001-06-15 3:50 ` Robert Kleemann @ 2001-06-16 23:56 ` Robert Kleemann 2001-06-27 1:04 ` Robert Kleemann 1 sibling, 1 reply; 29+ messages in thread From: Robert Kleemann @ 2001-06-16 23:56 UTC (permalink / raw) To: linux-kernel In order to figure out what this problem is I'm going to add some printk statements in the networking code on the client machine. Hopefully, this will show me what's going on. My goal is to trace the receipt of the datagram by tcp, see why/how it's deciding to ack or not ack, and then trace the sending of the ack. There are quite a few files that seem to be involved including: linux/net/ipv4/tcp*.c as well as some important structures in linux/include/net/sock.h I'm guessing this is going to take me a while just to figure out where to look and what to look for. Can any of you networking gurus save me some time and suggest some functions to start looking at? thanx! Robert ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-16 23:56 ` Robert Kleemann @ 2001-06-27 1:04 ` Robert Kleemann 0 siblings, 0 replies; 29+ messages in thread From: Robert Kleemann @ 2001-06-27 1:04 UTC (permalink / raw) To: linux-kernel SUMMARY: The bad network behavior was due to shared irqs somehow screwing things up. This explained most but not all of the problems. DETAILS: Many people emailed me that they were experiencing similar problems. Even though the cause of my problem is not kernel related, I'm hoping my narrative and eventual solution will helps some folks. I also still think this behavior is really weird so those of you with an abundance of brains and curiosity might want to take a guess at explaining the behavior that I'm seeing. When I last posted I had a reproducible test case which spewed a bunch of packets from a server to a client. The behavior is that the client eventually stops ACKing and so the the connection stalls indefinitely. I spent some time studying the kernel networking code and traced the code path taken by a tcp packet: linux/net/core/dev.c:netif_rx() // packet received by eth card linux/net/ipv4/ip_input.c:ip_rcv() linux/net/ipv4/ip_input.c:ip_rcv_finish() linux/net/ipv4/tcp_ipv4.c:tcp_v4_recv() linux/net/ipv4/tcp_ipv4.c:tcp_v4_do_rcv() linux/net/ipv4/tcp_input.c:tcp_rcv_established() // packet placed in user queue Each routine had 2 to 6 conditions that would result in a dropped packet. I added printk statements for each of these conditions in hopes of detecting why the final packet is not acked. I recompiled the kernel, and reran the test. The result was that the packet was being droped in tcp_rcv_established() due to an invalid checksum. I then ran tcpdump to verify that the packets sent from the server were the same packets that were received by the client. It turned out that one byte was being corrupted and it was always the same byte in the stream that was corrupted. This was very confusing because my previous logs show _no_ corruption of the final packet. Anyway, now it appeared to be a hardware related problem so I started swapping ethernet cards to no effect. I then look at the irqs (cat /proc/interrupts) and noticed that the ethernet card in the client was sharing an irq with the aic7xxx scsi adapter. The following url made me think that this could be causing a problem: http://www.scyld.com/expert/irq-conflict.html The motherboard on the client is an old Intel PR440FX (dual 200mhz PPro, onboard LAN, SCSI) and doesn't allow any kind of configuring of the irqs so I ended up throwing another pci net card in the box just to juggle the irqs enough so that one of the net cards was not sharing an irq with the scsi card. The bug no longer repros! Neither the reduced test case nor the original shows any problems. My only remaining questions are: 1) Does this make sense? Would a scsi card sharing an irq with a net card cause rare but highly reproducable corruption? I was able to run http, telnet, ftp, mail, and games though this card with no problems. It only failed on a specific set of data. This is what initially led me to believe that the problem was not hardware related. 2) Now that two net cards are sharing an irq, have I just trading one subtle corruption bug for another? Will some different data set cause the same type of corruption? Is it safe to share irqs? 3) My old tcpdump logs (from several weeks ago) show _no_ corruption. I would have believed that I must have screwed up except that I still have the logs and the packets sent from the server compare exactly with those received by the client. I can't seem to reproduce this behavior. Robert. ^ permalink raw reply [flat|nested] 29+ messages in thread
[parent not found: <Pine.LNX.4.33.0106121720310.1152-100000@localhost.localdomain.suse.lists.linux.kernel>]
* Re: Client receives TCP packets but does not ACK [not found] <Pine.LNX.4.33.0106121720310.1152-100000@localhost.localdomain.suse.lists.linux.kernel> @ 2001-06-13 8:48 ` Andi Kleen 2001-06-13 16:09 ` Robert Kleemann 0 siblings, 1 reply; 29+ messages in thread From: Andi Kleen @ 2001-06-13 8:48 UTC (permalink / raw) To: Robert Kleemann; +Cc: linux-kernel Robert Kleemann <robert@kleemann.org> writes: > I have a client server program that opens a tcp connection between two > machines. Everything is fine until a certain type of data is sent > across the socket at which point the client refuses to ACK and the > server continues to resend the packets to no avail. > > I've verified that the client is blocking on a socket read (and not > coming out) I've also run "tcpdump -lxa -s 5000" on each machine and > verified that each packet sent by each machine is received by the > other. I diffed the data and there appears to be no corruption. > > I first saw this with the server running 2.4.2 and the client running > 2.2.16 but I have since upgraded the server first to 2.4.5 and then > also added a patch from 1.4.6-pre2 that had to do with tcp acks. The > bug still repros. I have also upgraded the client to 2.4.2, 2.4.5, > and 2.4.5 + ack patch with no luck. > > There have been quite a few other people who have experienced these > symptoms and posted to the list over the past 5 months or so. I > haven't seen a resolution for any of them except for requests to try > the latest kernel since there have been a lot of networking fixes in > the latest kernels. I have appened links to these other postings at > the end of this email in case their data might help. > > I can consistently reproduce this problem on my machines (10mbs > ethernet lan) and would really like to narrow this bug down to the > source instead of trying the latest kernels and hoping that they solve > the problem. The networking code (net/ipv4/tcp*.c) is daunting to me > but if someone has any suggestions on good places to add debug code, > building a debug version, or whatever, I can try it on my local system > and investigate further. This bug is driving me crazy and I want to > find it and fix it! > > Are there any other details that would help? My hardware > configuration? Network settings? etc? The packet likely doesn't fit into the socket buffer and is silently dropped. The TCP stack doesn't force an ACK in this case, but it probably should, although it wouldn't solve the deadlock. The deadlock will be only solved if the local application reads data and clears the socket buffer. If you have a single packet that is bigger than the empty socket buffer / 2 you lose. You can check the allocated socket buffer size using netstat. You can increase it using the /proc/sys/net/core/rmem_{default,max} sysctls; in 2.4 there is also a TCP memory limit that can be tuned using /proc/sys/net/ipv4/tcp_mem. Doubling one of these will probably fix your problems. Normally the socket buffer should not overflow if the sender honors the TCP window protocol, but there are some corner cases where it can still happen, e.g. when the application sends lots of small packets (which all have fixed metadata overhead) or the device driver always hands full MTU sized packets to the stack. 2.4.4+ has some fixes that should make these corner cases less likely. It cannot be completely solved unfortunately. -Andi ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-13 8:48 ` Andi Kleen @ 2001-06-13 16:09 ` Robert Kleemann 0 siblings, 0 replies; 29+ messages in thread From: Robert Kleemann @ 2001-06-13 16:09 UTC (permalink / raw) To: Andi Kleen; +Cc: linux-kernel On 13 Jun 2001, Andi Kleen wrote: > The packet likely doesn't fit into the socket buffer and is silently > dropped. The TCP stack doesn't force an ACK in this case, but it > probably should, although it wouldn't solve the deadlock. The deadlock > will be only solved if the local application reads data and clears the > socket buffer. If you have a single packet that is bigger than the > empty socket buffer / 2 you lose. > > You can check the allocated socket buffer size using netstat. Thanks for the quick response! I tried most of the netstat options and was unable to see the buffer size. I do see the Recv-Q and the Send-Q which are usually zero except when the client stops ack-ing and then the server's Send-Q starts filling up. > You can increase it using the /proc/sys/net/core/rmem_{default,max} > sysctls; in 2.4 there is also a TCP memory limit that can be tuned > using /proc/sys/net/ipv4/tcp_mem. Doubling one of these will probably > fix your problems. On the client: /proc/sys/net/core/rmem_default = 65535 /proc/sys/net/core/rmem_max = 65535 /proc/sys/net/ipv4/tcp_mem = 48128 48640 49152 On the server: /proc/sys/net/core/rmem_default = 65535 /proc/sys/net/core/rmem_max = 65535 /proc/sys/net/ipv4/tcp_mem = 23552 24064 24576 The "bad" packet that seems to cause all the problems is only 1448 bytes long so I don't think insufficient buffers is the problem. After the client stops ack-ing I can watch the server's Send-Q slowly rise 2K, 4K, 6K, but it never comes close to these buffer limits. Robert. ^ permalink raw reply [flat|nested] 29+ messages in thread
* RE: Client receives TCP packets but does not ACK @ 2001-06-15 12:53 Heusden, Folkert van 2001-06-15 18:27 ` Mike Black 2001-06-18 11:50 ` Jan Hudec 0 siblings, 2 replies; 29+ messages in thread From: Heusden, Folkert van @ 2001-06-15 12:53 UTC (permalink / raw) To: Mike Black, linux-kernel > TCP is NOT a guaranteed protocol -- you can't just blast data from one port > to another and expect it to work. Isn't it? Are you really sure about that? I thought UDP was the not-guaranteed-one and TCP was the one guaranting that all data reaches the other end in order and all. Please enlighten me. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 12:53 Heusden, Folkert van @ 2001-06-15 18:27 ` Mike Black 2001-06-15 18:39 ` Gérard Roudier 2001-06-15 19:12 ` Alan Cox 2001-06-18 11:50 ` Jan Hudec 1 sibling, 2 replies; 29+ messages in thread From: Mike Black @ 2001-06-15 18:27 UTC (permalink / raw) To: Heusden, Folkert van, linux-kernel This is a very common misconception -- I worked a contract many years ago where I actually had to quote the author of TCP to convince a banking company I was working with that TCP is not a guaranteed protocol. Guaranteed delivery at layer 5 - yes -- but NOT a guaranteed protcol. Guaranteed means that there is absolutely NO way that data can be dropped by an application if either sender or receiver screws up. The only way to do this is at layer 7 of the OSI model -- even then you end up making assumptions. Here's some examples for layer 5 (which TCP operates at) but talking at Layer 7: #1 - You send() data -- meanwhile the receiver terminates the connection -- what happened to the data? It's gone! Your app never receives feedback that it didn't send() correctly. You'll see the reset on the next read but you don't know what happened to the data. #2 - You send() data and overrun your IP queue -- nobody will ever know the difference without a layer 7 protocol (or int the case quoted in this subject it might lock up). #3 - You send() data and either machine has bad RAM and flips a bit -- guess what? -- data corruption. Even when you do layer 7 (with checksums and ack/nak) you make assumptions: #1 - You checksum the packet you just received -- what's to say a bit can't flip? TCP may be guaranteed at layer 5 but we don't typically program at layer 5 -- we program at layer 7 and then lots of people assume they're doing it at layer 5 -- ergo the problems. To look at it another way -- "Just 'cuz I told my C library to send a packet doesn't mean it's going to work". For example, if you're using non-blocking sockets you have to check to ensure there's room in your IP queue to transmit. TCP is guaranteed delivery at layer 5 -- but that's all -- not a "guaranteed protocol" ________________________________________ Michael D. Black Principal Engineer mblack@csihq.com 321-676-2923,x203 http://www.csihq.com Computer Science Innovations http://www.csihq.com/~mike My home page FAX 321-676-2355 ----- Original Message ----- From: "Heusden, Folkert van" <f.v.heusden@ftr.nl> To: "Mike Black" <mblack@csihq.com>; <linux-kernel@vger.kernel.org> Sent: Friday, June 15, 2001 8:53 AM Subject: RE: Client receives TCP packets but does not ACK > TCP is NOT a guaranteed protocol -- you can't just blast data from one port > to another and expect it to work. Isn't it? Are you really sure about that? I thought UDP was the not-guaranteed-one and TCP was the one guaranting that all data reaches the other end in order and all. Please enlighten me. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 18:27 ` Mike Black @ 2001-06-15 18:39 ` Gérard Roudier 2001-06-15 19:12 ` Alan Cox 1 sibling, 0 replies; 29+ messages in thread From: Gérard Roudier @ 2001-06-15 18:39 UTC (permalink / raw) To: Mike Black; +Cc: Heusden, Folkert van, linux-kernel On Fri, 15 Jun 2001, Mike Black wrote: > This is a very common misconception -- I worked a contract many years ago > where I actually had to quote the author of TCP to convince a banking > company I was working with that TCP is not a guaranteed protocol. > Guaranteed delivery at layer 5 - yes -- but NOT a guaranteed protcol. > > Guaranteed means that there is absolutely NO way that data can be dropped by > an application if either sender or receiver screws up. > > The only way to do this is at layer 7 of the OSI model -- even then you end > up making assumptions. You are mixing oranges (protocols) and apples (implementations and APIs) here. The layer that is expected to provide reliable end to end communication is layer 4 (transport layer). TCP, at least in theory, is as good as OSI transport in providing reliable end to end communication. > Here's some examples for layer 5 (which TCP operates at) but talking at > Layer 7: > > #1 - You send() data -- meanwhile the receiver terminates the connection -- > what happened to the data? It's gone! Your app never receives feedback > that it didn't send() correctly. You'll see the reset on the next read but > you don't know what happened to the data. > #2 - You send() data and overrun your IP queue -- nobody will ever know the > difference without a layer 7 protocol (or int the case quoted in this > subject it might lock up). > #3 - You send() data and either machine has bad RAM and flips a bit -- guess > what? -- data corruption. > > Even when you do layer 7 (with checksums and ack/nak) you make assumptions: > > #1 - You checksum the packet you just received -- what's to say a bit can't > flip? > > TCP may be guaranteed at layer 5 but we don't typically program at layer > 5 -- we program at layer 7 and then lots of people assume they're doing it > at layer 5 -- ergo the problems. Layers above layer 4 provide additionnal services for applications but they assume that layer 4 is reliable. In other words, a broken transport layer breaks all layers above it and thus the applications. In fact, when you build your application above layer 4 and need services normally provided by upper OSI layers, you have to implement equivalent services in your application, using layered protocols or not. > To look at it another way -- "Just 'cuz I told my C library to send a packet > doesn't mean it's going to work". > For example, if you're using non-blocking sockets you have to check to > ensure there's room in your IP queue to transmit. That's API semantic issue, not protocol issue. Gérard. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 18:27 ` Mike Black 2001-06-15 18:39 ` Gérard Roudier @ 2001-06-15 19:12 ` Alan Cox 2001-06-17 18:17 ` Pavel Machek 1 sibling, 1 reply; 29+ messages in thread From: Alan Cox @ 2001-06-15 19:12 UTC (permalink / raw) To: Mike Black; +Cc: Heusden Folkert van, linux-kernel > TCP is guaranteed delivery at layer 5 -- but that's all -- not a "guaranteed > protocol" For certain specific cases this is in itself not true either. Also for many many implementations. Specifically 1. If the receiver closes and there is unread data many TCP's forget to RST the sender to indicate that data was lost. 2. There is a flaw in the TCP protocol itself that is extremely unlikely to bite people but can in theory cause wrong data in some unusual circumstances that Ian Heavans found and has yet to be fixed by the keepers of the protocol. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 19:12 ` Alan Cox @ 2001-06-17 18:17 ` Pavel Machek 2001-06-17 19:32 ` Alan Cox 2001-06-17 19:40 ` Dan Podeanu 0 siblings, 2 replies; 29+ messages in thread From: Pavel Machek @ 2001-06-17 18:17 UTC (permalink / raw) To: Alan Cox, Mike Black; +Cc: Heusden Folkert van, linux-kernel Hi! > Specifically > 1. If the receiver closes and there is unread data many TCP's forget > to RST the sender to indicate that data was lost. Do at least FreeBSD, Solaris and NT sent RST correctly? > 2. There is a flaw in the TCP protocol itself that is extremely unlikely > to bite people but can in theory cause wrong data in some unusual > circumstances that Ian Heavans found and has yet to be fixed by > the keepers of the protocol. This is interesting; where are details? Pavel -- I'm pavel@ucw.cz. "In my country we have almost anarchy and I don't care." Panos Katsaloulis describing me w.r.t. patents at discuss@linmodems.org ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-17 18:17 ` Pavel Machek @ 2001-06-17 19:32 ` Alan Cox 2001-06-17 19:40 ` Dan Podeanu 1 sibling, 0 replies; 29+ messages in thread From: Alan Cox @ 2001-06-17 19:32 UTC (permalink / raw) To: Pavel Machek; +Cc: Alan Cox, Mike Black, Heusden Folkert van, linux-kernel > > Specifically > > 1. If the receiver closes and there is unread data many TCP's forget > > to RST the sender to indicate that data was lost. > > Do at least FreeBSD, Solaris and NT sent RST correctly? I dont believe so > > 2. There is a flaw in the TCP protocol itself that is extremely unlikely > > to bite people but can in theory cause wrong data in some unusual > > circumstances that Ian Heavans found and has yet to be fixed by > > the keepers of the protocol. > > This is interesting; where are details? http://www.schooner.com/~loverso/Public/Internet-Drafts/draft-heavens-problems-rsts-00.txt Yes a 1996 tcp protocol flaw that still hasnt been fixed. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-17 18:17 ` Pavel Machek 2001-06-17 19:32 ` Alan Cox @ 2001-06-17 19:40 ` Dan Podeanu [not found] ` <200106172113.f5HLDhJ377473@saturn.cs.uml.edu> 2001-06-17 22:35 ` dean gaudet 1 sibling, 2 replies; 29+ messages in thread From: Dan Podeanu @ 2001-06-17 19:40 UTC (permalink / raw) To: Pavel Machek; +Cc: linux-kernel On Sun, Jun 17, 2001 at 08:17:27PM +0200, Pavel Machek wrote: > > 2. There is a flaw in the TCP protocol itself that is extremely unlikely > > to bite people but can in theory cause wrong data in some unusual > > circumstances that Ian Heavans found and has yet to be fixed by > > the keepers of the protocol. Bit offtopic. Is there any logical reason why if, given fd is a connected, AF_INET, SOCK_STREAM socket, and one does a write(fd, buffer, len); close(fd); to the peer, over a rather slow network (read modem, satelite link, etc), the data gets lost (the remote receives the disconnect before the last packet). According to socket(7), even if SO_LINGER is not set, the data is flushed in the background. Is it Linux or TCP specific? Or some obvious techincal detail I'm missing? Thanks, Dan. ^ permalink raw reply [flat|nested] 29+ messages in thread
[parent not found: <200106172113.f5HLDhJ377473@saturn.cs.uml.edu>]
* Re: Client receives TCP packets but does not ACK [not found] ` <200106172113.f5HLDhJ377473@saturn.cs.uml.edu> @ 2001-06-17 22:09 ` Dan Podeanu 0 siblings, 0 replies; 29+ messages in thread From: Dan Podeanu @ 2001-06-17 22:09 UTC (permalink / raw) To: Albert D. Cahalan; +Cc: linux-kernel On Sun, Jun 17, 2001 at 05:13:43PM -0400, Albert D. Cahalan wrote: > > Is there any logical reason why if, given fd is a connected, AF_INET, > > SOCK_STREAM socket, and one does a write(fd, buffer, len); close(fd); > > to the peer, over a rather slow network (read modem, satelite link, etc), > > the data gets lost (the remote receives the disconnect before the last > > packet). According to socket(7), even if SO_LINGER is not set, the data > > is flushed in the background. > > > > Is it Linux or TCP specific? Or some obvious techincal detail I'm missing? > > The UNIX API (Linux, BSD, Solaris, OSF/1...) requires that you > put that write() call in a loop, because you can get partial > writes. Repeat until done... the OS might do 1 byte at a time. Not so true. The write is completed successfuly, ie. size == write(fd, buf, size); so the data actually gets to the kernel's network buffer, only the background polling is not done properly, in the way I see things. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-17 19:40 ` Dan Podeanu [not found] ` <200106172113.f5HLDhJ377473@saturn.cs.uml.edu> @ 2001-06-17 22:35 ` dean gaudet 1 sibling, 0 replies; 29+ messages in thread From: dean gaudet @ 2001-06-17 22:35 UTC (permalink / raw) To: Dan Podeanu; +Cc: Pavel Machek, linux-kernel On Sun, 17 Jun 2001, Dan Podeanu wrote: > Is there any logical reason why if, given fd is a connected, AF_INET, > SOCK_STREAM socket, and one does a write(fd, buffer, len); close(fd); > to the peer, over a rather slow network (read modem, satelite link, etc), > the data gets lost (the remote receives the disconnect before the last > packet). According to socket(7), even if SO_LINGER is not set, the data > is flushed in the background. suppose A writes B, and A closes its fd. suppose that B writes to A and it arrives at A before the A->B data has left the buffer. in that case A will RST and drop the data in its buffer, so you've lost the data you thought you had transmitted. > Is it Linux or TCP specific? Or some obvious techincal detail I'm missing? it's TCP. the linux specific behaviour (and the recommended behaviour now) is that above if the B->A traffic arrived before the close, but wasn't read by the application on A, then the RST will be sent immediately. this generally results in folks discovering their broken applications much earlier than on other stacks. it's basically a race condition as to when the B->A data arrives. the above is the reason apache uses at least 4 system calls to tear down a connection... with http/1.1 and pipelining it's totally valid for the B->A traffic to be sent regardless of what's happening in the A->B direction. (ditto for multiplexed protocols... and to some extent SMTP pipelining.) -dean ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-15 12:53 Heusden, Folkert van 2001-06-15 18:27 ` Mike Black @ 2001-06-18 11:50 ` Jan Hudec 2001-06-18 16:17 ` dean gaudet 2001-06-20 21:01 ` David Schwartz 1 sibling, 2 replies; 29+ messages in thread From: Jan Hudec @ 2001-06-18 11:50 UTC (permalink / raw) To: linux-kernel > > TCP is NOT a guaranteed protocol -- you can't just blast data from one > port > > to another and expect it to work. > > Isn't it? Are you really sure about that? I thought UDP was the > not-guaranteed-one and TCP was the one guaranting that all data reaches the > other end in order and all. Please enlighten me. It's "hlaf guaranteed." It guarantees, that if data are delivered to the reciever, all data sent before already arived and in correct order. But it's not guaranteed that data succesuly writen on 1 end actualy arived unless the connection was correctly shutdown and closed. Btw: can the aplication somehow ask the tcp/ip stack what was actualy acked? (ie. how many bytes were acked). -------------------------------------------------------------------------------- - Jan Hudec `Bulb' <bulb@ucw.cz> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-18 11:50 ` Jan Hudec @ 2001-06-18 16:17 ` dean gaudet 2001-06-18 16:48 ` Jonathan Morton 2001-06-20 21:01 ` David Schwartz 1 sibling, 1 reply; 29+ messages in thread From: dean gaudet @ 2001-06-18 16:17 UTC (permalink / raw) To: Jan Hudec; +Cc: linux-kernel On Mon, 18 Jun 2001, Jan Hudec wrote: > Btw: can the aplication somehow ask the tcp/ip stack what was actualy acked? > (ie. how many bytes were acked). no, but it's not necessarily a useful number anyhow -- because it's possible that the remote end ACKd bytes but the ACK never arrives. so you can get into a situation where the remote application has the entire message but the local application doesn't know. the only way to solve this is above the TCP layer. (message duplicate elimination using an unique id.) if the #bytes ack'd was available it would probably fool people into implementing buggy code (which of course they do anyhow :) -dean ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-18 16:17 ` dean gaudet @ 2001-06-18 16:48 ` Jonathan Morton 2001-06-18 22:30 ` dean gaudet 0 siblings, 1 reply; 29+ messages in thread From: Jonathan Morton @ 2001-06-18 16:48 UTC (permalink / raw) To: dean gaudet, Jan Hudec; +Cc: linux-kernel > > Btw: can the aplication somehow ask the tcp/ip stack what was >actualy acked? >> (ie. how many bytes were acked). > >no, but it's not necessarily a useful number anyhow -- because it's >possible that the remote end ACKd bytes but the ACK never arrives. so you >can get into a situation where the remote application has the entire >message but the local application doesn't know. the only way to solve >this is above the TCP layer. (message duplicate elimination using an >unique id.) No, because if the ACK doesn't reach the sending machine, the sender will retry the data until it does get an ACK. So the sender always has information about some amount of data which is guaranteed to have arrived at the other end. The receiver might know about this sooner, but that's simply a function of network latency. The fundamental problem, if I understand right, is that some stacks allow packets indicating closing of a connection (FIN) to arrive before the actual data at the end of the connection does. The only workaround I can think of for this is for the closing stack to wait until all sent data has been ACKed before sending the FIN. The ACK may, of course, never arrive, but that's what round-trip timeouts are for. -- -------------------------------------------------------------- from: Jonathan "Chromatix" Morton mail: chromi@cyberspace.org (not for attachments) website: http://www.chromatix.uklinux.net/vnc/ geekcode: GCS$/E dpu(!) s:- a20 C+++ UL++ P L+++ E W+ N- o? K? w--- O-- M++$ V? PS PE- Y+ PGP++ t- 5- X- R !tv b++ DI+++ D G e+ h+ r++ y+(*) tagline: The key to knowledge is not to rely on people to teach you it. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-18 16:48 ` Jonathan Morton @ 2001-06-18 22:30 ` dean gaudet 2001-06-18 23:43 ` Jonathan Morton 0 siblings, 1 reply; 29+ messages in thread From: dean gaudet @ 2001-06-18 22:30 UTC (permalink / raw) To: Jonathan Morton; +Cc: Jan Hudec, linux-kernel On Mon, 18 Jun 2001, Jonathan Morton wrote: > > > Btw: can the aplication somehow ask the tcp/ip stack what was > >actualy acked? > >> (ie. how many bytes were acked). > > > >no, but it's not necessarily a useful number anyhow -- because it's > >possible that the remote end ACKd bytes but the ACK never arrives. so you > >can get into a situation where the remote application has the entire > >message but the local application doesn't know. the only way to solve > >this is above the TCP layer. (message duplicate elimination using an > >unique id.) > > No, because if the ACK doesn't reach the sending machine, the sender > will retry the data until it does get an ACK. if the network goes down in between, the sender may never get the ACK. the sender will see a timeout eventually. the receiver may already be done with the connection and closed it and never see the error. if it were a protocol such as SMTP then the sender would retry later, and the result would be a duplicate message. (which you can eliminate above the TCP layer using unique ids.) -dean ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-18 22:30 ` dean gaudet @ 2001-06-18 23:43 ` Jonathan Morton 2001-06-19 2:46 ` dean gaudet 0 siblings, 1 reply; 29+ messages in thread From: Jonathan Morton @ 2001-06-18 23:43 UTC (permalink / raw) To: dean gaudet; +Cc: Jan Hudec, linux-kernel > > > > Btw: can the aplication somehow ask the tcp/ip stack what was >> >actualy acked? >> >> (ie. how many bytes were acked). >> > >> >no, but it's not necessarily a useful number anyhow -- because it's >> >possible that the remote end ACKd bytes but the ACK never arrives. so you >> >can get into a situation where the remote application has the entire >> >message but the local application doesn't know. the only way to solve >> >this is above the TCP layer. (message duplicate elimination using an >> >unique id.) >> >> No, because if the ACK doesn't reach the sending machine, the sender >> will retry the data until it does get an ACK. > >if the network goes down in between, the sender may never get the ACK. >the sender will see a timeout eventually. the receiver may already be >done with the connection and closed it and never see the error. if it >were a protocol such as SMTP then the sender would retry later, and the >result would be a duplicate message. (which you can eliminate above the >TCP layer using unique ids.) But, if the sender does not attempt to close the socket until the ACK returns, then the receiver will see an unfinished connection and (hopefully) realise that the message is unsafe and not attempt to send it. With SMTP, the last piece of data is a QUIT anyway, which occurs after the end-of-message marker - once the QUIT is sent and/or received, both ends know that the connection is finished with and will close the socket independently of each other. If the network disappears before the QUIT comes along, the receiver should be discarding messages and the sender retrying later. -- -------------------------------------------------------------- from: Jonathan "Chromatix" Morton mail: chromi@cyberspace.org (not for attachments) website: http://www.chromatix.uklinux.net/vnc/ geekcode: GCS$/E dpu(!) s:- a20 C+++ UL++ P L+++ E W+ N- o? K? w--- O-- M++$ V? PS PE- Y+ PGP++ t- 5- X- R !tv b++ DI+++ D G e+ h+ r++ y+(*) tagline: The key to knowledge is not to rely on people to teach you it. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-06-18 23:43 ` Jonathan Morton @ 2001-06-19 2:46 ` dean gaudet 0 siblings, 0 replies; 29+ messages in thread From: dean gaudet @ 2001-06-19 2:46 UTC (permalink / raw) To: Jonathan Morton; +Cc: Jan Hudec, linux-kernel On Tue, 19 Jun 2001, Jonathan Morton wrote: > > > > > Btw: can the aplication somehow ask the tcp/ip stack what was > >> >actualy acked? > >> >> (ie. how many bytes were acked). > >> > > >> >no, but it's not necessarily a useful number anyhow -- because it's > >> >possible that the remote end ACKd bytes but the ACK never arrives. so you > >> >can get into a situation where the remote application has the entire > >> >message but the local application doesn't know. the only way to solve > >> >this is above the TCP layer. (message duplicate elimination using an > >> >unique id.) > >> > >> No, because if the ACK doesn't reach the sending machine, the sender > >> will retry the data until it does get an ACK. > > > >if the network goes down in between, the sender may never get the ACK. > >the sender will see a timeout eventually. the receiver may already be > >done with the connection and closed it and never see the error. if it > >were a protocol such as SMTP then the sender would retry later, and the > >result would be a duplicate message. (which you can eliminate above the > >TCP layer using unique ids.) > > But, if the sender does not attempt to close the socket until the ACK > returns, then the receiver will see an unfinished connection and > (hopefully) realise that the message is unsafe and not attempt to > send it. suppose the network goes away and doesn't come back. the ACK never gets through. > With SMTP, the last piece of data is a QUIT anyway, which occurs > after the end-of-message marker - once the QUIT is sent and/or > received, both ends know that the connection is finished with and > will close the socket independently of each other. If the network > disappears before the QUIT comes along, the receiver should be > discarding messages and the sender retrying later. QUIT is the last step of a session which can include multiple messages. a single message begins with the "MAIL FROM:<foo>" and ends with the . that terminates the DATA section. after that the smtp server sends back the "250 OK". the smtp client is now free to sit on the connection "forever", possibly beginning another "MAIL FROM:<foo>". (i.e. connection caching in sendmail.) but in the meanwhile, the smtp server has moved the message into its next phase of delivery as soon as it sends back the "250 OK", which could include having forwarded it off the box, or to a mailing list, etc. so in this example where you want to consider network failure is after the smtp client has sent the trailing "." closing the DATA section, and that data has been received by the smtp server. then the network fails before the ACK (and "250 OK") returns to the smtp client. in this case the client has no choice but to resend later. (both sides should get an error eventually assuming the implementors don't suck, unlike in some other protocols such as HTTP/0.9 and HTTP/1.0 where the protocol itself is flawed.) the result is probably a message duplicate. so what you were asking about was, what if the smtp server in this case could find out that the "250 OK" was never ACKd. in that case just move the network failure a little later in the series of events... and also consider cases where the TCP stack ACKs but the application never gets to read() the data (system failures). basically these transactional semantics have to occur above TCP/IP itself. this is where QUIT comes in. and to some extent, message-IDs for duplicate elimination. (in HTTP/1.1 the introduction of chunked transfer encoding to handle variable length dynamic responses in the face of network failures... but folks building web forms still need to put unique-ids into the forms to handle the duplicate message problem.) i guess knowing the number of ACK'd bytes might be a useful debugging aid, but i'd fear it being misused by app writers. -dean ^ permalink raw reply [flat|nested] 29+ messages in thread
* RE: Client receives TCP packets but does not ACK 2001-06-18 11:50 ` Jan Hudec 2001-06-18 16:17 ` dean gaudet @ 2001-06-20 21:01 ` David Schwartz 1 sibling, 0 replies; 29+ messages in thread From: David Schwartz @ 2001-06-20 21:01 UTC (permalink / raw) To: Jan Hudec, linux-kernel > Btw: can the aplication somehow ask the tcp/ip stack what was > actualy acked? > (ie. how many bytes were acked). No, and you shouldn't want to know. Even if the other end ACKed the data, that doesn't mean that the application on the other end didn't crash. So it won't tell you what you want to know, which is 'did the application on the other end process the data?'. Application-level guarantees can only be provided by application-level code. DS ^ permalink raw reply [flat|nested] 29+ messages in thread
[parent not found: <E15BiHy-0002xC-00@the-village.bc.nu.suse.lists.linux.kernel>]
* Re: Client receives TCP packets but does not ACK [not found] <E15BiHy-0002xC-00@the-village.bc.nu.suse.lists.linux.kernel> @ 2001-06-17 20:21 ` Andi Kleen 0 siblings, 0 replies; 29+ messages in thread From: Andi Kleen @ 2001-06-17 20:21 UTC (permalink / raw) To: Alan Cox; +Cc: linux-kernel Alan Cox <alan@lxorguk.ukuu.org.uk> writes: > > > Specifically > > > 1. If the receiver closes and there is unread data many TCP's forget > > > to RST the sender to indicate that data was lost. > > > > Do at least FreeBSD, Solaris and NT sent RST correctly? > > I dont believe so There is also a different bug in Linux that makes the application not notice errors. When it does a close() and an error occurs while flushing buffered data and doing the FIN handshake it is not returned by close() (no matter if linger time hits or not). Most transaction applications like SMTP fortunately use an own ACKing protocol, which works around that. -Andi ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK @ 2001-07-01 21:27 Nivedita Singhvi 2001-07-11 3:43 ` Robert Kleemann 0 siblings, 1 reply; 29+ messages in thread From: Nivedita Singhvi @ 2001-07-01 21:27 UTC (permalink / raw) To: robert; +Cc: linux-kernel > The bad network behavior was due to shared irqs somehow screwing > things up. This explained most but not all of the problems. ah, that's why your test pgm succeeded on my systems.. > When I last posted I had a reproducible test case which spewed a bunch > of packets from a server to a client. The behavior is that the client > eventually stops ACKing and so the the connection stalls indefinitely. > packet. I added printk statements for each of these conditions in > hopes of detecting why the final packet is not acked. I recompiled > the kernel, and reran the test. The result was that the packet was > being droped in tcp_rcv_established() due to an invalid checksum. I Ouch! In the interests of not having it be so painful to identify the problem (to this point, i.e. TCP drops due to checksum failures) the next time around, I'd like to ask: - Were you seeing any bad csum error messages in /var/log/messages? i.e. or else was it only TCP? - Was the stats field /proc/net/snmp/Tcp:InErrs reflecting those drops? - What additional logging/stats gathering would have made this (silent drops due to checksum failures by TCP) easier to detect? My 2c: The stat TcpInErrs is updated for most TCP input failures. So its not obvious (unless youre real familiar with TCP) that there are checksum failures happening. It actually includes only these errors: - checksum failures - header len problems - unexpected SYN's Is this adequate as a diagnostic, or would adding a breakdown counter(s) for checksum (and other) failures be useful? At the moment, there is no logging TCP does on a plain vanilla kernel, you have to recompile the kernel with NETDEBUG in order to see logged checksum failures, at least at the TCP level. It would be nice to have people be able to look at a counter or stat on the fly and tell whether they're having packets silently dropped due to checksum failures (and other issues) without needing to recompile the kernel... Any thoughts? thanks, Nivedita --- I'd appreciate a cc since I'm not subscribed.. nivedita@sequent.com nivedita@us.ibm.com ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: Client receives TCP packets but does not ACK 2001-07-01 21:27 Nivedita Singhvi @ 2001-07-11 3:43 ` Robert Kleemann 0 siblings, 0 replies; 29+ messages in thread From: Robert Kleemann @ 2001-07-11 3:43 UTC (permalink / raw) To: Nivedita Singhvi; +Cc: linux-kernel I'm not sure if an extra tcp error would have helped me with this. I would still have had to learn the details of tcp (acks, delayed acks, checksum, buffers) in order to learn that a tcp checksum problem could have produced the behavior I was seeing. An error notifying me of irq conflicts would have _really_ helped. Robert. ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2001-07-11 3:43 UTC | newest] Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2001-06-13 0:26 Client receives TCP packets but does not ACK Robert Kleemann 2001-06-15 3:50 ` Robert Kleemann 2001-06-15 12:44 ` Mike Black 2001-06-15 18:29 ` Albert D. Cahalan 2001-06-15 23:10 ` Robert Kleemann 2001-06-16 11:55 ` Mike Black 2001-06-16 23:56 ` Robert Kleemann 2001-06-27 1:04 ` Robert Kleemann [not found] <Pine.LNX.4.33.0106121720310.1152-100000@localhost.localdomain.suse.lists.linux.kernel> 2001-06-13 8:48 ` Andi Kleen 2001-06-13 16:09 ` Robert Kleemann 2001-06-15 12:53 Heusden, Folkert van 2001-06-15 18:27 ` Mike Black 2001-06-15 18:39 ` Gérard Roudier 2001-06-15 19:12 ` Alan Cox 2001-06-17 18:17 ` Pavel Machek 2001-06-17 19:32 ` Alan Cox 2001-06-17 19:40 ` Dan Podeanu [not found] ` <200106172113.f5HLDhJ377473@saturn.cs.uml.edu> 2001-06-17 22:09 ` Dan Podeanu 2001-06-17 22:35 ` dean gaudet 2001-06-18 11:50 ` Jan Hudec 2001-06-18 16:17 ` dean gaudet 2001-06-18 16:48 ` Jonathan Morton 2001-06-18 22:30 ` dean gaudet 2001-06-18 23:43 ` Jonathan Morton 2001-06-19 2:46 ` dean gaudet 2001-06-20 21:01 ` David Schwartz [not found] <E15BiHy-0002xC-00@the-village.bc.nu.suse.lists.linux.kernel> 2001-06-17 20:21 ` Andi Kleen 2001-07-01 21:27 Nivedita Singhvi 2001-07-11 3:43 ` Robert Kleemann
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).