Subject: [tcpm] Fwd: TCP Loopback Connections with the Same Src/Dest Port

From: Fernando Gont <[email-masked]>
Date: Sun, 21 Jul 2013 18:47:34 +0200

Folks,

Found this by chance -- probably a datapoint that advice is needed in
this area (that is, draft-gont-tcpm-tcp-seq-validation).

P.S.: Will present results from real-world testing at the next tcpm meeting.

Cheers,
Fernando

-------- Original Message --------
From: Matt Miller <[email-masked]>
Date: Wed, 17 Jul 2013 07:08:26 -0400
X-Google-Sender-Auth: ba5SYKKiksigElenhewyH0EffCs
Message-ID:
<[email-masked]>
Subject: TCP Loopback Connections with the Same Src/Dest Port
To: FreeBSD Net <[email-masked]>

Our system is based on FreeBSD 8.1.  In some tests, we were having
issues caused by connections of this form (more details below):

 TCP4      0      0      0/   0/   0    127.0.0.1.665   127.0.0.1.665
 FIN_WAIT_1
 TCP4      0      0      0/   0/   0    127.0.0.1.637   127.0.0.1.637
 FIN_WAIT_1
 TCP4      0      0      0/   0/   0    127.0.0.1.648   127.0.0.1.648
 FIN_WAIT_1

Some questions we had:

- Has anyone else ever seen these same src/dest address/port TCP
connections created?  Does anyone know of a legitimate reason why they
should be allowed?

- If there are no known use cases for this type of connection, does
anyone have more context/insight on the design here: should this type
of inpcb creation be prevented in the kernel or is it the
application's responsibility to ensure it never creates this type of
socket?

For those interested, more details of the issue seen follow.  The
connection seems to get stuck in swi_net sending and receiving pure
FIN/ACKs to itself:

#12 0xffffffff804372ce in ip_output (m=0xffffff0003ccf300,
opt=<optimized out>, ro=0xffffff8020c2b6a0, flags=0, imo=0x0,
inp=0xffffff0019933968) at ../../../../sys/netinet/ip_output.c
#13 0xffffffff804423dc in tcp_output (tp=0xffffff0019de2370) at
../../../../sys/netinet/tcp_output.c
#14 0xffffffff8043ef5d in tcp_do_segment (m=0xffffff0019af1200,
th=0x100200, so=0xffffff011ac59570, tp=0xffffff0019de2370,
drop_hdrlen=52, tlen=0, iptos=0 '\000', ti_locked=3) at
../../../../sys/netinet/tcp_input.c
#15 0xffffffff80440311 in tcp_input (m=0xffffff0019af1200,
off0=<optimized out>) at ../../../../sys/netinet/tcp_input.c
#16 0xffffffff8043530b in ip_input (m=0xffffff0019af1200) at
../../../../sys/netinet/ip_input.c
#17 0xffffffff8040889f in netisr_process_workstream_proto
(proto=<optimized out>, nwsp=<optimized out>) at
../../../../sys/net/netisr.c
#18 swi_net (arg=0xffffffff80f59800) at ../../../../sys/net/netisr.c

swi_net() just continues in this loop, ad nauseam:

 759         while ((bits = nwsp->nws_pendingbits) != 0) {
 760                 while ((prot = ffs(bits)) != 0) {
 761                         prot--;
 762                         bits &= ~(1 << prot);
 763                         (void)netisr_process_workstream_proto(nwsp,
prot);
 764                 }
 765         }

The tcp_output() being triggered in tcp_do_segment() in the case is
the one show on line 2303 below:

2212         /*
2213          * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
2214          * ACKs.  If the ack is in the range
2215          *      tp->snd_una < th->th_ack <= tp->snd_max
2216          * then advance tp->snd_una to th->th_ack and drop
2217          * data from the retransmission queue.  If this ACK reflects
2218          * more up to date window information we update our
window information.
2219          */
2220         case TCPS_ESTABLISHED:
2221         case TCPS_FIN_WAIT_1:
2222         case TCPS_FIN_WAIT_2:
2223         case TCPS_CLOSE_WAIT:
2224         case TCPS_CLOSING:
2225         case TCPS_LAST_ACK:
2226                 if (SEQ_GT(th->th_ack, tp->snd_max)) {
2227                         TCPSTAT_INC(tcps_rcvacktoomuch);
2228                         goto dropafterack;
2229                 }
...
2234                 if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
...
2248                         if (tlen == 0 && tiwin == tp->snd_wnd) {
2249                                 TCPSTAT_INC(tcps_rcvdupack);
...
2277                                 if (!tcp_timer_active(tp, TT_REXMT) ||
2278                                     th->th_ack != tp->snd_una)
2279                                         tp->t_dupacks = 0;
2280                                 else if (++tp->t_dupacks >
tcprexmtthresh ||
2281                                     ((V_tcp_do_newreno ||
2282                                       (tp->t_flags &
TF_SACK_PERMIT)) &&
2283                                      IN_FASTRECOVERY(tp))) {
2284                                         if ((tp->t_flags &
TF_SACK_PERMIT) &&
2285                                             IN_FASTRECOVERY(tp)) {
2286                                                 int awnd;
2287
2288                                                 /*
2289                                                  * Compute the
amount of data in flight first.
2290                                                  * We can inject
new data into the pipe iff
2291                                                  * we have less
than 1/2 the original window's
2292                                                  * worth of data in
flight.
2293                                                  */
2294                                                 awnd =
(tp->snd_nxt - tp->snd_fack) +
2295
tp->sackhint.sack_bytes_rexmit;
2296                                                 if (awnd <
tp->snd_ssthresh) {
2297
tp->snd_cwnd += tp->t_maxseg;
2298                                                         if
(tp->snd_cwnd > tp->snd_ssthresh)
2299
tp->snd_cwnd = tp->snd_ssthresh;
2300                                                 }
2301                                         } else
2302                                                 tp->snd_cwnd +=
tp->t_maxseg;
2303                                         (void) tcp_output(tp);
2304                                         goto drop;

I've noticed that we don't yet have this patch in our code:

http://svnweb.freebsd.org/base?view=revision&revision=239672

Which seems like it could be relevant here to the general case of both
ends of the connection entering FIN_WAIT_1 at the same time and
sending FIN/ACKs repeatedly (though our connections are a bizarre case
of this where both ends of the connection are actually the same
connection).

Thanks,

Matt
_______________________________________________
[email-masked] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[email-masked]"

-- 
Fernando Gont
e-mail: [email-masked] || [email-masked]
PGP Fingerprint: 7809 84F5 322E 45C7 F1C9 3945 96EE A9EF D076 FFF1

---

From: Joe Touch <[email-masked]>
Date: Sun, 21 Jul 2013 22:02:31 -0700

Same src/dst for the same IP makes no sense; there need to be two ends 
to a connection, and each end is supposed to be uniquely determined by 
the socket (as defined in 793, not Un*x).

IMO, it ought to be rejected by the API, just as would be one that was 
otherwise incompletely or incorrectly specified (picking a source 
address not on a local interface, picking a port range you don't have 
privilege to access, etc.).

However, loopback is a subnet (127.0.0.0/8), not just a single address. 
It ought to be feasible and correct to open a connection to yourself on 
the same port on different loopback addresses.

Joe

---

From: Fernando Gont <[email-masked]>
Date: Mon, 22 Jul 2013 07:13:48 +0200

Hi, Joe,

> the socket (as defined in 793, not Un*x).

It could be employed for IPC, without the need for two state machines.

There are still two ends -- it's just that they are the same.

> privilege to access, etc.).

Side question: There's still the issue of what to do if, say, you're
listening on IP.port:* and received a packet IP.port:IP.port (i.e., you
cannot rely on the API, because you may receive the packet on the wire
-- e.g., if it was forged).

Thanks!

Cheers,

---

From: Jakob Heitz <[email-masked]>
Date: Mon, 22 Jul 2013 05:24:51 +0000

Suppose you could have 2 ends with the same protocol identifier.

Then you could have 3. No end knows who it's talking to anymore.

Reductio ad absurdum.

--

Jakob Heitz.

________________________________
From: [email-masked] [[email-masked]] on behalf of Fernando Gont [[email-masked]]
Sent: Sunday, 21 July 2013 10:13 PM
To: Joe Touch
Cc: [email-masked]; Fernando Gont
Subject: Re: [tcpm] Fwd: TCP Loopback Connections with the Same Src/Dest Port

Hi, Joe,

---

From: Jakob Heitz <[email-masked]>
Date: Mon, 22 Jul 2013 05:30:27 +0000

Note, anycast is different.

Multiple anycast endpoints have the same address, but they

coordinate amongst themselves to appear as a single endpoint.

--

Jakob Heitz.

________________________________
From: [email-masked] [[email-masked]] on behalf of Jakob Heitz [[email-masked]]
Sent: Sunday, 21 July 2013 10:24 PM
To: Fernando Gont; Joe Touch
Cc: [email-masked]
Subject: Re: [tcpm] Fwd: TCP Loopback Connections with the Same Src/Dest Port

Reductio ad absurdum.

--

Jakob Heitz.

Hi, Joe,

---

From: Fernando Gont <[email-masked]>
Date: Mon, 22 Jul 2013 08:24:42 +0200

> Then you could have 3. No end knows who it's talking to anymore.

I don't follow... could you please elaborate?

When you try to create a third endpoint, the address would be in use.

But with only two endpoints, it's fine: since you have a local and a
remote endpoint. -- the fact that both are the same is simply a cornercase.

Cheers,
-- 
Fernando Gont
SI6 Networks
e-mail: [email-masked]
PGP Fingerprint: 6666 31C6 D484 63B2 8FB1 E3C4 AE25 0D55 1D4E 7492

---

From: David Borman <[email-masked]>
Date: Mon, 22 Jul 2013 09:17:36 -0500

It's a socket connected to itself, and thus only makes sense for a local IP address, be it the loopback address or any other address on the machine.  You can write to the socket, and then read the data back out.  If your TCP properly handles this case of a self-connected socket, then it handles a bunch of corner cases.  If you have to disallow them because it sends your system into an infinite loop of packets, then you have a latent bug just waiting to be tickled between a pair of sockets.  It's better to fix the problem than disallow the symptom.  In all these cases that I've seen, the problem is that there is valid ACK information in the packet, and the incoming TCP processing is dropping the packet without processing the ACK information.  Crossing SYNs, crossing FINs, crossing probes, they all can cause this problem if you don't process the ACK information.  The self-connected socket just guarantees that you'll hit both the crossing SYN and crossing FIN cases.

Testing that a self-connected socket works should be part of every TCP regression test.

			-David Borman

On Jul 22, 2013, at 12:02 AM, Joe Touch <[email-masked]> wrote:

> Same src/dst for the same IP makes no sense; there need to be two ends to a connection, and each end is supposed to be uniquely determined by the socket (as defined in 793, not Un*x).
> 
> IMO, it ought to be rejected by the API, just as would be one that was otherwise incompletely or incorrectly specified (picking a source address not on a local interface, picking a port range you don't have privilege to access, etc.).
> 
> However, loopback is a subnet (127.0.0.0/8), not just a single address. It ought to be feasible and correct to open a connection to yourself on the same port on different loopback addresses.
> 
> Joe
> 
> tcpm mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tcpm

---

From: Joe Touch <[email-masked]>
Date: Mon, 22 Jul 2013 08:35:50 -0700

> Testing that a self-connected socket works should be part of every TCP regression test.

 From RFC793:

     To allow for many processes within a single Host to use TCP
     communication facilities simultaneously, the TCP provides a set of
     addresses or ports within each host.  Concatenated with the network
     and host addresses from the internet communication layer, this forms
     a socket.  A pair of sockets uniquely identifies each connection.

This text says "a pair". I interpreted that as prohibiting use of a 
single socket for both ends, but I suppose you could allow it to happen.

The benefit of that situation is it would test simultaneous open and 
close, but note that some docs have written those off lately when we 
think that "can't" happen.

You'd have to prove that every protocol could handle simultaneous cases 
and state.

The key question is "why would this ever happen, or should it ever 
reasonably happen"? It's just as easily handled by having the Un*x 
socket "lie" about having TCP and just copy the buffer from send to 
receive - and what, really, is the point of that?

Joe

---

From: David Borman <[email-masked]>
Date: Mon, 22 Jul 2013 12:49:25 -0500

On Jul 22, 2013, at 10:35 AM, Joe Touch <[email-masked]> wrote:

> This text says "a pair". I interpreted that as prohibiting use of a single socket for both ends, but I suppose you could allow it to happen.

Yeah..., I don't make that interpretation.  Logically it's still a pair, it just happens to be that the same socket is being used for both sides of the pair.  Self connected TCP sockets have been around and working for a long time (they worked in CSRG BSD, I know because I fixed 'em), but people make changes to code and don't test for self-connected sockets, so they can get broken. And when things break for self connected sockets, the same situation can happen with a pair of sockets.  You can test all the same cases with a pair of sockets, it just takes more work to get the timing just right.

> 
> The benefit of that situation is it would test simultaneous open and close, but note that some docs have written those off lately when we think that "can't" happen.

And that's when the bugs creep in. :-)

> 
> You'd have to prove that every protocol could handle simultaneous cases and state.

For every protocol used by sockets?  No, this is only about TCP sockets, not sockets in general.  Different protocols have different semantics, it doesn't matter what other protocols will or will not allow.

> 
> The key question is "why would this ever happen, or should it ever reasonably happen"? It's just as easily handled by having the Un*x socket "lie" about having TCP and just copy the buffer from send to receive - and what, really, is the point of that?

I disagree, that question is a red herring.  It doesn't matter whether or not you have an application use for it, it ought to work, and as a test tool it's an easy way to verify that crossing SYNs and crossing FINs are being handled properly.

			-David Borman

P.S. A use case?  Besides testing, the only semi-useful case that pops into my mind would be to pass data across an exec() call in lieu of using a tmp file, but you can also do that with a pair of sockets and a little more work.

---

From: Joe Touch <[email-masked]>
Date: Mon, 22 Jul 2013 11:02:23 -0700

On 7/22/2013 10:49 AM, David Borman wrote:
> For every protocol used by sockets?  No, this is only about TCP
> sockets, not sockets in general.  Different protocols have different
> semantics, it doesn't matter what other protocols will or will not
> allow.

I meant for every TCP extension, modification, and option.

I've never ignored such cases, but I do recall others doing so (I'm not 
fully online today and can't easily grep for that, though).

Joe

---

From: Joe Touch <[email-masked]>
Date: Mon, 22 Jul 2013 11:07:34 -0700

On 7/22/2013 10:49 AM, David Borman wrote:
> P.S. A use case?  Besides testing, the only semi-useful case that
> pops into my mind would be to pass data across an exec() call in lieu
> of using a tmp file, but you can also do that with a pair of sockets
> and a little more work.

If there are two processes, then there ought to be two different 
processes (or subprocesses if you prefer).

I.e., this is fine reason for 127.0.0.1:600 talking to 127.0.0.1.599, or 
for 127.0.0.1:600 talking to 127.0.0.2:600.

Joe

---

From: Joe Touch <[email-masked]>
Date: Mon, 22 Jul 2013 11:16:40 -0700

> processes (or subprocesses if you prefer).

Let me try typing that again:

If there are two different processes (or subprocesses if you prefer), 
then there ought to be two *different* sockets.

---

From: David Borman <[email-masked]>
Date: Mon, 22 Jul 2013 13:27:32 -0500

On Jul 22, 2013, at 1:16 PM, Joe Touch <[email-masked]> wrote:

> If there are two different processes (or subprocesses if you prefer), then there ought to be two *different* sockets.

No, only one process, doing an exec(), no fork() involved.  Since all your data gets lost across an exec(), a typical way to pass data across an exec() is either as command line arguments to the exec() call or via a tmp file, depending on how much data you need to pass.
			-David

---

From: Joe Touch <[email-masked]>
Date: Mon, 22 Jul 2013 11:52:49 -0700

On 7/22/2013 11:27 AM, David Borman wrote:
>> >If there are two different processes (or subprocesses if you prefer), then there ought to be two*different*  sockets.
> No, only one process, doing an exec(), no fork() involved. Since all
> your data gets lost across an exec(), a typical way to pass data across
> an exec() is either as command line arguments to the exec() call or via
> a tmp file, depending on how much data you need to pass.

That's a potential argument for a self-(un*x)socket, but not a self-TCP 
socket.

There's no argument here why TCP needs to be involved.

Joe

---

From: Joe Touch <[email-masked]>
Date: Mon, 22 Jul 2013 12:00:53 -0700

Further, FWIW, I'd argue:

	- if you are the same process, a socket is not an appropriate
	place to "store" anything
		local variables for small things
		external storage for large things

		there's nothing you can store in a socket that you
		can't more efficiently store in local memory, within
		a single process

	- every doc I've read on exec() refers to the transition
	as either crossing processes (terminating the caller,
	starting a new process for the callee) or 'subprocesses'
	(when the caller doesn't terminate)
		that's not the "same process"

Not all corners are worth considering.

Joe

On 7/22/2013 11:52 AM, Joe Touch wrote:
>>> >If there are two different processes (or subprocesses if you
>>> prefer), then there ought to be two*different*  sockets.

---

From: Tim Shepard <[email-masked]>
Date: Mon, 22 Jul 2013 15:21:19 -0400

> 		that's not the "same process"

No, exec() replaces the program (the executable) in the current
process.  It has always been that way as long as I can remember in
all the various flavors of unix and unix-like systems I've used.  I
just looked and the wikipedia article on exec seems to describe it
correctly.

And I see no reason to prohibit self-connection of a TCP, and I like
David Bormon's observation about it being an important test case in
the test suite.

The semantics of self-connection seem straightforward to me.  Works
the same as a self-connected TCP implemention via a mirror host.
(Mirror host is a testing hack where the mirror host at some IP
address out there simply swaps source and destination ports and IP
addresses in every packet it receives and sends the packet back out
which, I'm told, was a very useful testing hack in the early days
of TCP).

			-Tim Shepard
			 [email-masked]

---

From: Michael Tuexen <[email-masked]>
Date: Mon, 22 Jul 2013 21:50:28 +0200

> David Bormon's observation about it being an important test case in
While testing the SCTP stack of FreeBSD we also used this. It is
a very useful testcase...

Best regards
Michael

---

From: Joe Touch <[email-masked]>
Date: Tue, 23 Jul 2013 08:48:06 -0700

Hi, all,

OK, I've been convinced that supporting such loopback isn't prohibited 
by 793, but I remain convinced that supporting it within the protocol 
isn't strictly required.

There are other cases where TCP implementations take shortcuts when it 
knows better - e.g., ignoring congestion control when both ends are on 
the same subnet. TCP could just as easily ignore the entire state 
machine when both sockets are identical and just reflect everything back 
in one step, or the Un*x socket layer could do so directly.

IMO, an app that wants to talk to itself ought to either use different 
ports or different looback addresses (or both) - though, given my 
experience with Linux of late (65K total connection limit), I'd be more 
surprised if that works too.

However, the case below also hints at a bug where both ends enter 
FIN-WAIT-1 at the same time - which can happen whether reflexive or not, 
and should be fixed anyway.

Joe

---

From: Fernando Gont <[email-masked]>
Date: Tue, 30 Jul 2013 00:43:44 +0200

HI, Joe,

> by 793, but I remain convinced that supporting it within the protocol

Well, there's nothing in RFC793 that relieves you from supportng that
corner case....

> in one step, or the Un*x socket layer could do so directly.

In the same way it could do that when both endpoints are on the same node...

> surprised if that works too.

What would be the rationale for that "ought to"?

> and should be fixed anyway.

Agreed.

Thanks for the input, by the way!

Cheers,
Fernando

---

From: Joe Touch <[email-masked]>
Date: Mon, 29 Jul 2013 16:13:09 -0700

> Well, there's nothing in RFC793 that relieves you from supportng that

That depends on the interpretation of a few key sentences in that RFC.

> In the same way it could do that when both endpoints are on the same node...

Yes, but that would not require support by the actual exchange of 
reflected messages.

> What would be the rationale for that "ought to"?

There seems little point in pushing a corner case of TCP when it can be 
avoided by implementing both ends independently. There are 250+ loopback 
addresses.

Joe

---

From: Fernando Gont <[email-masked]>
Date: Tue, 30 Jul 2013 01:47:56 +0200

> That depends on the interpretation of a few key sentences in that RFC.

May be. The way I rad it is that you need a local endpoint, and a remote
endpoint. But there's nothing in RFC 793 that requires both endpoints to
be different.

> Yes, but that would not require support by the actual exchange of

Well, you actually need special code to *not* support reflected
endpoints -- at the end of the day, reflected endpoints are just a
specific case of "simultaneous open".

> avoided by implementing both ends independently. There are 250+ loopback

I see it exactly the other way around: you need additional code not to
support mirrored end-points, since you essentially have to disable a
corner case that *would* work if you already support simultaneous opens
(which you must support).

Cheers,

---

From: Joe Touch <[email-masked]>
Date: Mon, 29 Jul 2013 16:55:44 -0700

On 7/29/2013 4:47 PM, Fernando Gont wrote:
> at the end of the day, reflected endpoints are just a

They're more than that.

They're simultaneous everything, with the same ISN.

FWIW, an app needs special code to deal with the self-reflected case 
anyway - it needs to know that only one incarnation should close the 
connection, vs. giving each incarnation a unique socket pair.

I recall that there have also been extensions that don't handle the 
simultaneous case - that basically just punt, and say "try again" when 
it happens. When these are two different sockets, that's a reasonable 
approach; when it's a single reflexive socket, it would continually fail.

Joe

---

From: Fernando Gont <[email-masked]>
Date: Tue, 30 Jul 2013 02:58:15 +0200

> They're simultaneous everything, with the same ISN.

Does it really matter that the ISNs are the same? (packets are not
actaully traveling over a network)

> connection, vs. giving each incarnation a unique socket pair.

Well, if the connection is closed, you get a simultaneous close.

[Yes, if anything, I would only expect applications that "really know
what they're doing" to use this "mirrored-endpoints connections"...
However, when ti comes to kernel code, it takes more work to not support
them , than to do it (assuming that you support simultaneous opens,
simultaneous closes, etc.)]

> approach; when it's a single reflexive socket, it would continually fail.

Me, I'd argue that if e.g. simultaneous-opens are part of TCP, your
extension should work with them rather than rely on "let's retry and
hope that the SYNs don't cross on the network".

Cheers,

---

From: Joe Touch <[email-masked]>
Date: Mon, 29 Jul 2013 18:18:40 -0700

> actaully traveling over a network)

It doesn't to me, but again this is a corner case that some systems 
don't expect.

> Well, if the connection is closed, you get a simultaneous close.

So from an app-writer's viewpoint, why would all connections be 
simultaneous open and simultaneous close? What if that's a case that 
either the protocol or the app doesn't want - maybe it wants to try to 
de-sync by executing a timer and retrying.

It won't work on a reflexive socket. It will work everywhere else.

> simultaneous closes, etc.)]

I disagree; the work to not do it is very simple (it's just a test). The 
work to ensure it always works could be a lot more.

The key question isn't whether this is a 'fun case' that the protocol 
ought to handle; it's whether we should bother to ensure it is always 
supported. IMO, the special case is a lot simpler than testing every 
possible alternative.

> hope that the SYNs don't cross on the network".

"handling simultaneous opens" can be done two ways:
	- support them
	- don't support them, and retry to de-sync

The latter will never work with reflexive connections, but it's just as 
valid an approach.

Joe

---

From: Fernando Gont <[email-masked]>
Date: Tue, 30 Jul 2013 03:28:16 +0200

> It doesn't to me, but again this is a corner case that some systems

If it doesn't matter, then there's no problem if systems do not expect it.

> either the protocol or the app doesn't want 

You just don't use mirrored endpoints.

> I disagree; the work to not do it is very simple (it's just a test). 

THat's additional code -- no matter how simple it is.

> The

That's assuming your TCP impleemntation is broken in terms of
simultaneous opens, simultaneous closes, etc. -- i.e., if your
implementation is buggy, fix it.

> supported. IMO, the special case is a lot simpler than testing every

Not sure what you mean.

> The latter will never work with reflexive connections, but it's just as

So.. yu're arguing that a piece of of RFC 793 (that is part of TCP)
should not be supported?

Part of TCP is support for simultaneous opens. If you don't support
them, ether that's not TCP, or that's a buggy implementation.

Cheers,

---

From: Joe Touch <[email-masked]>
Date: Mon, 29 Jul 2013 19:55:32 -0700

> You just don't use mirrored endpoints.

But that's the point. If they behave differently they're not useful. 

> implementation is buggy, fix it.

It's more than that. Simultaneous < reflexive. 

>> supported. IMO, the special case is a lot simpler than testing every

Not sue I can explain better.  This is the crux of my concern. It's cute thst it could work but not necessary that it should.  

> them, ether that's not TCP, or that's a buggy implementation.

Again simultaneous < reflexive. 

Joe

---

From: Fernando Gont <[email-masked]>
Date: Tue, 30 Jul 2013 10:16:13 +0200

> Again simultaneous < reflexive. 

There is no difference in the TCP code that is required for
mirrored-endpoint-connections than the code that is required for
simultaneous-{open, close} to work.

In any case, my take is that the high-order-bit of this I-D is not the
mirrered-endpoint connections, but rather all the other stuff: the
update that is needed for simultaneous opens, simultaneous closes, and
simultaneous probes to work as expected -- and it looks like everyone
(both of us, and other folks that have viced their opinion, plus the
implementations out there) agrees that that must be addressed.

The mirrored-endpoints corner case is something on which I have a
position, but, as noted, is a secondary issue (at the end of the day, I
could myself live with not supporting them).

Thanks,

---

From: Joe Touch <[email-masked]>
Date: Tue, 30 Jul 2013 09:50:35 -0700

> simultaneous-{open, close} to work.

First, there is code in TCP to deal with similar special cases (e.g., 
not negotiating the window size when on the local subnet). So there's 
already similar special-case code deployed.

However, as I noted, the simultaneous open/close is only a subset of 
what needs to be vetted to ensure reflexive connections work.

> implementations out there) agrees that that must be addressed.

I agree with that.

> could myself live with not supporting them).

I agree this is a separate issue.

Joe