Choosing a TLS server identity by client address with NWListener

I run an HTTPS server on NWListener (iOS and macOS) that serves several identities from one listener on port 443, picked per handshake in sec_protocol_options_set_challenge_block, as suggested in this thread. That works well for every handshake that carries a server name.

The trouble is handshakes without one. Clients on the LAN connect by IP address, so they send no SNI (RFC 6066 keeps IP literals out of it), and they trust a self-signed certificate through a configuration profile. Internet clients and scanners that reach the public address through the router's port forward also often arrive without SNI. The two groups should get different certificates, and the only thing that tells them apart is the client's address. The listener knows it in newConnectionHandler, but the challenge block never sees it.

What I tried:

  • sec_protocol_metadata_t has accessors for the server name, ALPN, version, cipher suite and so on, but I can't find one for the connection's endpoints.
  • Setting a challenge block on the accepted connection's own TLS options before start():
listener.newConnectionHandler = { connection in
    let remote = connection.endpoint
    if let tls = connection.parameters.defaultProtocolStack.applicationProtocols
        .compactMap({ $0 as? NWProtocolTLS.Options }).first {
        sec_protocol_options_set_challenge_block(tls.securityProtocolOptions, { _, complete in
            complete(identity(for: remote))
        }, queue)
    }
    connection.start(queue: queue)
}

This block never runs. The listener's own block answers every handshake (tested on macOS 27.2).

My questions:

  1. Is there a supported way to choose the server identity per connection based on its endpoints, short of terminating TLS myself?
  2. Is the challenge block supported under TLS 1.3 by now? I also see it run twice for every handshake; is that expected?
  3. When a server-side handshake fails, connection.metadata(definition: NWProtocolTLS.definition) returns nil. Is there any way to learn which server name a failed handshake asked for, so it can be logged?

I filed FB25541009 with a small sample project that shows all three.