On 24 Nov (21:30:16), Micah Lee wrote:
[snip]
Greetings Micah!
But with v3 onion services, as soon as the OnionShare web server finishes sending the full HTTP response, the torified HTTP client stops downloading. I made a small python script, onion-bug.py, that reproduces the issue that you can test [2].
This is definitely on "tor" side. Here is what is going on:
When a DEL_ONION command is received, the v3 subsystem will close _all_ related circuits including the rendezvous circuit (where the data is being transferred).
This is something the v2 subsystem does *not* do so there is your difference between the two versions. Not closing the rendezvous circuit has the side effect that the connected client can still talk to the .onion as long as the application is still running behind. In the case of OnionShare, I don't think it matters since the Web server is simply gone by then.
That being said, I see that your Python script waits until everything has been given to "tor" before sending a DEL_ONION (correct me if I'm wrong). So then the question is how can the circuit dies _before_ everything was sent to the client if tor has recevied everything?
This is due to how tor handles cells. A DESTROY cell (which closes the circuit down the path) can be sent even if cells still exist on the circuit queue. In other words, once a DESTROY cell is issued, it will be high priority and thus can leave behind some data cells. There are reasons for that so this isn't a "weird behavior" but by design.
The solution here is to make v3 act like v2 does, that is close everything except the existing established RP circuit(s) so any transfer can be finalized and let the application on the other side close connections or simply stop serving.
I've opened this and marked it for backport: https://trac.torproject.org/projects/tor/ticket/28619
Big thanks to everyone on that OnionShare ticket for the thorough report! David