Opened 6 years ago

Closed 5 years ago

#10047 closed enhancement (wontfix)

PTs could self-shutdown when they detect their stdout is closed

Reported by: infinity0 Owned by: asn
Priority: Medium Milestone:
Component: Circumvention/Pluggable transport Version:
Severity: Keywords: needs-spec-change
Cc: yawning, asn, dcf Actual Points:
Parent ID: #10629 Points:
Reviewer: Sponsor:

Description (last modified by infinity0)

In 9330 we were exploring solutions to signal a PT to do clean shutdown on Windows. In 10006 dcf suggested a workaround using JobObjects, which has the nice property that the children shutdown even when their parent crashes or is killed (SIGKILL or TerminateProcess).

This raises the valid point, why don't we try to achieve this for all platforms? Since all PTs must already communicate via stdout back to Tor (or any parent process, such as a PT chainer), one way of detecting parent death is to check that stdout is still open.

Example: http://compgroups.net/comp.unix.programmer/how-to-kill-all-child-when-parent-exits/36841

We'll need to research whether we must write to the stream to detect it's closed, or if we can get away with doing something like poll or select.

Child Tickets

Change History (8)

comment:1 Changed 6 years ago by infinity0

Description: modified (diff)

comment:2 Changed 6 years ago by asn

Yes, I like this idea.

Like you said we will need to do some research to see how hard detecting closed streams is in practice, but I think it shouldn't be too hard.

comment:3 Changed 6 years ago by infinity0

Parent ID: #10629

comment:4 Changed 6 years ago by asn

Keywords: needs-spec-change added

comment:5 Changed 6 years ago by dcf

I found that you can make this idea work without any changes to tor. All you have to do is introduce a process that interposes between tor and the pluggable transport, and write the pluggable transport so that it interprets a closed stdin as a command to terminate. tor calls TerminateProcess on the buffer process, which dies immediately. The death of the buffer process closes the stdin of the pluggable transport.

Here's a short implementation of the idea.

The terminateprocess-buffer program is what gets called by tor. terminateprocess-buffer just executes the command given by its arguments and creates a pipe to the subcommand's stdin. The way it looks in torrc is:

ClientTransportPlugin meek exec ./Tor/PluggableTransports/terminateprocess-buffer ./Tor/PluggableTransports/meek-client-torbrowser --url=https://meek-reflect.appspot.com/ --front=www.google.com --log meek-client.log

That is, you just stick "terminateprocess-buffer" in front of the command line you were using before.

I tested it in the tbb-3.5.2.1-meek-5 bundles, where the process tree looks like

tor
  terminateprocess-buffer
    meek-client-torbrowser
      firefox
      meek-client

When tor kills terminateprocess-buffer, meek-client-torbrowser notices and cleans up its own children.

(I've just realized that what's described in this comment differs a bit from the ticket description: it's testing for a closed stdin, not stdout.)

Last edited 5 years ago by dcf (previous) (diff)

comment:6 Changed 5 years ago by yawning

Hmm, I'm thinking of wontfixing this in favor of #15435 (add a pt env var that indicates that stdin will be kept open, which all new tors will set with appropriate modifications to actually keep stdin in the child open).

Rationale is that, terminateprocess-buffer checks stdin instead of stdout, and the newer ticket has a branch that does the right thing. Thoughts?

comment:7 Changed 5 years ago by infinity0

SGTM, stdin does sound better than stdout. Commented further on that ticket.

comment:8 Changed 5 years ago by yawning

Resolution: wontfix
Status: newclosed

WONTFIXing in favor of #15435.

Note: See TracTickets for help on using tickets.