SimplePush: UDP: handle port being in use from previous invocation

RESOLVED WONTFIX

Status

()

Core
DOM: Push Notifications
RESOLVED WONTFIX
5 years ago
2 years ago

People

(Reporter: nsm, Assigned: nsm)

Tracking

Trunk
x86_64
Linux
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(3 attachments)

If the UDP port 2442 is in use due to a previous process crash or some other reason, try a different port.
If a process crashes, all of its open sockets should get cleaned up, and UDP sockets should get released right away (unlike TCP sockets, with their TIME_WAIT state); so the port _should_ be available right away.

I haven't seen this, but the Internets seem to suggest that the port may linger if there is still outgoing data to get sent, but setting the SO_REUSEADDR socket option should resolve that.
Assignee: nsm.nikhil → nobody

Updated

5 years ago
Assignee: nobody → acperez

Comment 2

5 years ago
The UDP server currently makes the bind with the 'PR_SockOpt_Reuseaddr'. I don't think this is a good approach, as Mike said UDP does not have a TIME_WAIT state so when a process crash the socket is released and there is no need to use the  'PR_SockOpt_Reuseaddr' socket option.

With the current implementation I tried to launch two UDP servers using the same port and I see that both sockets keep listening on the same port but only the last receive packets. The first server doesn't receive any error but it will never get a packet. From my point of view, the best option is to remove the 'PR_SockOpt_Reuseaddr' socket option and notify to the second server that the port is already in use, thus the application is responsible to change it and solve the problem.

Comment 3

5 years ago
As proposed by Nikhil I created a script with a loop running a xpcshell that launches the udp server without the 'PR_SockOpt_Reuseaddr', after a second sends a SIGKILL and launch the server again. After 1000 iterations no errors happened due to port already in use.

Comment 4

5 years ago
Created attachment 727556 [details] [diff] [review]
Patch 1: Fix behavior when port already in use
Attachment #727556 - Flags: review?(honzab.moz)
Attachment #727556 - Flags: review?(honzab.moz) → review+
Assignee: acperez → nsm.nikhil
Attachment #727556 - Attachment description: Fix behavior when port already in use → Patch 1: Fix behavior when port already in use
Created attachment 733124 [details]
Patch 2: [DO NOT LAND] Shim to bind on port 2442

This should be applied before patch 3. It is useful for testing.

It creates a PortBlockingService that captures port 2442 (default push udp port) 5seconds after it is created.

It also modifies PushService to start the websocket as soon as the service is inited and to attempt setting up UDP 15s later (even if the server does not disconnect the websocket).
Created attachment 733125 [details] [diff] [review]
Patch 3: Try 100 ports linearly

This is a first attempt.

Patch linearly searches a 100 ports starting from 2442 until one can be bound. If that fails or the UDP socket fails for some other reason, switches back to WebSocket.

If the port has changed, reestablishes WS connection once to notify server of the new hostport pair.
Attachment #733125 - Flags: feedback?(justin.lebar+bug)
> Patch linearly searches a 100 ports starting from 2442 until one can be bound.

I should think that trying a bunch of random ports over 1024 would be saner than this.  With this implementation if some software happens to acquire a bunch of ports around 2442, we're screwed, whereas if we pick random ports, it's much harder for us to be DOS'ed.
Supposing we can't open a UDP port, how does the push server know not to close the WS connection and try to switch to UDP again?
Attachment #733125 - Flags: feedback?(justin.lebar+bug)
(In reply to Justin Lebar [:jlebar] from comment #8)
> Supposing we can't open a UDP port, how does the push server know not to
> close the WS connection and try to switch to UDP again?

Good point. On failure to open UDP, the client should send a hello without a hostport so that the server doesn't try to disconnect. Is this a failure case worth handling though? I mean in terms of the odds of not being able to open a UDP socket on multiple random ports are astoundingly low unless some other process on the phone is just being a prick. Can firewalls which have blocked UDP prevent the socket from being created?
> Can firewalls which have blocked UDP prevent the socket from being created?

Software that happens to be running as root on the phone can do whatever it wants, of course.  I'm not sure if those are the sorts of firewalls you had in mind.

Anyway we should design protocols that fail elegantly instead of spin in a busyloop forever.

Updated

5 years ago
Component: General → DOM: Push Notifications
Product: Boot2Gecko → Core
Version: unspecified → Trunk
Closing this out, since UDP wake-up was removed in bug 1265914.
Status: NEW → RESOLVED
Last Resolved: 2 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.