• src/xpdev/netwrap.c

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Mon Mar 2 22:42:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/5ad72a8fa1261e4573b58d45
    Modified Files:
    src/xpdev/netwrap.c
    Log Message:
    getNameServerList() was returning a list with (1) blank entries

    ... when the host was configured with no IPv4 DNS servers.

    So don't add blank IP addresses to the list of hostnames returned from this function. If there are no IPv4 DNS servers, this function should've (and will now) return an empty list.

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deucе@VERT to Git commit to main/sbbs/master on Sun Mar 15 16:01:53 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/4d10a54239ab8c52d2061abf
    Modified Files:
    src/xpdev/netwrap.c
    Log Message:
    Fix addrinfo linked list traversal in parseIPv6Address()

    cur++ is undefined behavior on a linked list — addrinfo nodes from getaddrinfo() are not contiguous in memory. Use cur = cur->ai_next
    to follow the linked list correctly.

    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

    ---
    ï¿­ Synchronet ï¿­ Vertrauen ï¿­ Home of Synchronet ï¿­ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Sat Mar 21 20:05:42 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/775e87a6145aaaf4673a8e52
    Modified Files:
    src/xpdev/netwrap.c
    Log Message:
    Add IPv6 support to getHostNameByAddr()

    Make isValidAddressString() work on Windows when WinSock hasn't already been initialized.
    Update the buffers passed to xp_inet_pton() from isValidAddressString() to be non-structs (which were getting clobbered by xp_inet_pton()).

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Mon Jul 27 02:09:08 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/0ed3f6b3f2b2827cb3ec6a03
    Modified Files:
    src/xpdev/netwrap.c
    Log Message:
    xpdev: an IPv6 address resolved to the local host's name

    xp_inet_pton() returns 1 on success, 0 when the string is numeric but not
    of the requested address family, and -1 when it doesn't parse at all. getHostNameByAddr() and isValidAddressString() tested for "not -1", so the
    0 case counted as success.

    That gave getHostNameByAddr() a wrong answer rather than no answer: an
    IPv6 argument took the IPv4 branch with sin_addr never written, and getnameinfo() on the resulting 0.0.0.0 succeeds, returning the local
    host's name. Every IPv6 address reverse-resolved to the local machine,
    the QWK message from_host stamp included.

    isValidAddressString() arrived at the right answer either way -- an IPv6
    string that returns 0 from the AF_INET call is accepted there, where the
    strict test accepts it from the AF_INET6 call instead -- and changes with
    it for the contract rather than the behavior.

    The comparison arrived with 775e87a614 (2026-03-21) in
    getHostNameByAddr(); isValidAddressString() predates it. The test harness
    keeps the const on the result it prints.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Mon Jul 27 02:09:08 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/7eb6f7302b37d5b88285e5c1
    Modified Files:
    src/xpdev/netwrap.c
    Log Message:
    xpdev: detect the IPv6 name servers configured on Windows

    getNameServerList() read FIXED_INFO.DnsServerList from GetNetworkParams(), which reports IPv4 name servers only -- its address strings are char[16].
    A host whose resolvers are all IPv6 therefore looked like a host with no resolvers at all, leaving system.name_servers empty and breaking dns.js,
    and with it ircd.js, which won't start without a name server.

    Enumerate with GetAdaptersAddresses(AF_UNSPEC) instead, walking each up, non-loopback adapter's FirstDnsServerAddress. The same server is commonly listed on more than one adapter, so duplicates are dropped. Windows
    assigns fec0:0:0:ffff::1/2/3 to any interface that has no IPv6 name server
    of its own and they never answer, so they are skipped rather than handed
    to a caller as dead sockets. The sizing call is retried, since the adapter
    set can grow between it and the call that fills the buffer.

    getnameinfo() formats the addresses, so WinSock must be initialized; GetNetworkParams() required nothing of the sort, and without it every
    address is dropped and the function returns an empty list rather than an
    error. getHostNameByAddr() and isValidAddressString() already bracket
    their calls the same way.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net