Question about Snowflake behavior

The real question:
How does the Snowflake proxy think a connection is open when there is no UDP traffic from it.

The facts:
I wanted to restart the proxy with a bigger value in -capacity just to see the effects. So I do a bit of snooping looking at my proxy logs and stuff and notice a open connection which has been there for over a day. I still can’t accept that someone is surfing for over a day. There must be an artificial way to keep the connection open like some sort of heartbeat.

I do a tcpdump to display all UDP traffic to my machine. Not just once but over and over again. I see occasional traffic from that IP and more from IPs I’ve identified as open connections. I put a rule into the INPUT filter to DROP that day-old IP. Of course tcpdump shows no UDP traffic but about 1.5 hours later that connection still shows open. (insert the real question here). Rather than terminate the proxy I pull the ethernet wire and shortly after every connection is closed (the logs now say so) then I kill and restart the proxy.

The client-to-proxy connection of Snowflake does heartbeat messaging through the same WebRTC data channel that it uses for data transfer. If you want details, it uses the smux library for that. See the Snowflake paper. (edit: incorrect. This is only the case for client-to-server communication. Apologies).

I would guess whatever you did didn’t actually fully block the traffic.


For client-to-proxy connection, the proxy has a timeout here, and it’s 30 seconds. But “activity” is counted here, inside of Write (which sends data to the data channel, and not receives it).
Maybe the Pion library has a default timeout and it closes stale connections anyway, but you might be onto something :thinking: .

The proxy (server) has a default inactivity timeout of 30 seconds.

If a client is connected for this long, the client appears to send data at least every 30 seconds to maintain the connection.

Don’t know why this is marked as solution. It is not.

This should be logical except - if I break the flow of traffic anywhere between the client, my proxy, the bridge to Tor and back - somewhere, something should click that this connection is broken and should be closed. I’m assuming that whatever keeps TCP traffic reliable is being emulated or encapsulated in those UDP packets from the client.

I did NOT do a tcpdump for traffic with that IP as a destination; but as above.
Maybe it relies on the TCP connection to 02.snowflake.torproject.net to determine that the connection is alive; but as above.

Maybe I misunderstand the mechanism of iptables and conntrack.

There will be a next time. I did not mention it but this is not the first time for that IP and its partner on the same /24 network.
Next time I will put a LOG and DROP rule in the INPUT filter and I will do tcpdump for traffic to that IP destination.

I put a rule into the INPUT filter to DROP that day-old IP. Of course tcpdump shows no UDP traffic but about 1.5 hours later that connection still shows open

Apologies, I edited my previous reply.

Now to me it seems possible that the proxy never closes a client connection on its own.

But then, the server would close it when it stops receiving data from the client, thanks to smux (see the striken out text from my previous reply)…

You have pointed to the same place I discovered: webrtcconn.go where I found the comment “Closed connection due to inactivity” in function timeoutLoop except I can’t really read GO enough to diagnose anything. I will leave that to others.

Going through the iptables and conntrack mechanism convinced me I was not in left field after all.

It’s good we are in the same direction anyway.

I’m not sure if it mitigates the behavior described, but I use a shortened inactivity timeout for longer connected clients.
For example, if a client is connected for 40 minutes the proxy server calculates and reduces the inactivity timeout for this client to 25 seconds…for 80 minutes it’s 15…for 120 minutes it’s 5.

Don’t think so either but what you say is also interesting. I presume you have mofified the source code for this effect.

By your algorithm, what would 1 day be (1440 minutes)? I imagine a really short inactivity timeout.

Just as interesting is why do you do this?

When I see 1 day+ I wonder. It’s none of my business what a client does but I still smell a fish. If this person is keeping a connection open artificially then it keeps someone else from using a connection on my proxy (all theory of course). I can only get 7 open connections at any one time. I have not opened a range of UDP ports on the router so I assume this is the cause.

I’m waiting for the next time to test if it’s the UDP packets going to the client which keeps the connection open as pointed out by @WofWca

65% of my connections are between 1m and 29m. I ignore anything less. 22% are between 30m and 119m with a declining rate for 120+ minutes.

The minimum timeout that is set is 5 seconds (after a connection time of 120 minutes or more).

This is the reason why I do it. I prefer new clients over clients that sit on the connection for hours.

Nice to know I’m not alone with this idea.

Do you know, in fact, that these connections actually get closed. Do the logs show this.

I’m not doing what you do but know for sure that the inactivity timeout is NOT 8 hours. As I write this I have one. Connected 8 hrs, no UDP traffic in either direction and what I assume is it’s corresponding TCP connection to snowflake.torproject.net has traffic in both directions.

My previous attempts as above with the INPUT filter will have no effect since there IS no traffic.

Next attempt is to kill that corresponding TCP connection to the bridge to Tor just to see.