Subject: [BEHAVE] TCP listen/connect in TURN

From: Evgeniy Khramtsov <[email-masked]>
Date: Thu, 26 Apr 2007 22:46:20 +1000

draft-ietf-behave-turn-03 para 4.1 says:

"For TCP connections, the Connection Request allows the client to ask 
the server to open a connection to the peer. This also adds a permission 
to accept an incoming TCP connection from the remote address of the peer."

AFAIK, it is not possible to accept()/connect() on/from the same port 
simultaneously (at least with Berkley sockets). I just wonder how to 
implement such behavior of the TURN server?

_______________________________________________
Behave mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/behave

---

From: "Dan Wing" <[email-masked]>
Date: Thu, 26 Apr 2007 12:49:22 -0700

You should just need to connect() -- TCP simultaneous open will handle the
case where the SYNs cross (see figure 10 in RFC761).

-d

> -----Original Message-----
> From: Evgeniy Khramtsov [mailto:[email-masked]] 
> Sent: Thursday, April 26, 2007 5:46 AM
> To: Behave WG
> Subject: [BEHAVE] TCP listen/connect in TURN
>

---

From: Saikat Guha <[email-masked]>
Date: Thu, 26 Apr 2007 17:12:31 -0400

> implement such behavior of the TURN server?

Actually, it is possible. Perhaps a bug or undocumented feature, but it
works on Linux and Windows for sure, OSX as well I believe and by
extension on BSD too.

1: a = socket()
2: c = socket()
3: setsockopt(a, SO_REUSEADDR)
4: bind(a, port)
5: setsockopt(b, SO_REUSEADDR)
6: bind(c, port)
7: listen(a)
8: connect(c, remote)

The above sequence succeeds and does what is expected.

Interestingly, swapping lines 6 and 7 doesn't work; neither does
swapping lines 7 and 8 IIRC. Calling listen(c) in line 8 doesn't work,
but that's expected. Having and additional socket c2 with bind(c2, port)
before line 7 and connect(c2, remote2) after line 7 also works.

For current OSs, as long as:
1. All sockets are bound to the local port before listen/connect is
called on any one of them.
2. Listen is called on at most one socket and is called before all
connect's
It all works.

-- 
Saikat

---

From: Saikat Guha <[email-masked]>
Date: Thu, 26 Apr 2007 17:17:12 -0400

> case where the SYNs cross (see figure 10 in RFC761).

If the remote NAT does not have endpoint independent mappings
(non-BEHAVE compliant NAT) but the local NAT has either endpoint
independent or address dependent filtering (both BEHAVE recommended)
then ...

calling just connect() and waiting for TCP S-O will not work since the
remote side will be using a different address/port tuple than what the
local side expects.

however, calling both listen() and connect() will work. connect() will
punch the hole for the remote address. The remote SYN will come in
(passing the address dependent filtering test). It'll be ignored by the
socket which connect() was called on (5-tuple mismatch), but will be
picked up by the socket listen() was called on (destination addr/port
matches local binding).

---

From: "Evgeniy Khramtsov" <[email-masked]>
Date: Fri, 27 Apr 2007 15:34:49 +1000

> 2. Listen is called on at most one socket and is called before all
That's really cool, but this 'dirty hack' will not work on mulitple Connect
Requests since we cannot bind another socket for connection on the same port
after line 8. IMHO :)
_______________________________________________
Behave mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/behave

---

From: Saikat Guha <[email-masked]>
Date: Fri, 27 Apr 2007 02:44:05 -0400

>         Having and additional socket c2 with bind(c2, port)

> That's really cool, but this 'dirty hack' will not work on mulitple
> Connect Requests since we cannot bind another socket for connection on
> the same port after line 8. IMHO :)

True, although the server can preallocate a pool of sockets for a
connection and keep them bound. It can then support multiple requests
from the same port until that pool runs dry. The size of the pool can
vary at creation time of course.