Open Bug 1748782 Opened 3 years ago Updated 2 years ago

Reuse UDP ports for QUIC

Categories

(Core :: Networking, enhancement, P2)

enhancement

Tracking

()

Tracking Status
firefox97 --- affected

People

(Reporter: mt, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [necko-triaged])

I've received reports that some users behind NATs are encountering problems with UDP ports becoming exhausted. Reusing local ports might help alleviate this problem.

Background here is that NATs maintain tables of port allocations that map from a public IP and port to an internal IP and port. For TCP, NATs are able to remove entries from this table when the connection closes or is reset. For UDP, and QUIC especially, NATs cannot detect the end of a flow and so tend to cleanup entries on a timer. TCP entries also use a timer, but this is generally a lot longer as the FIN/RST can generally be relied on. NATs might also use a larger table for TCP as creating new TCP flows used to be more common.

All of this combines to mean that if we use a lot of QUIC, a NAT might run out of space for new bindings, which can prevent the creation of new connections.

It depends on the allocation scheme used by a NAT, but we might be able to reduce the stress on UDP binding tables in NATs by reusing local ports.

We don't request that servers use a connection ID and we probably shouldn't start doing that, so reuse would be limited to ports on which connections have been closed or abandoned already. That limits utility, but it might be sufficient.

We could reuse a port for the same remote IP address and port as that would help more types of NAT. However, the number of times that we would create a new connection to the same destination while a binding is active is limited. The type of NAT (Address and Port-Dependent Mapping) that might benefit from that sort of reuse is probably most able to cope with more flows as they have fewer hard constraints. This would only help those NATs that had artificial constraints on their table size.

What is more likely is that a NAT using Endpoint-Independent Mapping or Address-Dependent Mapping is running out of port bindings that are available for allocation. In that case, reusing ports could have a significant effect on connection success.

Reuse would require that we remember recently used ports, probably along with a time at which it was last used for sending or receiving (which is what will keep the binding active). Reusing those ports for new connections rather than asking for a new allocation might not be completely reliable, because other processes might have taken them if we released them. However, it might be worth making an attempt if we have opened a lot of ports.

The privacy implications of this sort of reuse are worth considering. Assuming that reuse results in no change in the public port allocation (that is, we're successful in avoiding the creation of a new binding at the NAT) we will expose to the outside world that the two flows come from the same client. While it is hard for us to know the NAT binding timers with any sort of reliability, we have to assume that an adversary can learn this information. Deferring reuse until we have a significant number of active flows doesn't really help in adversarial cases, but we might partition storage by container or PBM to prevent unnecessary cross-talk between those contexts.

Severity: -- → N/A
Priority: -- → P2
Whiteboard: [necko-triaged]
You need to log in before you can comment on or make changes to this bug.