Dov
Dov

Reputation: 16156

CFSocket created in Swift not listening

I'm trying to get basic Bonjour discovery up and running using the sample code from a 2012 WWDC session, but having converted it to Swift. It's partially working. I am able to register a port, and register my service on that port. The client is able to discover that service, and resolve it.

Here's the issue: I call CFSocketCreateWithNative() and specify the callback listener, but that callback never gets called. Further, I tried connecting wiht telnet (telnet localhost 12345) and I get:

Trying ::1...

telnet: connect to address ::1: Connection refused

Trying 127.0.0.1...

telnet: connect to address 127.0.0.1: Connection refused

Trying fe80::1...

telnet: connect to address fe80::1: Connection refused

telnet: Unable to connect to remote host

This is an abbreviated version of how I'm registering the sockets, with the full Swift file in a Gist:

private func registerIPv4Socket() throws -> (Int32, in_port_t) {
    let fd4 = socket(AF_INET, SOCK_STREAM, 0)

    var sin = sockaddr_in()
    sin.sin_family = sa_family_t(AF_INET)
    sin.sin_len = UInt8(sizeofValue(sin))
    sin.sin_port = 0

    withUnsafePointer(&sin) {
        Foundation.bind(fd4, UnsafePointer($0), UInt32(sin.sin_len))
    }

    var addrLen = socklen_t(sizeofValue(sin))
    withUnsafeMutablePointers(&sin, &addrLen) { (sinPtr, addrPtr) -> Int32 in
        getsockname(fd4, UnsafeMutablePointer(sinPtr), UnsafeMutablePointer(addrPtr))
    }

    let listenError = listen(fd4, 5)        
    return (fd4, sin.sin_port)
}

private func registerIPv6Socket(port: in_port_t) throws -> Int32 {
    let fd6 = socket(AF_INET6, SOCK_STREAM, 0)

    var one: Int32 = 1
    withUnsafePointer(&one) {
        setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, UnsafePointer($0), socklen_t(sizeofValue(one)))
    }

    var sin6 = sockaddr_in6()
    sin6.sin6_family = sa_family_t(AF_INET6)
    sin6.sin6_len = UInt8(sizeofValue(sin6))
    sin6.sin6_port = port

    withUnsafePointer(&sin6) {
        Foundation.bind(fd6, UnsafePointer($0), UInt32(sin6.sin6_len))
    }

    var addrLen = socklen_t(sizeofValue(sin6))
    withUnsafeMutablePointers(&sin6, &addrLen) { (sinPtr, addrPtr) -> Int32 in
        getsockname(fd6, UnsafeMutablePointer(sinPtr), UnsafeMutablePointer(addrPtr))
    }

    listen(fd6, 5)
    return fd6
}

Why isn't my app listening on the port it's reporting it should be?

Upvotes: 0

Views: 1703

Answers (1)

user3441734
user3441734

Reputation: 17534

Your IPv4 socket is listening on port sin.sin_port.bigEndian, but your IPv6 socket is listening on the little endian port. Update your IPv6 code to use the big endian port:

sin.sin6_port = port.bigEndian

Upvotes: 1

Related Questions