mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
6cf9ee9d03
* fix(dhcp): retransmit within a DORA transaction instead of restarting it nclient4's retryFn re-sends the same packet under the same xid with a doubling read deadline, which is RFC 2131 4.1 retransmission. WithRetry(1) runs that loop exactly once, so the client transmitted a single DISCOVER per attempt and never retransmitted it. socketTimeout then handed that lone transmission the caller's whole budget, so it sat silent for 4s, then 8s, then 16s, then 32s. Manager does retry, on that schedule, but each attempt builds a fresh client and therefore a fresh xid. Every attempt is a new transaction rather than a retransmission of the previous one, so an OFFER answering an earlier exchange is discarded as belonging to an unknown transaction. Send six transmissions per exchange starting from a 1s read, spanning a 63s ladder — longer than the widest window Manager schedules, so an attempt ends on the caller's context rather than on an exhausted ladder. socketTimeout now clamps to the caller's remaining budget instead of consuming it in one silent read. Observed live recovering an exchange whose OFFER arrived on the third transmission, which a single-shot client would have missed. Both allocation sites also stop replacing the allocator's error with a bare InsufficientAddressCapacity. ResolveErrorCode unwraps, so a genuinely exhausted static pool still surfaces that code while a DHCP fault reports as itself. The flat mapping is why every failure on this path read as a capacity problem regardless of cause. * chore(dhcptest): add --broadcast so the probe can mirror vpcd's Acquire path * fix(dhcp): resolve the chaddr on renew and release, not just on acquire Acquire derived a chaddr when the request carried none. Renew and Release read lease.HWAddr straight out of the store and handed it to nclient4, so a lease persisted before the chaddr was carried renewed with all zeros in chaddr and option 61 fell back to its untyped form. The lease then lands upstream with no hardware address against it — the outcome option 61 was fixed to stop, reached by a different route — and because the server sees an unknown client each time, every renewal takes a new lease. resolveHWAddr now serves all three paths and treats all-zeros as unusable rather than merely empty: six zero bytes passes a width check yet is the exact value that produces the unattributable entry. * test(dhcp): cover chaddr resolution and the unmasked allocation errors