Andrei G has uploaded a new patch set (#2). ( https://gerrit.osmocom.org/c/libosmocore/+/43575?usp=email )
Change subject: core/socket: sockaddr_cmp: compare fields ......................................................................
core/socket: sockaddr_cmp: compare fields
osmo_sockaddr_cmp() decides whether two addresses are equal with a memcmp() over the whole struct sockaddr_in or sockaddr_in6. On Linux those structures hold only family, port, address and padding, so the comparison is exact. On Darwin and the BSDs the first byte is sin_len / sin6_len. The kernel fills it in on recvfrom() and accept(), while an address the application built from configuration leaves it zero. The same peer then compares as two different addresses.
Every static NS-VC in gprs_ns2 breaks on this. The answer to the first NS-RESET arrives from the configured remote, gprs_ns2_udp.c cannot match it to the NS-VC ("Ignoring NS RESET ACK from newconnection for non-existing NS-VC", gprs_ns2.c:1066) and the link never leaves RESET. Observed with osmo-pcu against osmo-sgsn on Darwin loopback: the SGSN side, which learned the peer from the packet, goes to BLOCKED and then loses every NS-ALIVE-ACK, while the PCU side stays in RESET. Dynamic NS-VCs are unaffected because their remote address is a copy of what recvfrom() returned.
Compare the fields instead of the bytes: port and address for AF_INET, port, flow info, address and scope id for AF_INET6, in the order memcmp() visited them, so the ordering the function gives to sorted users does not change. The default branch keeps its memcmp() over the full osmo_sockaddr. Linux behaviour is unchanged.
Change-Id: I75fc62a92f546a906dbb1440984d62f962579255 Signed-off-by: Andrei Gosman andrei.gosman@gmail.com --- M src/core/socket.c 1 file changed, 30 insertions(+), 4 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/75/43575/2