sweep
One pass over the range: the first port free on every addrs wins, and a port that binds only some of them is given back before moving on. Null once the range is exhausted. Each refusal is logged at DEBUG rather than kept — climbing past a taken port is what this is for, not an anomaly, and a single retained exception would be an arbitrary one of many.