Netdev List
 help / color / mirror / Atom feed
* Re: TCP: orphans broken by RFC 2525 #2.17
From: David Miller @ 2010-09-26 23:08 UTC (permalink / raw)
  To: w; +Cc: netdev
In-Reply-To: <20100926225440.GH12373@1wt.eu>

From: Willy Tarreau <w@1wt.eu>
Date: Mon, 27 Sep 2010 00:54:40 +0200

> On Sun, Sep 26, 2010 at 03:38:32PM -0700, David Miller wrote:
>> From: Willy Tarreau <w@1wt.eu>
>> Date: Mon, 27 Sep 2010 00:34:48 +0200
>> 
>> > I don't see what is being violated nor what reliability has been
>> > compromised.
>> 
>> The TCP protcol's obligation to reliably deliver data between
>> two applications, that is what has been violated.
> 
> Once again, I don't see why, due to the orphans mechanism. Please
> consider for a minute that the application-level close() is distinct
> from the protocol-level close. The application-level close() just
> instructs the lower layer to turn the connection into an orphan.

A close() is equivalent to a shutdown() with both the send and
receive masks set.

You are telling TCP that you expect no more data to be received.

^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Willy Tarreau @ 2010-09-26 22:54 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20100926.153832.115943505.davem@davemloft.net>

On Sun, Sep 26, 2010 at 03:38:32PM -0700, David Miller wrote:
> From: Willy Tarreau <w@1wt.eu>
> Date: Mon, 27 Sep 2010 00:34:48 +0200
> 
> > I don't see what is being violated nor what reliability has been
> > compromised.
> 
> The TCP protcol's obligation to reliably deliver data between
> two applications, that is what has been violated.

Once again, I don't see why, due to the orphans mechanism. Please
consider for a minute that the application-level close() is distinct
from the protocol-level close. The application-level close() just
instructs the lower layer to turn the connection into an orphan. Any
pending data is sent. Incoming data may accumulate until the receive
buffer is full, but at least the other end regularly acks what is
being sent. Then once the other end has acked the orphaned data, we
perform the protocol-level close, which consists in either switching
the connection to TIME_WAIT if there are no pending data, or to send
an RST if there are pending data.

> You don't have to like this, but you certainly must cope with it
> in your applications :-)

It's not a matter of liking it or not, but to use something reliable.
Orphans are supposed to be (as long as there aren't any memory shortage).
But they're not. And my concern is that the information that my app
could make use for a reliable close exists in the kernel but is not
usable from the application level.

In fact, the end result is that we're observing exactly the opposite
of what RFC2525 wanted to achieve : their goal was to perform early
resets on aborts in order not to have to transfer too many data, but
the way we have it makes it mandatory to read everything because some
information is lost between the kernel and the application.

Willy


^ permalink raw reply

* Re: [PATCH] de2104x: fix TP link detection
From: David Miller @ 2010-09-26 22:52 UTC (permalink / raw)
  To: jgarzik; +Cc: linux, netdev, linux-kernel
In-Reply-To: <AANLkTikasuZbf6ymCWBjAW3oq7+BBox1N06jPZqTBQr4@mail.gmail.com>

From: Jeff Garzik <jgarzik@pobox.com>
Date: Sat, 25 Sep 2010 16:58:10 -0400

> Acked-by: Jeff Garzik <jgarzik@redhat.com>

Applied, thanks guys.

^ permalink raw reply

* Re: de2104x: fix power management
From: David Miller @ 2010-09-26 22:49 UTC (permalink / raw)
  To: jgarzik; +Cc: linux, netdev, linux-kernel
In-Reply-To: <4C9E2E88.3080101@pobox.com>

From: Jeff Garzik <jgarzik@pobox.com>
Date: Sat, 25 Sep 2010 13:16:56 -0400

> On 09/25/2010 05:57 AM, Ondrej Zary wrote:
>> At least my 21041 cards come out of suspend with bus mastering
>> disabled so
>> they did not work after resume(no data transferred).
>> After adding pci_set_master(), the driver oopsed immediately on resume
>> -
>> because de_clean_rings() is called on suspend but de_init_rings() call
>> was missing in resume.
>>
>> Also disable link (reset SIA) before sleep (de4x5 does this too).
>>
>> Signed-off-by: Ondrej Zary<linux@rainbow-software.org>
 ...
> Acked-by: Jeff Garzik <jgarzik@redhat.com>

I'll apply this, thanks guys.

> IMO suspend/resume could use another look; if netif_running is false
> (interface is down), de2104x does not put the PCI device to sleep,
> which seems strange.

TG3 does the same.

The reason is that until we bringing the device up (and thus
netif_running becomes true) the device is left in the most appropriate
powered down state.

At least that is my understanding.

What is appropriate for any driver in this situation depends upon how
it programs the device before ->open() occurs.

> I also wonder if rtnl_lock() couldn't be eliminated, as other net
> drivers don't need it in suspend/resume.

I suspect the RTNL stuff here can be safely removed.

I think it's using it to guard the netif_running() check but that
isn't necessary.

^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: David Miller @ 2010-09-26 22:38 UTC (permalink / raw)
  To: w; +Cc: netdev
In-Reply-To: <20100926223448.GF12373@1wt.eu>

From: Willy Tarreau <w@1wt.eu>
Date: Mon, 27 Sep 2010 00:34:48 +0200

> I don't see what is being violated nor what reliability has been
> compromised.

The TCP protcol's obligation to reliably deliver data between
two applications, that is what has been violated.

You don't have to like this, but you certainly must cope with it
in your applications :-)

^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Willy Tarreau @ 2010-09-26 22:34 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20100926.151346.112585478.davem@davemloft.net>

Hi David,

On Sun, Sep 26, 2010 at 03:13:46PM -0700, David Miller wrote:
> From: Willy Tarreau <w@1wt.eu>
> Date: Sun, 26 Sep 2010 15:17:17 +0200
> 
> > I've read RFC 2525 #2.17 and it shows quite interesting examples of what
> > it wanted to protect against. However, the recommendation did not consider
> > the fact that there could be some unacked pending data in the outgoing
> > buffers.
> 
> It doesn't matter if there is any pending data still outgoing when
> we received this data after close().
> 
> The issue is that the reliable transport nature of TCP has been
> violated, and as such the entire connection's reliability has
> been compromised.

I don't see what is being violated nor what reliability has been
compromised. Some data has reliably been delivered to the kernel,
a shutdown() has reliably been performed, followed by a close()
which then makes use of the orphans mechanism to deliver the data
to the other side.

> The only appropriate response is a full reset.

I'm not against the full reset, I really want it, but I don't want
it to be sent before the previous data. The reset here is being sent
out of order and kills the data that were previously going to be
delivered. It's all about a timing issue BTW. If the other side sends
its data slightly later, it reliably receives its response followed by
a reset it understands and respects. So this is a valid working
mechanism. I'm just trying to ensure that the reset does not break
ordering and is delivered after the pending data.

> As Eric said, your only option is to fully sync the data coming
> from the peer.

The why are we keeping the orphans feature and not get rid of it then ?
It becomes completely useless, and we can as well disable all the
lingering options which have no use beyond that.

The lingering controls how long unacked data remains in an orphaned
socket, which precisely is my case. If the application has no way to
know whether it can close, all this becomes useless.

I can easily admit I'm doing something wrong, but here we have a
feature that I think I'm correctly using and it does not always
work, and I can't know when I can use it, so I should not use it.
Obviously, either I'm missing something or there's something wrong.
And that's what I'd like to find out.

Thanks,
Willy


^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: David Miller @ 2010-09-26 22:19 UTC (permalink / raw)
  To: w; +Cc: eric.dumazet, netdev
In-Reply-To: <20100926214614.GD12373@1wt.eu>

From: Willy Tarreau <w@1wt.eu>
Date: Sun, 26 Sep 2010 23:46:14 +0200

> Eventhough we optimize for the most common cases, that doesn't save us
> from having to support the legacy cases.

There is nothing "legacy" about performing a proper reset when data
was lost.

Otherwise the peer has every right to believe that the data it sent
was sinked all the way to the remote application.

Which it wasn't.

Reset is the only appropriate action in this situation.

If the application layer protocol you're dealing with is so broken
that a multi-megabyte transfer happens even when it gets an error
indication, that really isn't the kernels problem and it is very clear
where the "fix" lies and that in the application layer proptocol and
handling.

^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: David Miller @ 2010-09-26 22:14 UTC (permalink / raw)
  To: w; +Cc: eric.dumazet, netdev
In-Reply-To: <20100926191632.GB13046@1wt.eu>

From: Willy Tarreau <w@1wt.eu>
Date: Sun, 26 Sep 2010 21:16:32 +0200

> On Sun, Sep 26, 2010 at 07:40:15PM +0200, Willy Tarreau wrote:
>> 3) when an ACK comes from the other side, either it's below our last
>>    seq, and we simply ignore it, just as if we were in TIME_WAIT, or
>>    it is equal to the last seq and indicates that it's now safe to
>>    reset ; we would then just send the RST to notify the other side
>>    that the data it sent were not read. The connection can then either
>>    be destroyed or put in TIME_WAIT. It's the point where the connection
>>    normally switches from FIN_WAIT1 to FIN_WAIT2, since the FIN has been
>>    acked. The only difference is that we don't need a FIN_WAIT2 state
>>    for an orphan.
> 
> In fact, the following patch seems to provide the expected result :

There is no way I'm applying this.

Pending outgoing data means nothing, and not sending out the RST is
wrong because there will be no notification to the peer that you
decided to close and ignore the data stream the peer sent, and thus
data was lost.

^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: David Miller @ 2010-09-26 22:13 UTC (permalink / raw)
  To: w; +Cc: netdev
In-Reply-To: <20100926131717.GA13046@1wt.eu>

From: Willy Tarreau <w@1wt.eu>
Date: Sun, 26 Sep 2010 15:17:17 +0200

> I've read RFC 2525 #2.17 and it shows quite interesting examples of what
> it wanted to protect against. However, the recommendation did not consider
> the fact that there could be some unacked pending data in the outgoing
> buffers.

It doesn't matter if there is any pending data still outgoing when
we received this data after close().

The issue is that the reliable transport nature of TCP has been
violated, and as such the entire connection's reliability has
been compromised.

The only appropriate response is a full reset.

As Eric said, your only option is to fully sync the data coming
from the peer.

^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: David Miller @ 2010-09-26 22:10 UTC (permalink / raw)
  To: w; +Cc: eric.dumazet, netdev
In-Reply-To: <20100926184914.GC12373@1wt.eu>


TCP is a reliable transport.

If you choose to close before the data from the peer has been fully
received, you've subverted the reliability of the data transport.

Reset is the only reasonable action in this situation.

^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Willy Tarreau @ 2010-09-26 21:46 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1285534871.2357.19.camel@edumazet-laptop>

On Sun, Sep 26, 2010 at 11:01:11PM +0200, Eric Dumazet wrote:
> Le dimanche 26 septembre 2010 à 20:49 +0200, Willy Tarreau a écrit :
> > On Sun, Sep 26, 2010 at 08:35:15PM +0200, Eric Dumazet wrote:
> > > I was referring to this code. It works well for me.
> > > 
> > > shutdown(fd, SHUT_RDWR);
> > > while (recv(fd, buff, sizeof(buff), 0) > 0)
> > > 	;
> > > close(fd);
> > 
> > Ah this one yes, but it's overkill. We're actively pumping data from the
> > other side to drop it on the floor until it finally closes while we only
> > need to know when it has ACKed the FIN. In practice, doing that on a POST
> > request which causes a 302 or 401 will result in the whole amount of data
> > being transferred twice. Not only this is bad for the bandwidth, this is
> > also bad for the user, as we're causing him to experience a complete upload
> > twice, just to be sure it has received the FIN, while it's pretty obvious
> > that it's not necessary in 99.9% of the cases.
> > 
> 
> I dont understand how recv() could transfert data twice.

That's not what I said, I said the client would have to retransfer. Here's
what typically happens, for instance with an authentication requirement :

Client                                Server
           SYN ----------->
               <----------- SYN/ACK
           ACK ----------->

POST /some_url HTTP/1.1
Host: xxx
Content-length: 10 meg
             ------ headers are sent ---->
xxxxxxxxxxxxx
xxxxxxxxxxxxx ----- data are being sent ->  HTTP/1.1 401 forbidden
xxxxxxxxxxxxx                               WWW-Authenticate: basic realm="xxx"
...                                         Connection: close
             <----------------------------
xxxxxxxxxxxxx
             <---------------------------- FIN
xxxxxxxxxxxxx
...
10 megs of data being sent and drained by the server
xxxxxxxxxxxxx
             FIN --------------->
                 <--------------  ACK


second attempt with credentials this time

           SYN ----------->
               <----------- SYN/ACK
           ACK ----------->

POST /some_url HTTP/1.1
Host: x
authorization: basic xyz
Content-length: 10 meg
             ------ headers are sent ---->
xxxxxxxxxxxxx
xxxxxxxxxxxxx
xxxxxxxxxxxxx
etc...


So in this case the data is effectively transmitted twice. With an
RST once the client acks the FIN, the first transfer aborts very
early instead, saving half of the bandwidth.

> You only read from the socket receive queue to null buffer, and in most
> cases a single recv() call will be enough to drain the queue.

Indeed, in *most* cases, and just as right now in most cases there is no
problem. As I said, that's the first reported issue in 10 years and hundreds
of billions of connections cumulated on various sites. But instead of really
fixing the issue, it just reduces its occurrences. Also, it does only work
for low bandwidth clients (most common case too). That's what I'm going to
implement anyway, but this is an unreliable workaround. All I know is that
it will probably divide by 10 the number of times this problem is encountered
but it will not fix it.

> > Since this method is the least efficient one and clearly not acceptable
> > for practical cases, I wanted to dig at the root, where the information
> > is known. And the TCP recv code is precisely the place where we know
> > exactly when it's safe to reset.
> > 
> 
> And its safe to reset exactly when application just does close(), if
> unread data was not drained. Not only its safe, but required. A new RFC
> might be needed ?

I'm not requesting a new RFC, but I'm just trying to make a correct use
of orphans as implemented in the Linux stack, and I'm realizing that
since RFC2525 was implemented, orphans cannot be relied on at all anymore.
We can simply delete all the orphans code and emit an RST immediately upon
close(), there is no safe use of them now. And that's my concern. In my
opinion, the code is there and was written precisely for that usage. Since
I'm seeing that it can't be used for what it's designed for, I'm naturally
interested in trying to get it usable again. And in fact, when I really
want an RST, I can already have one by disabling lingering before the
close(). This too shows that the default close() by default protects
orphaned data.

> > Also there's another issue in doing this. It requires polling of the
> > receive side for all requests, which adds one epoll_ctl() syscall and
> > one recv() call, which have a much noticeable negative performance
> > impact at high rates (at 100000 connections per second, every syscall
> > counts). For now I could very well consider that I do this only for
> > POST requests, which currently are the ones exhibiting the issue the
> > most, but since HTTP browsers will try to enable pipelining again
> > soon, the problem will generalize to all types of requests. Hence my
> > attempts to do it the optimal way.
> 
> This might be overkill but is a portable way of doing this, on all
> versions of linux.

I'm not discussing the portability at all. You see, right now, Linux is
by some margin the fastest platform to run haproxy, and the one I always
recommend for that. Some people experience good performance on FreeBSD
too, but the fine-grained control we have on Linux helps maintaining a
high level of performance by avoiding many unnecessary steps when we
can trust the OS to do some things correctly. Having workarounds for
some versions that we know don't work as expected is not an issue, and
it's even a good reason to sometimes make people upgrade. But having to
cut performance in half under Linux on some workloads because the user
land can't know something obvious that the OS knows is a bit of a waste.

> Sure, you could patch kernel to add a new system call
> 
> close_proper(fd);

That would just be the normal close() (the one with lingering enabled)
in theory.

> As shutdown() only uses two bits, you can eventually add another bit to
> flush receive queue as well (to avoid the copy of it)

This is a good idea, but it will still leave some incorrectly handled
cases where the other side has the time to send a few packets between
the shutdown() and the close().

> Another question, is : why the server closes the socket, if you believe
> more pipelining is coming soon ?

There are quite a bunch of situations in HTTP where you have no other
solution than closing. All responses that don't advertise a length must
terminated by a close. Haproxy is a reverse-proxy, so it sits between
the client and the server. When a server sends such responses, haproxy
must forward the close to the client, regardless of what's in the request
buffer. Also, some response codes require a close. The 400 bad request
for instance, implies a mandatory close (as well as many 4xx or 5xx).
All redirects (301/302/303/307) should lead to a close if the target is
another site.

Eventhough we optimize for the most common cases, that doesn't save us
from having to support the legacy cases.

Regards,
Willy


^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Eric Dumazet @ 2010-09-26 21:01 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: netdev
In-Reply-To: <20100926184914.GC12373@1wt.eu>

Le dimanche 26 septembre 2010 à 20:49 +0200, Willy Tarreau a écrit :
> On Sun, Sep 26, 2010 at 08:35:15PM +0200, Eric Dumazet wrote:
> > I was referring to this code. It works well for me.
> > 
> > shutdown(fd, SHUT_RDWR);
> > while (recv(fd, buff, sizeof(buff), 0) > 0)
> > 	;
> > close(fd);
> 
> Ah this one yes, but it's overkill. We're actively pumping data from the
> other side to drop it on the floor until it finally closes while we only
> need to know when it has ACKed the FIN. In practice, doing that on a POST
> request which causes a 302 or 401 will result in the whole amount of data
> being transferred twice. Not only this is bad for the bandwidth, this is
> also bad for the user, as we're causing him to experience a complete upload
> twice, just to be sure it has received the FIN, while it's pretty obvious
> that it's not necessary in 99.9% of the cases.
> 

I dont understand how recv() could transfert data twice.

Once you issued shutdown(RDWR), socket rx buffer is freezed and no more
incoming data should be accepted/queued.

You only read from the socket receive queue to null buffer, and in most
cases a single recv() call will be enough to drain the queue.


> Since this method is the least efficient one and clearly not acceptable
> for practical cases, I wanted to dig at the root, where the information
> is known. And the TCP recv code is precisely the place where we know
> exactly when it's safe to reset.
> 

And its safe to reset exactly when application just does close(), if
unread data was not drained. Not only its safe, but required. A new RFC
might be needed ?


> Also there's another issue in doing this. It requires polling of the
> receive side for all requests, which adds one epoll_ctl() syscall and
> one recv() call, which have a much noticeable negative performance
> impact at high rates (at 100000 connections per second, every syscall
> counts). For now I could very well consider that I do this only for
> POST requests, which currently are the ones exhibiting the issue the
> most, but since HTTP browsers will try to enable pipelining again
> soon, the problem will generalize to all types of requests. Hence my
> attempts to do it the optimal way.

This might be overkill but is a portable way of doing this, on all
versions of linux.

Sure, you could patch kernel to add a new system call

close_proper(fd);

As shutdown() only uses two bits, you can eventually add another bit to
flush receive queue as well (to avoid the copy of it)

Another question, is : why the server closes the socket, if you believe
more pipelining is coming soon ?




^ permalink raw reply

* 2.6.36-rc5-git7: Reported regressions 2.6.34 -> 2.6.35
From: Rafael J. Wysocki @ 2010-09-26 20:29 UTC (permalink / raw)
  To: Linux Kernel Mailing List
  Cc: Maciej Rutecki, Florian Mickler, Andrew Morton, Linus Torvalds,
	Kernel Testers List, Network Development, Linux ACPI,
	Linux PM List, Linux SCSI List, Linux Wireless List, DRI

This message contains a list of some post-2.6.34 regressions introduced before
2.6.35, for which there are no fixes in the mainline known to the tracking team.
If any of them have been fixed already, please let us know.

If you know of any other unresolved post-2.6.34 regressions, please let us know
either and we'll add them to the list.  Also, please let us know if any
of the entries below are invalid.

Each entry from the list will be sent additionally in an automatic reply to
this message with CCs to the people involved in reporting and handling the
issue.


Listed regressions statistics:

  Date          Total  Pending  Unresolved
  ----------------------------------------
  2010-09-26      139       24          21
  2010-09-20      137       27          25
  2010-09-12      135       26          25
  2010-08-30      124       38          34
  2010-08-01      100       27          23
  2010-07-23       94       33          25
  2010-07-09       79       45          37
  2010-06-21       46       37          26
  2010-06-09       15       13          10


Unresolved regressions
----------------------

Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=18732
Subject		: Radeon HD 4700 needs MSI disabled
Submitter	: Rafael Gandolfi <kaillasse91-PkbjNfxxIARGWvitb5QawA@public.gmane.org>
Date		: 2010-09-18 12:06 (9 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=18522
Subject		: [REGRESSION] cdrom drive doesn't detect removal
Submitter	: Maxim Levitsky <maximlevitsky-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-09-12 9:49 (15 days old)
First-Bad-Commit: http://git.kernel.org/linus/6b4517a7913a09d3259bb1d21c9cb300f12294bd
Message-ID	: <1284284969.2928.18.camel@maxim-laptop>
References	: http://marc.info/?l=linux-kernel&m=128428499013930&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=18202
Subject		: Microphone levels too low
Submitter	: Alexander Hunziker <alex.hunziker-Mds7TqofYmjt3F02DXVmkw@public.gmane.org>
Date		: 2010-09-09 22:20 (18 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=18032
Subject		: No sound on headphone jack
Submitter	: Alexander Hunziker <alex.hunziker-Mds7TqofYmjt3F02DXVmkw@public.gmane.org>
Date		: 2010-09-07 21:45 (20 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=17812
Subject		: Kernel completely frozen when memory is full
Submitter	: Mickey86 <mikael.cordon-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-09-05 13:09 (22 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=17772
Subject		: Unable to locate IOAPIC for GSI *
Submitter	: zersaa <zersaa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-09-04 21:28 (23 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=17261
Subject		: Freezes on bootup
Submitter	: Dan Dart <dandart-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
Date		: 2010-08-29 09:00 (29 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16691
Subject		: IPW5100: iwlagn broken with 2.6.34.x to 2.6.35.2 update
Submitter	: Can Celasun <dcelasun-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-08-21 08:28 (37 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16633
Subject		: ath5k + 2.6.35 x86 + hostapd - Failed to set channel
Submitter	: NiTr0 <nitr0-z9XQkeP78BxUq1AO9QMCaQ@public.gmane.org>
Date		: 2010-08-19 19:37 (39 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16614
Subject		: [2.6.35] usb 2.0 em28xx  kernel panic general protection fault: 0000 [#1] SMP          RIP: 0010:[<ffffffffa004fbc5>]  [<ffffffffa004fbc5>] em28xx_isoc_copy_vbi+0x62e/0x812 [em28xx]
Submitter	: Sander Eikelenboom <linux-6SM94LqRVpn6gRhOQ7JHfg@public.gmane.org>
Date		: 2010-08-10 22:12 (48 days old)
Message-ID	: <61936849.20100811001257-6SM94LqRVpn6gRhOQ7JHfg@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128152075830927&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16562
Subject		: 2.6.35: cpu_idle bug report / on i7 870 cpu (x86_64)
Submitter	: Justin Piszcz <jpiszcz-BP4nVm5VUdNhbmWW9KSYcQ@public.gmane.org>
Date		: 2010-08-06 22:09 (52 days old)
Message-ID	: <alpine.DEB.2.00.1008061800530.5241-0qmrozcXWo8bm2hyYBkBBg@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128113260904048&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16549
Subject		: 2.6.35: suspicious rcu_dereference_check() usage
Submitter	: Vladislav Bolkhovitin <vst-d+Crzxg7Rs0@public.gmane.org>
Date		: 2010-08-04 10:56 (54 days old)
Message-ID	: <4C594740.1090608-d+Crzxg7Rs0@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128091938215177&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16525
Subject		: unexpected high load since 2.6.35
Submitter	: MadLoisae-hi6Y0CQ0nG0@public.gmane.org <MadLoisae-hi6Y0CQ0nG0@public.gmane.org>
Date		: 2010-08-02 20:53 (56 days old)
Message-ID	: <4C573041.1070103-hi6Y0CQ0nG0@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128078243726655&w=2
		  http://lkml.org/lkml/2010/9/14/105


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16515
Subject		: [bisected] Radeon rv280 can't boot on kernel 2.6.35.
Submitter	: Albert Gall <ss3vdr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-08-04 16:10 (54 days old)
First-Bad-Commit: http://git.kernel.org/linus/https://bugzilla.kernel.org/attachment.cgi?id=27350
Handled-By	: Alex Deucher <alexdeucher-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16488
Subject		: [i915] Framebuffer ID error after suspend/hibernate leading to X crash
Submitter	: Milan Bouchet-Valat <nalimilan-pqIVbhRXszc@public.gmane.org>
Date		: 2010-08-01 08:55 (57 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16462
Subject		: unable to connect to AP on legal channel 13
Submitter	: Daniel J Blueman <daniel.blueman-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-07-25 17:06 (64 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16458
Subject		: Bluetooth disabled after resume
Submitter	: AttilaN <attila123456-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-07-25 09:33 (64 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16380
Subject		: Loop devices act strangely in 2.6.35
Submitter	: Artem S. Tashkinov <t.artem-VInPYn6yXxRWk0Htik3J/w@public.gmane.org>
Date		: 2010-07-13 23:21 (76 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16322
Subject		: WARNING: at /arch/x86/include/asm/processor.h:1005 read_measured_perf_ctrs+0x5a/0x70()
Submitter	: boris64 <bugzilla.kernel.org-ro/BP3KN3ujR7s880joybQ@public.gmane.org>
Date		: 2010-07-01 13:54 (88 days old)
Handled-By	: H. Peter Anvin <hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16265
Subject		: Why is kslowd accumulating so much CPU time?
Submitter	: Theodore Ts'o <tytso-3s7WtUTddSA@public.gmane.org>
Date		: 2010-06-09 18:36 (110 days old)
First-Bad-Commit: http://git.kernel.org/linus/fbf81762e385d3d45acad057b654d56972acf58c
Message-ID	: <E1OMQ88-0002a1-Gb-UK71uKi2zisAobODsErMgNi2O/JbrIOy@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=127610857819033&w=4
		  http://bugs.freedesktop.org/show_bug.cgi?id=29536
Handled-By	: Chris Wilson <chris-Y6uKTt2uX1cEflXRtASbqLVCufUGDwFn@public.gmane.org>


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16221
Subject		: 2.6.35-rc2-git5 -- [drm:drm_mode_getfb] *ERROR* invalid framebuffer id
Submitter	: Miles Lane <miles.lane-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-06-11 20:31 (108 days old)
Message-ID	: <AANLkTim0jVRyqkwlGOcrg_XTvUQwcBYfWJX-aRzkkrLG-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=127628828119623&w=2


Regressions with patches
------------------------

Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16396
Subject		: [bisected] resume from suspend freezes system
Submitter	: tomas m <tmezzadra-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-07-15 02:32 (74 days old)
Handled-By	: Rafael J. Wysocki <rjw-KKrjLPT3xs0@public.gmane.org>
Patch		: https://bugzilla.kernel.org/attachment.cgi?id=31422


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16312
Subject		: WARNING: at fs/fs-writeback.c:1127 __mark_inode_dirty
Submitter	: Zdenek Kabelac <zdenek.kabelac-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-06-28 9:40 (91 days old)
Message-ID	: <AANLkTin24fr5O4_q5Xbo9Y_NKkEmtcp6Hgmr9_4qXaFz-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=127771804806465&w=2
		  http://lkml.indiana.edu/hypermail/linux/kernel/1007.3/00884.html
Handled-By	: Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
		  Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
Patch		: https://bugzilla.kernel.org/attachment.cgi?id=30282


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16228
Subject		: BUG/boot failure on Dell Precision T3500 (pci/ahci_stop_engine)
Submitter	: Brian Bloniarz <brian.bloniarz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-06-16 17:57 (103 days old)
Handled-By	: Bjorn Helgaas <bjorn.helgaas-VXdhtT5mjnY@public.gmane.org>
Patch		: https://patchwork.kernel.org/patch/189182/
		  https://patchwork.kernel.org/patch/189232/
		  https://patchwork.kernel.org/patch/189242/
		  https://patchwork.kernel.org/patch/189252/


For details, please visit the bug entries and follow the links given in
references.

As you can see, there is a Bugzilla entry for each of the listed regressions.
There also is a Bugzilla entry used for tracking the regressions introduced
between 2.6.34 and 2.6.35, unresolved as well as resolved, at:

http://bugzilla.kernel.org/show_bug.cgi?id=16055

Please let the tracking team know if there are any Bugzilla entries that
should be added to the list in there.

Thanks!

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* 2.6.36-rc5-git7: Reported regressions from 2.6.35
From: Rafael J. Wysocki @ 2010-09-26 19:55 UTC (permalink / raw)
  To: Linux Kernel Mailing List
  Cc: Maciej Rutecki, Florian Mickler, Andrew Morton, Linus Torvalds,
	Kernel Testers List, Network Development, Linux ACPI,
	Linux PM List, Linux SCSI List, Linux Wireless List, DRI

This message contains a list of some regressions from 2.6.35,
for which there are no fixes in the mainline known to the tracking team.
If any of them have been fixed already, please let us know.

If you know of any other unresolved regressions from 2.6.35, please let us
know either and we'll add them to the list.  Also, please let us know
if any of the entries below are invalid.

Each entry from the list will be sent additionally in an automatic reply
to this message with CCs to the people involved in reporting and handling
the issue.


Listed regressions statistics:

  Date          Total  Pending  Unresolved
  ----------------------------------------
  2010-09-26       46       15          13
  2010-09-20       38       15          15
  2010-09-12       28       14          13
  2010-08-30       21       16          15


Unresolved regressions
----------------------

Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=19082
Subject		: fs/fs-writeback.c to dump
Submitter	: Pavel Vasilyev <pavel-wkUsHEiXLHUox3rIn2DAYQ@public.gmane.org>
Date		: 2010-09-25 15:52 (2 days old)
Message-ID	: <201009251952.58749.pavel-wkUsHEiXLHUox3rIn2DAYQ@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128543035026659&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=19072
Subject		: [2.6.36-rc regression] occasional complete system hangs on sparc64 SMP
Submitter	: Mikael Pettersson <mikpe-1zs4UD6AkMk@public.gmane.org>
Date		: 2010-09-23 17:02 (4 days old)
Message-ID	: <19611.34846.813757.309183-tgku4HJDRZih8lFjZTKsyTAV6s6igYVG@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128526136531048&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=19062
Subject		: Dirtiable inode bdi default != sb bdi btrfs
Submitter	: Cesar Eduardo Barros <cesarb-PWySMVKUnqmsTnJN9+BGXg@public.gmane.org>
Date		: 2010-09-23 0:54 (4 days old)
Message-ID	: <4C9AA546.6050201-PWySMVKUnqmsTnJN9+BGXg@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128520328929595&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=19052
Subject		: 2.6.36-rc5-git1 -- [drm:i915_report_and_clear_eir] *ERROR* EIR stuck: 0x00000010, masking
Submitter	: Miles Lane <miles.lane-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-09-22 23:47 (5 days old)
Message-ID	: <AANLkTikWQjUQjFJU9MO1+XbSLAEE-GARz+S+Dz2Fgu4h-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128519926626322&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=19002
Subject		: Radeon rv730 AGP/KMS/DRM kernel lockup
Submitter	: Duncan <1i5t5.duncan-j9pdmedNgrk@public.gmane.org>
Date		: 2010-09-23 16:48 (4 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=18992
Subject		: warn_slow_path_common in iwlagn/mac80211 in 2.6.36-rc5
Submitter	: rocko <rockorequin-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org>
Date		: 2010-09-23 03:07 (4 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=18342
Subject		: [regression] i915 incorrectly detects bogus LVDS connection instead of LVDS1
Submitter	: Woody Suwalski <terraluna977-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date		: 2010-09-08 15:10 (19 days old)
Message-ID	: <AANLkTim2mrVRCKg-2couMTFV7krHQp0+2e_cbaiT_KYW-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128395866331382&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=17722
Subject		: 2.6.36-rc3: WARNING: at net/mac80211/scan.c:269 ieee80211_scan_completed
Submitter	: Thomas Meyer <thomas-VsYtu1Qij5c@public.gmane.org>
Date		: 2010-08-31 20:14 (27 days old)
Message-ID	: <201008312214.52473.thomas-VsYtu1Qij5c@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128328580504227&w=2
		  http://www.spinics.net/lists/netdev/msg140769.html


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=17361
Subject		: Watchdog detected hard LOCKUP in jbd2_journal_get_write_access
Submitter	: Christian Casteyde <casteyde.christian-GANU6spQydw@public.gmane.org>
Date		: 2010-08-29 19:59 (29 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=17121
Subject		: Two blank rectangles more than 10 cm long when booting
Submitter	: Eric Valette <eric.valette-GANU6spQydw@public.gmane.org>
Date		: 2010-08-26 17:24 (32 days old)


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=17061
Subject		: 2.6.36-rc1 on zaurus: bluetooth regression
Submitter	: Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org>
Date		: 2010-08-21 15:24 (37 days old)
Message-ID	: <20100821152445.GA1536-+ZI9xUNit7I@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128240433828087&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16971
Subject		: qla4xxx compile failure on 32-bit PowerPC: missing readq and writeq
Submitter	: Meelis Roos <mroos-Y27EyoLml9s@public.gmane.org>
Date		: 2010-08-19 21:03 (39 days old)
Message-ID	: <alpine.SOC.1.00.1008192359310.19654-ptEonEWSGqKptlylMvRsHA@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128225184900892&w=2


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=16951
Subject		: hackbench regression with 2.6.36-rc1
Submitter	: Zhang, Yanmin <yanmin_zhang-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Date		: 2010-08-18 6:18 (40 days old)
Message-ID	: <1282112318.21202.8.camel-sz7BYL/Y5Hu/P+R7jlPCFVaTQe2KTcn/@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128211235904910&w=2


Regressions with patches
------------------------

Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=18962
Subject		: screen failes in kde
Submitter	: Hans de Bruin <jmdebruin-agH9qYG3oEhmR6Xm/wNWPw@public.gmane.org>
Date		: 2010-09-22 15:42 (5 days old)
First-Bad-Commit: http://git.kernel.org/linus/e259befd9013e212648c3bd4f6f1fbf92d0dd51d
Handled-By	: Chris Wilson <chris-Y6uKTt2uX1cEflXRtASbqLVCufUGDwFn@public.gmane.org>
Patch		: https://bugzilla.kernel.org/attachment.cgi?id=31042


Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=18742
Subject		: PROBLEM: Kernel panic on 2.6.36-rc4 when loading intel_ips on Core i3 laptop
Submitter	: infernix <infernix-ZHiucA87ovfk1uMJSBkQmQ@public.gmane.org>
Date		: 2010-09-15 14:35 (12 days old)
Message-ID	: <4C90D998.6050103-ZHiucA87ovfk1uMJSBkQmQ@public.gmane.org>
References	: http://marc.info/?l=linux-kernel&m=128456187928496&w=2
Handled-By	: Jesse Barnes <jbarnes-Y1mF5jBUw70BENJcbMCuUQ@public.gmane.org>
Patch		: https://bugzilla.kernel.org/attachment.cgi?id=31112


For details, please visit the bug entries and follow the links given in
references.

As you can see, there is a Bugzilla entry for each of the listed regressions.
There also is a Bugzilla entry used for tracking the regressions from 2.6.35,
unresolved as well as resolved, at:

http://bugzilla.kernel.org/show_bug.cgi?id=16444

Please let the tracking team know if there are any Bugzilla entries that
should be added to the list in there.

Thanks!

^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Willy Tarreau @ 2010-09-26 19:16 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <20100926174014.GA12373@1wt.eu>

On Sun, Sep 26, 2010 at 07:40:15PM +0200, Willy Tarreau wrote:
> 3) when an ACK comes from the other side, either it's below our last
>    seq, and we simply ignore it, just as if we were in TIME_WAIT, or
>    it is equal to the last seq and indicates that it's now safe to
>    reset ; we would then just send the RST to notify the other side
>    that the data it sent were not read. The connection can then either
>    be destroyed or put in TIME_WAIT. It's the point where the connection
>    normally switches from FIN_WAIT1 to FIN_WAIT2, since the FIN has been
>    acked. The only difference is that we don't need a FIN_WAIT2 state
>    for an orphan.

In fact, the following patch seems to provide the expected result :

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index f1813bc..ee5fa5d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1879,7 +1880,7 @@ void tcp_close(struct sock *sk, long timeout)
 	 * advertise a zero window, then kill -9 the FTP client, wheee...
 	 * Note: timeout is always zero in such a case.
 	 */
-	if (data_was_unread) {
+	if (data_was_unread && !tcp_sk(sk)->packets_out) {
 		/* Unread data was tossed, zap the connection. */
 		NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
 		tcp_set_state(sk, TCP_CLOSE);


Here's what I get if I call it that way :

$ (echo "req1";usleep 200000;echo "req2") | nc6 10.8.3.4 8000

(excuse me for the long lines, I've disabled timestamps for better readability
but they're still long).

21:11:43.379465 IP 10.8.3.1.59244 > 10.8.3.4.8000: Flags [S], seq 210901267, win 5840, options [mss 1460,sackOK,TS val 305301003 ecr 0,nop,wscale 7], length 0
21:11:43.379514 IP 10.8.3.4.8000 > 10.8.3.1.59244: Flags [S.], seq 3131672819, ack 210901268, win 5840, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
21:11:43.379866 IP 10.8.3.1.59244 > 10.8.3.4.8000: Flags [.], ack 3131672820, win 46, length 0
21:11:43.379922 IP 10.8.3.1.59244 > 10.8.3.4.8000: Flags [P.], ack 3131672820, win 46, length 5
21:11:43.379946 IP 10.8.3.4.8000 > 10.8.3.1.59244: Flags [.], ack 210901273, win 92, length 0
21:11:43.581305 IP 10.8.3.1.59244 > 10.8.3.4.8000: Flags [P.], ack 3131672820, win 46, length 5
21:11:43.581331 IP 10.8.3.4.8000 > 10.8.3.1.59244: Flags [.], ack 210901278, win 92, length 0
21:11:44.380442 IP 10.8.3.4.8000 > 10.8.3.1.59244: Flags [P.], ack 210901278, win 92, length 7
21:11:44.380506 IP 10.8.3.4.8000 > 10.8.3.1.59244: Flags [FP.], seq 3131672827:3131672834, ack 210901278, win 92, length 7
21:11:44.380649 IP 10.8.3.1.59244 > 10.8.3.4.8000: Flags [.], ack 3131672827, win 46, length 0
21:11:44.380672 IP 10.8.3.1.59244 > 10.8.3.4.8000: Flags [F.], seq 210901278, ack 3131672835, win 46, length 0
21:11:44.380685 IP 10.8.3.4.8000 > 10.8.3.1.59244: Flags [.], ack 210901279, win 92, length 0

Here we have correctly got a FIN+PUSH for the last data instead of the reset.
The other side ACKs and after the last ACK, the socket is correctly in
TIME_WAIT state.

If I try to push more data after the connection closes, I correctly get
a reset to be sent :

$ (echo "req1";usleep 1200000;echo "req2"; usleep 200000; echo "req3") | nc6 --half-close 10.8.3.4 8000

21:15:00.068376 IP 10.8.3.1.60849 > 10.8.3.4.8000: Flags [S], seq 3284326660, win 5840, options [mss 1460,sackOK,TS val 305350241 ecr 0,nop,wscale 7], length 0
21:15:00.068428 IP 10.8.3.4.8000 > 10.8.3.1.60849: Flags [S.], seq 1933854189, ack 3284326661, win 5840, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
21:15:00.068779 IP 10.8.3.1.60849 > 10.8.3.4.8000: Flags [.], ack 1933854190, win 46, length 0
21:15:00.068830 IP 10.8.3.1.60849 > 10.8.3.4.8000: Flags [P.], ack 1933854190, win 46, length 5
21:15:00.068854 IP 10.8.3.4.8000 > 10.8.3.1.60849: Flags [.], ack 3284326666, win 92, length 0
21:15:01.069238 IP 10.8.3.4.8000 > 10.8.3.1.60849: Flags [P.], ack 3284326666, win 92, length 7
21:15:01.069300 IP 10.8.3.4.8000 > 10.8.3.1.60849: Flags [FP.], seq 1933854197:1933854204, ack 3284326666, win 92, length 7
21:15:01.069448 IP 10.8.3.1.60849 > 10.8.3.4.8000: Flags [.], ack 1933854197, win 46, length 0
21:15:01.109938 IP 10.8.3.1.60849 > 10.8.3.4.8000: Flags [.], ack 1933854205, win 46, length 0
21:15:01.270509 IP 10.8.3.1.60849 > 10.8.3.4.8000: Flags [P.], ack 1933854205, win 46, length 5
21:15:01.270542 IP 10.8.3.4.8000 > 10.8.3.1.60849: Flags [R], seq 1933854205, win 0, length 0

I had already tested that previously but unfortunately the test was
combined with an attempt to zero the rx window, which had corrupted my
tests.

Would you have any problem with the proposed change above ?

Thanks,
Willy


^ permalink raw reply related

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Willy Tarreau @ 2010-09-26 18:49 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1285526115.2530.12.camel@edumazet-laptop>

On Sun, Sep 26, 2010 at 08:35:15PM +0200, Eric Dumazet wrote:
> I was referring to this code. It works well for me.
> 
> shutdown(fd, SHUT_RDWR);
> while (recv(fd, buff, sizeof(buff), 0) > 0)
> 	;
> close(fd);

Ah this one yes, but it's overkill. We're actively pumping data from the
other side to drop it on the floor until it finally closes while we only
need to know when it has ACKed the FIN. In practice, doing that on a POST
request which causes a 302 or 401 will result in the whole amount of data
being transferred twice. Not only this is bad for the bandwidth, this is
also bad for the user, as we're causing him to experience a complete upload
twice, just to be sure it has received the FIN, while it's pretty obvious
that it's not necessary in 99.9% of the cases.

Since this method is the least efficient one and clearly not acceptable
for practical cases, I wanted to dig at the root, where the information
is known. And the TCP recv code is precisely the place where we know
exactly when it's safe to reset.

Also there's another issue in doing this. It requires polling of the
receive side for all requests, which adds one epoll_ctl() syscall and
one recv() call, which have a much noticeable negative performance
impact at high rates (at 100000 connections per second, every syscall
counts). For now I could very well consider that I do this only for
POST requests, which currently are the ones exhibiting the issue the
most, but since HTTP browsers will try to enable pipelining again
soon, the problem will generalize to all types of requests. Hence my
attempts to do it the optimal way.

Regards,
Willy


^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Eric Dumazet @ 2010-09-26 18:35 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: netdev
In-Reply-To: <20100926174014.GA12373@1wt.eu>

Le dimanche 26 septembre 2010 à 19:40 +0200, Willy Tarreau a écrit :
> Hi Eric,
> 
> On Sun, Sep 26, 2010 at 07:02:47PM +0200, Eric Dumazet wrote:
> > How could we delay the close() ? We must either send a FIN or RST.
> 
> I don't mean to delay the close(), but I'm aware that my description
> was not very clear.
> 
> Here's what I would find normal :
> 
> 1) upon close(), we send a FIN, whether there are incoming pending
>    data or not (after all, the only difference is only a timing
>    issue, as the data in the rx buffer might very well come just
>    after the FIN, as it almost always does, BTW). The connection
>    then becomes FIN_WAIT1 just as now.
> 
> 2) mark the socket as orphaned
> 
> 3) when an ACK comes from the other side, either it's below our last
>    seq, and we simply ignore it, just as if we were in TIME_WAIT, or
>    it is equal to the last seq and indicates that it's now safe to
>    reset ; we would then just send the RST to notify the other side
>    that the data it sent were not read. The connection can then either
>    be destroyed or put in TIME_WAIT. It's the point where the connection
>    normally switches from FIN_WAIT1 to FIN_WAIT2, since the FIN has been
>    acked. The only difference is that we don't need a FIN_WAIT2 state
>    for an orphan.
> 
> > I would say, fix the program, so that RST is avoided ?
> 
> Not that easy, see below.
> 
> > The program does :
> > 
> > recv() // read the request
> > send() // queue the answer
> > close() // could work if world was perfect...
> > 
> > Change it to
> > 
> > recv()
> > send()
> > shutdown()
> > recv() // read & flush in excess data
> 
> New data arrives now, close() below will cause an RST again.
> 
> > close()
> > 
> > This for sure will send FIN after all queued data is sent.
> > I am not sure the final rcv() is even needed, its Sunday after all ;)
> 
> Currently the real code (ie: not the poc I posted) does :
> 
>    recv()
>    send()
>    shutdown()
>    close()
> 
> The extra CRLF almost always happens between the recv() and send(). What
> I intend to do as a workaround is exactly what you described above, but
> I'm well aware it's not enough. It will only reduce the rate at which this
> case happens. Well, in fact, in 10 years of production at many sites, it's
> the first time such an issue is reported and it could be tracked down to
> these two extra bytes. But the workaround will not prevent the two extra
> bytes from coming after the last recv().
> 
> Also, the issue remains when processing large POST requests. Let's suppose
> the application is receiving a massive POST (eg: 10 MB) but the request is
> not authenticated, so the application returns an HTTP 401 response to
> require the client to authenticate. There's no way for the application to
> be notified that the small response was completely read by the client and
> that it's safe to close().
> 
> For these reasons, I concluded that the application can't get everything
> right and needs help from the kernel (said differently, I think that the
> RFC2525 fix is causing harm in addition to goods). In my opinion, this
> section in the RFC was added based on a few observations of trivial cases
> but was but its impact was not completely explored.
> 
> I'm willing to experiment, but I'm not much familiar with the code itself
> and sometimes I'm not sure about what I'm doing, probably that some help
> would be welcome. What I'd like to do is to implement the step 3 above,
> which is to only send the RST upon receipt of an ACK on an orphan that
> would switch a normal socket from FIN_WAIT1 to FIN_WAIT2.
> 
> Also, I'm not sure about what other OSes are doing. For instance, I tried
> on Solaris and did not observe the issue at all, though I think that
> Solaris simply does not implement the RFC2525 recommendation.
> 
> Have a nice sunday evening ;-)
> Willy
> 

I was referring to this code. It works well for me.

shutdown(fd, SHUT_RDWR);
while (recv(fd, buff, sizeof(buff), 0) > 0)
	;
close(fd);




^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Willy Tarreau @ 2010-09-26 17:40 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1285520567.2530.8.camel@edumazet-laptop>

Hi Eric,

On Sun, Sep 26, 2010 at 07:02:47PM +0200, Eric Dumazet wrote:
> How could we delay the close() ? We must either send a FIN or RST.

I don't mean to delay the close(), but I'm aware that my description
was not very clear.

Here's what I would find normal :

1) upon close(), we send a FIN, whether there are incoming pending
   data or not (after all, the only difference is only a timing
   issue, as the data in the rx buffer might very well come just
   after the FIN, as it almost always does, BTW). The connection
   then becomes FIN_WAIT1 just as now.

2) mark the socket as orphaned

3) when an ACK comes from the other side, either it's below our last
   seq, and we simply ignore it, just as if we were in TIME_WAIT, or
   it is equal to the last seq and indicates that it's now safe to
   reset ; we would then just send the RST to notify the other side
   that the data it sent were not read. The connection can then either
   be destroyed or put in TIME_WAIT. It's the point where the connection
   normally switches from FIN_WAIT1 to FIN_WAIT2, since the FIN has been
   acked. The only difference is that we don't need a FIN_WAIT2 state
   for an orphan.

> I would say, fix the program, so that RST is avoided ?

Not that easy, see below.

> The program does :
> 
> recv() // read the request
> send() // queue the answer
> close() // could work if world was perfect...
> 
> Change it to
> 
> recv()
> send()
> shutdown()
> recv() // read & flush in excess data

New data arrives now, close() below will cause an RST again.

> close()
> 
> This for sure will send FIN after all queued data is sent.
> I am not sure the final rcv() is even needed, its Sunday after all ;)

Currently the real code (ie: not the poc I posted) does :

   recv()
   send()
   shutdown()
   close()

The extra CRLF almost always happens between the recv() and send(). What
I intend to do as a workaround is exactly what you described above, but
I'm well aware it's not enough. It will only reduce the rate at which this
case happens. Well, in fact, in 10 years of production at many sites, it's
the first time such an issue is reported and it could be tracked down to
these two extra bytes. But the workaround will not prevent the two extra
bytes from coming after the last recv().

Also, the issue remains when processing large POST requests. Let's suppose
the application is receiving a massive POST (eg: 10 MB) but the request is
not authenticated, so the application returns an HTTP 401 response to
require the client to authenticate. There's no way for the application to
be notified that the small response was completely read by the client and
that it's safe to close().

For these reasons, I concluded that the application can't get everything
right and needs help from the kernel (said differently, I think that the
RFC2525 fix is causing harm in addition to goods). In my opinion, this
section in the RFC was added based on a few observations of trivial cases
but was but its impact was not completely explored.

I'm willing to experiment, but I'm not much familiar with the code itself
and sometimes I'm not sure about what I'm doing, probably that some help
would be welcome. What I'd like to do is to implement the step 3 above,
which is to only send the RST upon receipt of an ACK on an orphan that
would switch a normal socket from FIN_WAIT1 to FIN_WAIT2.

Also, I'm not sure about what other OSes are doing. For instance, I tried
on Solaris and did not observe the issue at all, though I think that
Solaris simply does not implement the RFC2525 recommendation.

Have a nice sunday evening ;-)
Willy


^ permalink raw reply

* Re: TCP: orphans broken by RFC 2525 #2.17
From: Eric Dumazet @ 2010-09-26 17:02 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: netdev
In-Reply-To: <20100926131717.GA13046@1wt.eu>

Le dimanche 26 septembre 2010 à 15:17 +0200, Willy Tarreau a écrit :
> Hi,
> 
> one haproxy user was reporting occasionally truncated responses to
> HTTP POST requests exclusively. After he took many captures, we
> could verify that the strace dumps were showing all data to be
> emitted, but network captures showed that an RST was emitted before
> the end of the data.
> 
> Looking more closely, I noticed that in traces showing the issue,
> the client was sending an additional CRLF after the data in a
> separate packet (permitted eventhough not recommended).
> 
> I could thus finally understand what happens and I'm now able to
> reproduce it very easily using the attached program. What happens
> is that haproxy sends the last data to the client, followed by a
> shutdown()+close(). This is mimmicked by the attached program,
> which is connected to by a simple netcat from another machine
> sending two distinct chunks :
> 
> server:$ ./abort-data
> client:$ (echo "req1";usleep 200000; echo "req2") | nc6 server 8000
> block1
> ("block2" is missing here)
> client:$
> 
> It gives the following capture, with client=10.8.3.4 and server=10.8.3.1 :
> 
> reading from file abort-linux.cap, link-type EN10MB (Ethernet)
> 10:47:07.057793 IP (tos 0x0, ttl 64, id 57159, offset 0, flags [DF], proto TCP (6), length 60)
>     10.8.3.4.39925 > 10.8.3.1.8000: Flags [S], cksum 0xdad9 (correct), seq 2570439277, win 5840, options [mss 1460,sackOK,TS val 138417450 ecr 0,nop,wscale 6], length 0
> 10:47:07.058015 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
>     10.8.3.1.8000 > 10.8.3.4.39925: Flags [S.], cksum 0x3851 (correct), seq 1066199564, ack 2570439278, win 5792, options [mss 1460,sackOK,TS val 295921514 ecr 138417450,nop,wscale 7], length 0
> 10:47:07.058071 IP (tos 0x0, ttl 64, id 57160, offset 0, flags [DF], proto TCP (6), length 52)
>     10.8.3.4.39925 > 10.8.3.1.8000: Flags [.], cksum 0x7d60 (correct), seq 2570439278, ack 1066199565, win 92, options [nop,nop,TS val 138417451 ecr 295921514], length 0
> 10:47:07.058213 IP (tos 0x0, ttl 64, id 57161, offset 0, flags [DF], proto TCP (6), length 57)
>     10.8.3.4.39925 > 10.8.3.1.8000: Flags [P.], cksum 0x1a40 (incorrect -> 0x8fbc), seq 2570439278:2570439283, ack 1066199565, win 92, options [nop,nop,TS val 138417451 ecr 295921514], length 5
> 10:47:07.058410 IP (tos 0x0, ttl 64, id 36199, offset 0, flags [DF], proto TCP (6), length 52)
>     10.8.3.1.8000 > 10.8.3.4.39925: Flags [.], cksum 0x7d89 (correct), seq 1066199565, ack 2570439283, win 46, options [nop,nop,TS val 295921514 ecr 138417451], length 0
> 10:47:07.253294 IP (tos 0x0, ttl 64, id 57162, offset 0, flags [DF], proto TCP (6), length 53)
>     10.8.3.4.39925 > 10.8.3.1.8000: Flags [P.], cksum 0x1a3c (incorrect -> 0x7321), seq 2570439283:2570439284, ack 1066199565, win 92, options [nop,nop,TS val 138417500 ecr 295921514], length 1
> 10:47:07.253468 IP (tos 0x0, ttl 64, id 36200, offset 0, flags [DF], proto TCP (6), length 52)
>     10.8.3.1.8000 > 10.8.3.4.39925: Flags [.], cksum 0x7d27 (correct), seq 1066199565, ack 2570439284, win 46, options [nop,nop,TS val 295921562 ecr 138417500], length 0
> 10:47:08.060213 IP (tos 0x0, ttl 64, id 36201, offset 0, flags [DF], proto TCP (6), length 59)
>     10.8.3.1.8000 > 10.8.3.4.39925: Flags [P.], cksum 0x354c (correct), seq 1066199565:1066199572, ack 2570439284, win 46, options [nop,nop,TS val 295921765 ecr 138417500], length 7
> 10:47:08.060270 IP (tos 0x0, ttl 64, id 57163, offset 0, flags [DF], proto TCP (6), length 52)
>     10.8.3.4.39925 > 10.8.3.1.8000: Flags [.], cksum 0x7b5e (correct), seq 2570439284, ack 1066199572, win 92, options [nop,nop,TS val 138417701 ecr 295921765], length 0
> 10:47:08.060298 IP (tos 0x0, ttl 64, id 36202, offset 0, flags [DF], proto TCP (6), length 52)
>     10.8.3.1.8000 > 10.8.3.4.39925: Flags [R.], cksum 0x7c51 (correct), seq 1066199572, ack 2570439284, win 46, options [nop,nop,TS val 295921765 ecr 138417500], length 0
> 10:47:08.060613 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
>     10.8.3.1.8000 > 10.8.3.4.39925: Flags [R], cksum 0xb0f5 (correct), seq 1066199572, win 0, length 0
> .
> 
> The connection should in theory become an orphan. I'm saying "in theory",
> because since the following test was added to tcp_close(), if the client
> happens to send any data between the last recv() and the close(), we
> immediately send an RST to it, regardless of any pending outgoing data :
> 
>         /* As outlined in RFC 2525, section 2.17, we send a RST here because
>          * data was lost. To witness the awful effects of the old behavior of
>          * always doing a FIN, run an older 2.1.x kernel or 2.0.x, start a bulk
>          * GET in an FTP client, suspend the process, wait for the client to
>          * advertise a zero window, then kill -9 the FTP client, wheee...
>          * Note: timeout is always zero in such a case.
>          */
>         if (data_was_unread) {
>                 /* Unread data was tossed, zap the connection. */
>                 NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
>                 tcp_set_state(sk, TCP_CLOSE);
>                 tcp_send_active_reset(sk, sk->sk_allocation);
> 	}
> 
> The immediate effect then is that the client receives an abort before it
> even gets the last data that were scheduled for being sent.
> 
> I've read RFC 2525 #2.17 and it shows quite interesting examples of what
> it wanted to protect against. However, the recommendation did not consider
> the fact that there could be some unacked pending data in the outgoing
> buffers.
> 
> What is even more more embarrassing is that the HTTP working group is
> trying to encourage browsers to enable pipelining by default. That means
> that the situation above can become much more common, where two requests
> will be pipeline, the first one will cause a short response followed by
> a close(), and the simple presence of the second one will kill the first
> one's data.
> 
> I tried to think about a finer way to process those unwanted data. Ideally,
> we should just ignore until the ACK indicates that our last segment was
> properly received. Then we could emit the RST.
> 
> I made a few attempts by first changing the test above like this :
> 
> -        if (data_was_unread) {
> +        if (data_was_unread && !tcp_sk(sk)->packets_out) {
> 
> then fiddling a little bit in tcp_input.c:tcp_rcv_state_process() for
> the TCP_FIN_WAIT1 state, but I'm not satisfied with my experimentations,
> they were a bit too much experimental for the results to be considered
> reliable.
> 
> What I was looking for was a way to only send an RST when the socket is
> an orphan and all of its outgoing data has been ACKed. This would cover
> the situations that RFC 2525 #2.17 tries to fix without rendering orphans
> unusable.
> 
> Has anyone an opinion on this, or even could suggest a patch to relax
> the conditions in which we send an RST ?

How could we delay the close() ? We must either send a FIN or RST.

I would say, fix the program, so that RST is avoided ?

The program does :

recv() // read the request
send() // queue the answer
close() // could work if world was perfect...

Change it to

recv()
send()
shutdown()
recv() // read & flush in excess data
close()

This for sure will send FIN after all queued data is sent.
I am not sure the final rcv() is even needed, its Sunday after all ;)



^ permalink raw reply

* Re: [PATCH v11 00/17] Provide a zero-copy method on KVM virtio-net.
From: Michael S. Tsirkin @ 2010-09-26 17:01 UTC (permalink / raw)
  To: xiaohui.xin; +Cc: netdev, kvm, linux-kernel, mingo, davem, herbert, jdike
In-Reply-To: <1285388855-27410-1-git-send-email-xiaohui.xin@intel.com>

On Sat, Sep 25, 2010 at 12:27:18PM +0800, xiaohui.xin@intel.com wrote:
> We provide an zero-copy method which driver side may get external
> buffers to DMA. Here external means driver don't use kernel space
> to allocate skb buffers. Currently the external buffer can be from
> guest virtio-net driver.
> 
> The idea is simple, just to pin the guest VM user space and then
> let host NIC driver has the chance to directly DMA to it. 
> The patches are based on vhost-net backend driver. We add a device
> which provides proto_ops as sendmsg/recvmsg to vhost-net to
> send/recv directly to/from the NIC driver. KVM guest who use the
> vhost-net backend may bind any ethX interface in the host side to
> get copyless data transfer thru guest virtio-net frontend.
> patch 01-10:  	net core and kernel changes.
> patch 11-13:  	new device as interface to mantpulate external buffers.
> patch 14: 	for vhost-net.
> patch 15:	An example on modifying NIC driver to using napi_gro_frags().
> patch 16:	An example how to get guest buffers based on driver
> 		who using napi_gro_frags().
> patch 17:	It's a patch to address comments from Michael S. Thirkin
> 		to add 2 new ioctls in mp device.
> 		We split it out here to make easier reiewer.



I commented on how to avoid mm semaphore on data path separately, and
since you didn't have time to review that yet, I won't repeat that here.

At this point what are the plans on macvtap integration?
You indicated this is the interface you intend to use longterm.

^ permalink raw reply

* [PATCH] net/9p: Mount only matching virtio channels
From: Sven Eckelmann @ 2010-09-26 15:28 UTC (permalink / raw)
  To: ericvh; +Cc: davem, netdev, linux-kernel, Sven Eckelmann

p9_virtio_create will only compare the the channel's tag characters
against the device name till the end of the channel's tag but not till
the end of the device name. This means that if a user defines channels
with the tags foo and foobar then he would mount foo when he requested
foonot and may mount foo when he requested foobar.

Thus it is necessary to check both string lengths against each other in
case of a successful partial string match.

Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
---
 net/9p/trans_virtio.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index dcfbe99..b885159 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -329,7 +329,8 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
 
 	mutex_lock(&virtio_9p_lock);
 	list_for_each_entry(chan, &virtio_chan_list, chan_list) {
-		if (!strncmp(devname, chan->tag, chan->tag_len)) {
+		if (!strncmp(devname, chan->tag, chan->tag_len) &&
+		    strlen(devname) == chan->tag_len) {
 			if (!chan->inuse) {
 				chan->inuse = true;
 				found = 1;
-- 
1.7.2.3

^ permalink raw reply related

* Re: [patch] ipvs: Keep track of backlog connections
From: Sven Wegener @ 2010-09-26 14:59 UTC (permalink / raw)
  To: Simon Horman
  Cc: lvs-devel, netdev, Wensong Zhang, Julian Anastasov,
	Venkata Mohan Reddy Koppula
In-Reply-To: <alpine.LNX.2.00.1009261629240.609@titan.stealer.net>

On Sun, 26 Sep 2010, Sven Wegener wrote:

> On Sun, 26 Sep 2010, Simon Horman wrote:
> 
> > here is an updated though as yet untested version of your patch from Julian
> > to take into account recent changes. In particualr, the ip_vs_sync.c
> > portion is no longer needed as only the flags in the first 16 bits are
> > synced now. It applies against Patrick McHardy's nf-next-2.6 tree.
> > 
> > You mentioned in your original post that you would work on an ipvsadm
> > patch for this feature. Have you had time to do so?
> > 
> > Also, are you in a position to test this? If not I can do so.
> 
> I've tested your patch with the below addition to ipvsadm and it works 
> correctly. 

And here is a small patch for the manpage:

diff --git a/ipvsadm.8 b/ipvsadm.8
index 6874c0e..78d67ef 100644
--- a/ipvsadm.8
+++ b/ipvsadm.8
@@ -392,6 +392,15 @@ information of each server in service listing. The persistent
 connection is used to forward the actual connections from the same
 client/network to the same server.
 .TP
+.B --backlog-conn
+Output of backlog connection information. The \fIlist\fP command
+with this option will display the backlog connection counter
+information of each server in service listing. A backlog connection
+is a connection that is inactive, but is expected to move to active
+soon. Speaking in TCP language, a connection from which we have seen
+the initial SYN packet, but the three-way handshake has not finished
+yet.
+.TP
 .B --sort
 Sort the list of virtual services and real servers. The virtual
 service entries are sorted in ascending order by <protocol, address,

^ permalink raw reply related

* Re: [patch] ipvs: Keep track of backlog connections
From: Sven Wegener @ 2010-09-26 14:31 UTC (permalink / raw)
  To: Simon Horman
  Cc: lvs-devel, netdev, Wensong Zhang, Julian Anastasov,
	Venkata Mohan Reddy Koppula
In-Reply-To: <20100926133101.GA9004@verge.net.au>

On Sun, 26 Sep 2010, Simon Horman wrote:

> here is an updated though as yet untested version of your patch from Julian
> to take into account recent changes. In particualr, the ip_vs_sync.c
> portion is no longer needed as only the flags in the first 16 bits are
> synced now. It applies against Patrick McHardy's nf-next-2.6 tree.
> 
> You mentioned in your original post that you would work on an ipvsadm
> patch for this feature. Have you had time to do so?
> 
> Also, are you in a position to test this? If not I can do so.

Hi,

I've tested your patch with the below addition to ipvsadm and it works 
correctly. 

Sven

From: Sven Wegener <sven.wegener@stealer.net>
Subject: [PATCH] Show backlog connections

Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
---
 ipvsadm.c                 |   51 ++++++++++++++++++++++++++++++--------------
 libipvs/ip_vs.h           |    4 +++
 libipvs/ip_vs_nl_policy.c |    1 +
 libipvs/libipvs.c         |    3 ++
 4 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/ipvsadm.c b/ipvsadm.c
index 8557d21..54ae110 100644
--- a/ipvsadm.c
+++ b/ipvsadm.c
@@ -181,7 +181,8 @@ static const char* cmdnames[] = {
 #define OPT_SYNCID		0x080000
 #define OPT_EXACT		0x100000
 #define OPT_ONEPACKET		0x200000
-#define NUMBER_OF_OPT		22
+#define OPT_BACKLOGCONN		0x400000
+#define NUMBER_OF_OPT		23
 
 static const char* optnames[] = {
 	"numeric",
@@ -206,6 +207,7 @@ static const char* optnames[] = {
 	"syncid",
 	"exact",
 	"ops",
+	"backlog-conn",
 };
 
 /*
@@ -218,21 +220,21 @@ static const char* optnames[] = {
  */
 static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
 {
-	/*   -n   -c   svc  -s   -p   -M   -r   fwd  -w   -x   -y   -mc  tot  dmn  -st  -rt  thr  -pc  srt  sid  -ex  ops */
-/*ADD*/     {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' '},
-/*EDIT*/    {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' '},
-/*DEL*/     {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*FLUSH*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*LIST*/    {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x'},
-/*ADDSRV*/  {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*DELSRV*/  {'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*EDITSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*STARTD*/  {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x'},
-/*STOPD*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x'},
-/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*SAVE*/    {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*ZERO*/    {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+	/*   -n   -c   svc  -s   -p   -M   -r   fwd  -w   -x   -y   -mc  tot  dmn  -st  -rt  thr  -pc  srt  sid  -ex  ops, blc */
+/*ADD*/     {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x'},
+/*EDIT*/    {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x'},
+/*DEL*/     {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*FLUSH*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*LIST*/    {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' '},
+/*ADDSRV*/  {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*DELSRV*/  {'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*EDITSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*STARTD*/  {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x'},
+/*STOPD*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x'},
+/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*SAVE*/    {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*ZERO*/    {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
 };
 
 /* printing format flags */
@@ -245,6 +247,7 @@ static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
 #define FMT_PERSISTENTCONN	0x0020
 #define FMT_NOSORT		0x0040
 #define FMT_EXACT		0x0080
+#define FMT_BACKLOGCONN		0x0100
 
 #define SERVICE_NONE		0x0000
 #define SERVICE_ADDR		0x0001
@@ -282,6 +285,7 @@ enum {
 	TAG_PERSISTENTCONN,
 	TAG_SORT,
 	TAG_NO_SORT,
+	TAG_BACKLOGCONN,
 };
 
 /* various parsing helpers & parsing functions */
@@ -421,6 +425,8 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 		{ "exact", 'X', POPT_ARG_NONE, NULL, 'X', NULL, NULL },
 		{ "ipv6", '6', POPT_ARG_NONE, NULL, '6', NULL, NULL },
 		{ "ops", 'o', POPT_ARG_NONE, NULL, 'o', NULL, NULL },
+		{ "backlog-conn", '\0', POPT_ARG_NONE, NULL,
+		  TAG_BACKLOGCONN, NULL, NULL },
 		{ NULL, 0, 0, NULL, 0, NULL, NULL }
 	};
 
@@ -647,6 +653,10 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 			set_option(options, OPT_ONEPACKET);
 			ce->svc.flags |= IP_VS_SVC_F_ONEPACKET;
 			break;
+		case TAG_BACKLOGCONN:
+			set_option(options, OPT_BACKLOGCONN);
+			*format |= FMT_BACKLOGCONN;
+			break;
 		default:
 			fail(2, "invalid option `%s'",
 			     poptBadOption(context, POPT_BADOPTION_NOALIAS));
@@ -1396,6 +1406,11 @@ static void print_title(unsigned int format)
 		       "  -> RemoteAddress:Port\n",
 		       "Prot LocalAddress:Port",
 		       "Weight", "PersistConn", "ActiveConn", "InActConn");
+	else if (format & FMT_BACKLOGCONN)
+		printf("%-33s %-9s %-11s %-10s %-10s\n"
+		       "  -> RemoteAddress:Port\n",
+		       "Prot LocalAddress:Port",
+		       "Weight", "BacklogConn", "ActiveConn", "InActConn");
 	else if (!(format & FMT_RULE))
 		printf("Prot LocalAddress:Port Scheduler Flags\n"
 		       "  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn\n");
@@ -1539,6 +1554,10 @@ print_service_entry(ipvs_service_entry_t *se, unsigned int format)
 			printf("  -> %-28s %-9u %-11u %-10u %-10u\n", dname,
 			       e->weight, e->persistconns,
 			       e->activeconns, e->inactconns);
+		} else if (format & FMT_BACKLOGCONN) {
+			printf("  -> %-28s %-9u %-11u %-10u %-10u\n", dname,
+			       e->weight, e->backlogconns,
+			       e->activeconns, e->inactconns);
 		} else
 			printf("  -> %-28s %-7s %-6d %-10u %-10u\n",
 			       dname, fwd_name(e->conn_flags),
diff --git a/libipvs/ip_vs.h b/libipvs/ip_vs.h
index 843c51a..4c2c265 100644
--- a/libipvs/ip_vs.h
+++ b/libipvs/ip_vs.h
@@ -277,6 +277,8 @@ struct ip_vs_dest_entry {
 	struct ip_vs_stats_user stats;
 	u_int16_t		af;
 	union nf_inet_addr	addr;
+
+	u_int32_t		backlogconns;	/* backlog connections */
 };
 
 /* The argument to IP_VS_SO_GET_DESTS */
@@ -455,6 +457,8 @@ enum {
 	IPVS_DEST_ATTR_PERSIST_CONNS,	/* persistent connections */
 
 	IPVS_DEST_ATTR_STATS,		/* nested attribute for dest stats */
+
+	IPVS_DEST_ATTR_BACKLOG_CONNS,	/* backlog connections */
 	__IPVS_DEST_ATTR_MAX,
 };
 
diff --git a/libipvs/ip_vs_nl_policy.c b/libipvs/ip_vs_nl_policy.c
index c80083e..d06a490 100644
--- a/libipvs/ip_vs_nl_policy.c
+++ b/libipvs/ip_vs_nl_policy.c
@@ -40,6 +40,7 @@ struct nla_policy ipvs_dest_policy[IPVS_DEST_ATTR_MAX + 1] = {
 	[IPVS_DEST_ATTR_INACT_CONNS]	= { .type = NLA_U32 },
 	[IPVS_DEST_ATTR_PERSIST_CONNS]	= { .type = NLA_U32 },
 	[IPVS_DEST_ATTR_STATS]		= { .type = NLA_NESTED },
+	[IPVS_DEST_ATTR_BACKLOG_CONNS]	= { .type = NLA_U32 },
 };
 
 struct nla_policy ipvs_stats_policy[IPVS_STATS_ATTR_MAX + 1] = {
diff --git a/libipvs/libipvs.c b/libipvs/libipvs.c
index 979d5bd..e06f9fa 100644
--- a/libipvs/libipvs.c
+++ b/libipvs/libipvs.c
@@ -748,6 +748,8 @@ static int ipvs_dests_parse_cb(struct nl_msg *msg, void *arg)
 	d->entrytable[i].l_threshold = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_L_THRESH]);
 	d->entrytable[i].activeconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_ACTIVE_CONNS]);
 	d->entrytable[i].inactconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_INACT_CONNS]);
+	if (dest_attrs[IPVS_DEST_ATTR_BACKLOG_CONNS])
+		d->entrytable[i].backlogconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_BACKLOG_CONNS]);
 	d->entrytable[i].persistconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_PERSIST_CONNS]);
 	d->entrytable[i].af = d->af;
 
@@ -853,6 +855,7 @@ ipvs_nl_dest_failure:
 		       sizeof(struct ip_vs_dest_entry_kern));
 		d->entrytable[i].af = AF_INET;
 		d->entrytable[i].addr.ip = d->entrytable[i].__addr_v4;
+		d->entrytable[i].backlogconns = 0;
 	}
 	free(dk);
 	return d;

^ permalink raw reply related

* [patch] ipvs: Keep track of backlog connections
From: Simon Horman @ 2010-09-26 13:31 UTC (permalink / raw)
  To: Sven Wegener
  Cc: lvs-devel, netdev, Wensong Zhang, Julian Anastasov,
	Venkata Mohan Reddy Koppula

From: Sven Wegener <sven.wegener@stealer.net>

A backlog connection is a connection that is on its way from inactive to
active. Speaking in TCP language, a connection from which we've seen the
initial SYN packet, but the three-way handshake hasn't finished yet.
These connections are expected to move to active soon. When a
destination is overloaded or isn't able to successfully establish
connections for various reasons, this count increases quickly and is an
indication for a problem.

Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
Signed-off-by: Julian Anastasov <ja@ssi.bg>

---

Hi Sven,

here is an updated though as yet untested version of your patch from Julian
to take into account recent changes. In particualr, the ip_vs_sync.c
portion is no longer needed as only the flags in the first 16 bits are
synced now. It applies against Patrick McHardy's nf-next-2.6 tree.

You mentioned in your original post that you would work on an ipvsadm
patch for this feature. Have you had time to do so?

Also, are you in a position to test this? If not I can do so.

Hi Mohan,

do you have any thoughts on an appropriate to add this feature to SCTP?

diff -urp net-next-2.6-e548833-nfct/linux/include/linux/ip_vs.h linux/include/linux/ip_vs.h
--- net-next-2.6-e548833-nfct/linux/include/linux/ip_vs.h	2010-09-15 11:28:02.000000000 +0300
+++ linux/include/linux/ip_vs.h	2010-09-26 15:21:53.507865229 +0300
@@ -91,6 +91,7 @@

 /* Flags that are not sent to backup server start from bit 16 */
 #define IP_VS_CONN_F_NFCT	(1 << 16)	/* use netfilter conntrack */
+#define IP_VS_CONN_F_BACKLOG	(1 << 17)	/* backlog connection */

 /* Connection flags from destination that can be changed by user space */
 #define IP_VS_CONN_F_DEST_MASK (IP_VS_CONN_F_FWD_MASK | \
@@ -360,6 +361,7 @@ enum {
 	IPVS_DEST_ATTR_PERSIST_CONNS,	/* persistent connections */

 	IPVS_DEST_ATTR_STATS,		/* nested attribute for dest stats */
+	IPVS_DEST_ATTR_BACKLOG_CONNS,	/* backlog connections */
 	__IPVS_DEST_ATTR_MAX,
 };

diff -urp net-next-2.6-e548833-nfct/linux/include/net/ip_vs.h linux/include/net/ip_vs.h
--- net-next-2.6-e548833-nfct/linux/include/net/ip_vs.h	2010-09-16 08:53:04.000000000 +0300
+++ linux/include/net/ip_vs.h	2010-09-26 15:31:27.369865994 +0300
@@ -501,6 +501,7 @@ struct ip_vs_dest {
 	/* connection counters and thresholds */
 	atomic_t		activeconns;	/* active connections */
 	atomic_t		inactconns;	/* inactive connections */
+	atomic_t		backlogconns;	/* backlog connections */
 	atomic_t		persistconns;	/* persistent connections */
 	__u32			u_threshold;	/* upper threshold */
 	__u32			l_threshold;	/* lower threshold */
diff -urp net-next-2.6-e548833-nfct/linux/net/netfilter/ipvs/ip_vs_conn.c linux/net/netfilter/ipvs/ip_vs_conn.c
--- net-next-2.6-e548833-nfct/linux/net/netfilter/ipvs/ip_vs_conn.c	2010-09-15 11:14:13.000000000 +0300
+++ linux/net/netfilter/ipvs/ip_vs_conn.c	2010-09-26 15:24:48.292865793 +0300
@@ -611,6 +611,8 @@ static inline void ip_vs_unbind_dest(str
 		} else {
 			atomic_dec(&dest->activeconns);
 		}
+		if (cp->flags & IP_VS_CONN_F_BACKLOG)
+			atomic_dec(&dest->backlogconns);
 	} else {
 		/* It is a persistent connection/template, so decrease
 		   the peristent connection counter */
diff -urp net-next-2.6-e548833-nfct/linux/net/netfilter/ipvs/ip_vs_ctl.c linux/net/netfilter/ipvs/ip_vs_ctl.c
--- net-next-2.6-e548833-nfct/linux/net/netfilter/ipvs/ip_vs_ctl.c	2010-09-16 08:56:34.000000000 +0300
+++ linux/net/netfilter/ipvs/ip_vs_ctl.c	2010-09-26 15:26:45.407867200 +0300
@@ -2593,6 +2593,7 @@ static const struct nla_policy ip_vs_des
 	[IPVS_DEST_ATTR_INACT_CONNS]	= { .type = NLA_U32 },
 	[IPVS_DEST_ATTR_PERSIST_CONNS]	= { .type = NLA_U32 },
 	[IPVS_DEST_ATTR_STATS]		= { .type = NLA_NESTED },
+	[IPVS_DEST_ATTR_BACKLOG_CONNS]	= { .type = NLA_U32 },
 };

 static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type,
@@ -2840,6 +2841,8 @@ static int ip_vs_genl_fill_dest(struct s
 		    atomic_read(&dest->activeconns));
 	NLA_PUT_U32(skb, IPVS_DEST_ATTR_INACT_CONNS,
 		    atomic_read(&dest->inactconns));
+	NLA_PUT_U32(skb, IPVS_DEST_ATTR_BACKLOG_CONNS,
+		    atomic_read(&dest->backlogconns));
 	NLA_PUT_U32(skb, IPVS_DEST_ATTR_PERSIST_CONNS,
 		    atomic_read(&dest->persistconns));

diff -urp net-next-2.6-e548833-nfct/linux/net/netfilter/ipvs/ip_vs_proto_tcp.c linux/net/netfilter/ipvs/ip_vs_proto_tcp.c
--- net-next-2.6-e548833-nfct/linux/net/netfilter/ipvs/ip_vs_proto_tcp.c	2010-09-10 08:27:33.000000000 +0300
+++ linux/net/netfilter/ipvs/ip_vs_proto_tcp.c	2010-09-26 15:29:18.425865407 +0300
@@ -510,6 +510,15 @@ set_tcp_state(struct ip_vs_protocol *pp,
 				atomic_dec(&dest->inactconns);
 				cp->flags &= ~IP_VS_CONN_F_INACTIVE;
 			}
+			if (new_state == IP_VS_TCP_S_SYN_RECV &&
+					!(cp->flags & IP_VS_CONN_F_BACKLOG)) {
+				atomic_inc(&dest->backlogconns);
+				cp->flags |= IP_VS_CONN_F_BACKLOG;
+			} else if (new_state == IP_VS_TCP_S_ESTABLISHED &&
+					cp->flags & IP_VS_CONN_F_BACKLOG) {
+				atomic_dec(&dest->backlogconns);
+				cp->flags &= ~IP_VS_CONN_F_BACKLOG;
+			}
 		}
 	}


^ permalink raw reply

* TCP: orphans broken by RFC 2525 #2.17
From: Willy Tarreau @ 2010-09-26 13:17 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: Type: text/plain, Size: 6731 bytes --]

Hi,

one haproxy user was reporting occasionally truncated responses to
HTTP POST requests exclusively. After he took many captures, we
could verify that the strace dumps were showing all data to be
emitted, but network captures showed that an RST was emitted before
the end of the data.

Looking more closely, I noticed that in traces showing the issue,
the client was sending an additional CRLF after the data in a
separate packet (permitted eventhough not recommended).

I could thus finally understand what happens and I'm now able to
reproduce it very easily using the attached program. What happens
is that haproxy sends the last data to the client, followed by a
shutdown()+close(). This is mimmicked by the attached program,
which is connected to by a simple netcat from another machine
sending two distinct chunks :

server:$ ./abort-data
client:$ (echo "req1";usleep 200000; echo "req2") | nc6 server 8000
block1
("block2" is missing here)
client:$

It gives the following capture, with client=10.8.3.4 and server=10.8.3.1 :

reading from file abort-linux.cap, link-type EN10MB (Ethernet)
10:47:07.057793 IP (tos 0x0, ttl 64, id 57159, offset 0, flags [DF], proto TCP (6), length 60)
    10.8.3.4.39925 > 10.8.3.1.8000: Flags [S], cksum 0xdad9 (correct), seq 2570439277, win 5840, options [mss 1460,sackOK,TS val 138417450 ecr 0,nop,wscale 6], length 0
10:47:07.058015 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    10.8.3.1.8000 > 10.8.3.4.39925: Flags [S.], cksum 0x3851 (correct), seq 1066199564, ack 2570439278, win 5792, options [mss 1460,sackOK,TS val 295921514 ecr 138417450,nop,wscale 7], length 0
10:47:07.058071 IP (tos 0x0, ttl 64, id 57160, offset 0, flags [DF], proto TCP (6), length 52)
    10.8.3.4.39925 > 10.8.3.1.8000: Flags [.], cksum 0x7d60 (correct), seq 2570439278, ack 1066199565, win 92, options [nop,nop,TS val 138417451 ecr 295921514], length 0
10:47:07.058213 IP (tos 0x0, ttl 64, id 57161, offset 0, flags [DF], proto TCP (6), length 57)
    10.8.3.4.39925 > 10.8.3.1.8000: Flags [P.], cksum 0x1a40 (incorrect -> 0x8fbc), seq 2570439278:2570439283, ack 1066199565, win 92, options [nop,nop,TS val 138417451 ecr 295921514], length 5
10:47:07.058410 IP (tos 0x0, ttl 64, id 36199, offset 0, flags [DF], proto TCP (6), length 52)
    10.8.3.1.8000 > 10.8.3.4.39925: Flags [.], cksum 0x7d89 (correct), seq 1066199565, ack 2570439283, win 46, options [nop,nop,TS val 295921514 ecr 138417451], length 0
10:47:07.253294 IP (tos 0x0, ttl 64, id 57162, offset 0, flags [DF], proto TCP (6), length 53)
    10.8.3.4.39925 > 10.8.3.1.8000: Flags [P.], cksum 0x1a3c (incorrect -> 0x7321), seq 2570439283:2570439284, ack 1066199565, win 92, options [nop,nop,TS val 138417500 ecr 295921514], length 1
10:47:07.253468 IP (tos 0x0, ttl 64, id 36200, offset 0, flags [DF], proto TCP (6), length 52)
    10.8.3.1.8000 > 10.8.3.4.39925: Flags [.], cksum 0x7d27 (correct), seq 1066199565, ack 2570439284, win 46, options [nop,nop,TS val 295921562 ecr 138417500], length 0
10:47:08.060213 IP (tos 0x0, ttl 64, id 36201, offset 0, flags [DF], proto TCP (6), length 59)
    10.8.3.1.8000 > 10.8.3.4.39925: Flags [P.], cksum 0x354c (correct), seq 1066199565:1066199572, ack 2570439284, win 46, options [nop,nop,TS val 295921765 ecr 138417500], length 7
10:47:08.060270 IP (tos 0x0, ttl 64, id 57163, offset 0, flags [DF], proto TCP (6), length 52)
    10.8.3.4.39925 > 10.8.3.1.8000: Flags [.], cksum 0x7b5e (correct), seq 2570439284, ack 1066199572, win 92, options [nop,nop,TS val 138417701 ecr 295921765], length 0
10:47:08.060298 IP (tos 0x0, ttl 64, id 36202, offset 0, flags [DF], proto TCP (6), length 52)
    10.8.3.1.8000 > 10.8.3.4.39925: Flags [R.], cksum 0x7c51 (correct), seq 1066199572, ack 2570439284, win 46, options [nop,nop,TS val 295921765 ecr 138417500], length 0
10:47:08.060613 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    10.8.3.1.8000 > 10.8.3.4.39925: Flags [R], cksum 0xb0f5 (correct), seq 1066199572, win 0, length 0
.

The connection should in theory become an orphan. I'm saying "in theory",
because since the following test was added to tcp_close(), if the client
happens to send any data between the last recv() and the close(), we
immediately send an RST to it, regardless of any pending outgoing data :

        /* As outlined in RFC 2525, section 2.17, we send a RST here because
         * data was lost. To witness the awful effects of the old behavior of
         * always doing a FIN, run an older 2.1.x kernel or 2.0.x, start a bulk
         * GET in an FTP client, suspend the process, wait for the client to
         * advertise a zero window, then kill -9 the FTP client, wheee...
         * Note: timeout is always zero in such a case.
         */
        if (data_was_unread) {
                /* Unread data was tossed, zap the connection. */
                NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
                tcp_set_state(sk, TCP_CLOSE);
                tcp_send_active_reset(sk, sk->sk_allocation);
	}

The immediate effect then is that the client receives an abort before it
even gets the last data that were scheduled for being sent.

I've read RFC 2525 #2.17 and it shows quite interesting examples of what
it wanted to protect against. However, the recommendation did not consider
the fact that there could be some unacked pending data in the outgoing
buffers.

What is even more more embarrassing is that the HTTP working group is
trying to encourage browsers to enable pipelining by default. That means
that the situation above can become much more common, where two requests
will be pipeline, the first one will cause a short response followed by
a close(), and the simple presence of the second one will kill the first
one's data.

I tried to think about a finer way to process those unwanted data. Ideally,
we should just ignore until the ACK indicates that our last segment was
properly received. Then we could emit the RST.

I made a few attempts by first changing the test above like this :

-        if (data_was_unread) {
+        if (data_was_unread && !tcp_sk(sk)->packets_out) {

then fiddling a little bit in tcp_input.c:tcp_rcv_state_process() for
the TCP_FIN_WAIT1 state, but I'm not satisfied with my experimentations,
they were a bit too much experimental for the results to be considered
reliable.

What I was looking for was a way to only send an RST when the socket is
an orphan and all of its outgoing data has been ACKed. This would cover
the situations that RFC 2525 #2.17 tries to fix without rendering orphans
unusable.

Has anyone an opinion on this, or even could suggest a patch to relax
the conditions in which we send an RST ?

Thanks,
Willy


[-- Attachment #2: abort-data.c --]
[-- Type: text/plain, Size: 1512 bytes --]

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int port = 8000;
int one = 1;

struct sockaddr_in lst_a;
int lst_fd, srv_fd;
int lbuf;

char buf[1024];

void die_msg(const char *msg)
{
	if (msg)
		fprintf(stderr, "%s\n", msg);
	exit(1);
}

void die_err(const char *msg)
{
	perror(msg);
	exit(1);
}

int main(int argc, char **argv)
{
	if (argc > 1)
		port = atol(argv[1]);

	if ((lst_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
		die_err("socket");

	if ((setsockopt(lst_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) == -1)
		die_err("setsockopt");

	bzero((char *)&lst_a, sizeof(lst_a));
	lst_a.sin_family      = AF_INET;
	lst_a.sin_addr.s_addr = htonl(INADDR_ANY);
	lst_a.sin_port        = htons(port);
	if (bind(lst_fd, (struct sockaddr *)&lst_a, sizeof(lst_a)) == -1)
		die_err("bind");

	if (listen(lst_fd, 1) == -1)
		die_err("listen");

	if ((srv_fd = accept(lst_fd, NULL, NULL)) == -1)
		die_err("accept");

	fprintf(stderr, "accept() returns %d\n", srv_fd);

	if ((lbuf = recv(srv_fd, buf, sizeof(buf), 0)) == -1)
		die_err("recv");

	fprintf(stderr, "recv() returns %d\n", lbuf);

	/* now let's pretend some processing time. If the sender sends any more
	 * data during the sleep(), it causes the response to be truncated.
	 */
	sleep(1);

	send(srv_fd, "block1\n", 7, 0);
	send(srv_fd, "block2\n", 7, 0);
	//shutdown(srv_fd, SHUT_WR);
	close(srv_fd);
	return 0;
}


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox