"Chris Angelico" <ros...@gmail.com> wrote in message news:mailman.13.1442657702.21674.python-l...@python.org...
On Sat, Sep 19, 2015 at 7:49 PM, James Harris <james.harri...@gmail.com> wrote:
"Chris Angelico" <ros...@gmail.com> wrote in message
news:mailman.8.1442612439.21674.python-l...@python.org...

...

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).

The way I'm describing it, the workers never actually read from the
socket. Once that socket becomes readable, they immediately shut down,
without making the socket no-longer-readable.

Understood. Good idea. Initial thoughts on it: Would work for threads. Would save on the number of sockets required. Would not work for processes if the model was ever changed. Would make it easier for rogue packets to shut a worker down. Would not allow any way to distinguish between shutdown priorities (not something I have mentioned). Definitely feasible. I'll keep it in mind.

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.

...

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).

TCP sockets work on the basis of a master socket and any number of
spawned sockets. The master is what gives you an open port; each
spawned socket represents one connection with one client. Once you
have an established connection, the master should be able to be closed
without disrupting that. No other process will be able to connect to
you, but you'll still be able to use one end of the socket to make the
other end readable.

Agreed but I need the listening socket to remain open and listening for new connections (at least until the whole program is told to shut down).

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.

With UDP, any process that can send a UDP packet can flood the system
with them until your workers shut down. You wouldn't even notice until
it succeeds.

Is that true? You seem to be describing a non-forged attack but to get the source UDP port right wouldn't the attacker have to be runing on the same machine *and* to bind to the same port that the machine had allocated to my program? I might be wrong but I don't think the UDP stack would allow the same port to be bound again before the original had been closed.

With TCP, at least an attacker would need raw socket
access. It's still not as protected as a Unix domain socket, but it's
a bit harder for someone to do.

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!

Sure. Sockets are pretty cheap. Even if you had one for every worker,
there's room for you to have thousands (maybe tens of thousands) of
workers without a problem. I think you'll run into other scaling
problems with that many workers on one computer :)

Let's see. If I stick with my original plan then each worker would have a TCP socket and a UDP socket. The "listener" thread would have its single listening TCP socket plus it would have a UDP socket for each worker thread. Total of three sockets per worker, two of which would be UDP sockets with port numbers assigned and thus consumed.

If I go with a single "shutdown socket" then I would have just one socket per worker. That would use fewer sockets, for sure.

James

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

Reply via email to