"Chris Angelico" <ros...@gmail.com> wrote in message news:mailman.8.1442612439.21674.python-l...@python.org...
On Sat, Sep 19, 2015 at 3:17 AM, James Harris <james.harri...@gmail.com> wrote:
Needless to say, on a test Windows machine AF_UNIX is not present. The only
cross-platform option, therefore, seems to be to use each subthread's
select()s to monitor two AF_INET sockets: the one to the client and a
control one from the master thread. I would seem to need IP socket pairs between the master thread and the subthreads. If the master thead receives a
shutdown signal it will send a shutdown command to each subthread.

The above seems logical but would use quite a few IP sockets. I cannot think
of a better way, though. Any comments on the ideas above?

If you're using select() to monitor the sockets, you don't actually
then have to _do_ anything with the shutdown socket. You could have a
single socket that sends the shutdown signal to all your workers.

I don't understand how a single socket could send the signal to all the workers. I did consider some form of multicast but thought it too complicated (and possibly infeasible).

Re. not understanding the single sending socket idea that you mention perhaps I had better explain a bit of what I had in mind:

1. A worker thread would have a TCP socket connection to its client, and another socket for communicating with the master. That second socket has to be AF_INET for portability. It could be TCP or UDP. A connected UDP socket may be most appropriate and seems worth trying.

2. If something happens to the master thread so that it determines that the application should shut down it would iterate over the sockets to the workers and tell each one to shut down. It would then shut itself down. (Am not sure at the moment whether to wait for the worker threads.)

3. A worker thread, being told to shutdown (basically a single byte received from the master thread) would tell its client to close the TCP connection and then it would wait a little while for it to do so - maybe a second or two. When the client closes the TCP connection (or the timeout wait period expires) the worker thread will close its end and exit.

Bear in mind, though, that Windows has no protection against other
processes shutting you down. You can restrict it to 127.0.0.1 (of
course) but any program running on the same computer as the server -
regardless of user permissions etc - will be able to connect to your
sockets.

I was thinking of a connected UDP socket. That way, AIUI, at least in the absence of forged datagrams, only the master thread will be able to communicate with the worker, due to connected UDP sockets demulitplexing datagrams based on their source as well as their destination, i.e. on a 5-tuple (UDP, source IP, source port, destination IP, destination port).

So it might be best to do something like this (all on the
main thread):

1) Open a listening socket
2) Connect to the listening socket
3) Accept a connection
4) Close the original listening socket
5) Spin off all your threads, passing them the socket from step 2
6) To terminate them all, write a byte to the socket from step 3.

That sounds similar to what I had in mind but I am not sure why you would close the listening socket. Connections could come in at any time and threads could therefore be needed at any time so I was thinking that the master thread (the one with the listening TCP socket) would just sit waiting for new connection requests (or an interrupting signal).

In reality, due to Windows not recognising signals while in the accept() call I think there would be a real master thread and a listening thread but I have omitted that in the descriptions above. As far as the normal worker threads are concerned they would be ready to be told to shut down by the listening thread, and it would be ready to be told to shut down by the master thread. Still with me? ;-)

This will make it difficult for ordinary userspace code to mess with
you. It'd still be possible, I think, for something with raw sockets
access to feign a termination signal; I have no idea what protections
Windows offers you there.

Yes, something which could forge a packet could tell a worker to close down. I don't think there's any significant problem here, thought, because:

* other programs are similarly vulnerable to forged packets
* the only forgery effect is to tell a worker thread to stop - not a big loss
* the shutdown protocol would/should cause the client to re-request
* a forger would have to know the specific port number used by the master thread to communicate with that particular worker, and the port number that worker was using.

Overall, I think it would be more than robust enough.

Notwithstanding your comment about a single socket, above, no one seems so far to have objected to the number of sockets this would need, which was my main concern, so that's good!

James

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to