4

I developing a distributed reverse proxy called PortFusion. Its initial goal was to establish long-time, minimal-overhead, high-throughput TCP tunnels through firewalls especially for RDP -- few, long-lived connections.

Now though, to answer user demand for security and for helping activists, I am extending it to support encryption and supporting lots of short-lived connections.

Network:

          Hu 1000 <============ Cx 1000 Au
           [ 1001                  1001=Ax:1000
              ^                             |
              |                             |
              |                             |
              |                             v
          Cu 1001 Au                    Hx 1000
Squid <----- 1001=Au:3128                [ 1001 <----- Firefox

Legend:

  u  you
  x  person x

  A  address
  H  PortFusionHost
  [  hosted service
  C  PortFusionClient

  <  establish               bidirectional link
  =  encrypted, secure,      bidirectional link
  -  localhost-only, normal, bidirectional link

Notes:

  - Squid as a forward HTTP proxy
  - Connection between two parties (===) are secure and encrypted
  - Cu is in complete control of what services are shared with Hx
  - A single Hu and a single Cu can handle multiple persons x y z

Questions:

In the network set-up above, I check the Connected property of sockets, for example the one Hx accepts from Firefox @Ax:1001, to propagate closures to corresponding mirroring sockets used by Cu to communicate with Squid.

But they always stay connected!!

  • Why do Firefox sockets always stay connected?
  • Is Firefox not responsible for closing the sockets it opens for HTTP requests once it has got responses?
  • Are there other external triggers I am missing that I can sense and use for closing sockets?

Information Regarding Accepted Answer

Using the Connected property of sockets was wrong. Following the tip in the accepted answer, I read this post and this MSDN article.

After the changes shown below, now both ends get immediately notified as soon as a request is fully responded to and closure propagation is working beautifully as expected. (In the past there was a different mechanism kicking in eventually clearing inactive sockets but it was not fast enough.)

Code (F#) Before:

            try
                request serverPort cl [||]
                while transmitting && socket.Connected do
                    if socket.Available = 0
                    then Thread.Sleep Wait
                    else let length = read()
                         LogFlow "<:>" "Read" serverPort "<-" client   length
                         request serverPort cl <| Array.sub   buffer 0 length
            with

Code After:

            try
                request serverPort cl [||]
                while transmitting && read() > 0 do
                    let length = !lengthR
                    LogFlow "<:>" "Read" serverPort "<-" client   length
                    request serverPort cl <| Array.sub   buffer 0 length
            with

where read contains a call to Socket.Receive and sets lengthR.

Community
  • 1
  • 1
Cetin Sert
  • 4,112
  • 4
  • 32
  • 69

2 Answers2

1

Many HTTP requests are done with Keep-Alive turned on, because as you may know establishing a TCP connection takes a significant amount of time. Any browser could do this, not just Firefox.

I wouldn't be surprised to see sockets left open for a long time, so long as they close when Firefox does.. they do, don't they?

Kieren Johnstone
  • 38,866
  • 13
  • 82
  • 137
  • Do they? Hmm let me check. Btw, how can I deal with port exhaustion in the face of Keep-Alive? – Cetin Sert Dec 20 '11 at 21:32
  • For a single PC/machine, there won't be more than 2 or 3 (by default) connections left open to each server/site. Very hard to get near to the limit that way - but if there are 100 users it's a lot easier, obviously. A HTTP proxy would be one way of controlling it; after a response is sent, you could simply terminate the connection. Or simply not support Keep-Alive. That would force the browser's hand. – Kieren Johnstone Dec 20 '11 at 21:34
  • PortFusion was also designed to be blissfully protocol-unaware. I didn't want it to get dirty by having different code handling different behaviors of all kinds of protocols. I can make hooks available for interested plug-in developers in the absolute worst case. Before it comes to that though, I would first like to learn/find and try solutions that would not be specific to a single protocol. – Cetin Sert Dec 20 '11 at 21:40
  • Thank you for your tip on `Keep-Alive`! – Cetin Sert Dec 21 '11 at 06:17
1

The 'connected' property refers to the socket, not to the connection. There is no connected state for cononections. They are connected until you get an EOS when reading, or an error when reading or writing. What you should be propagating is the EOS condition. You do that in a proxy by shutting down the output of the downstream socket. The proxy base product you are using should already do all that.

user207421
  • 289,834
  • 37
  • 266
  • 440
  • Your tip on the nature of `Connected´ helped me fix the problem!! I am updating the question with links to related articles and what I was doing wrong. – Cetin Sert Dec 21 '11 at 06:05