Search code examples
swiftmacossocketsunixposix

Listening socket max connections hit early, while having increased the limit


I have a simple listening socket, that stops accepting socket, returing EN_FILE after only 13 connections. I have tried using sysctl in the following manner:

$ sysctl kern.maxfiles
kern.maxfiles: 12288
$ sysctl kern.maxfilesperproc
kern.maxfilesperproc: 10240
$ sudo sysctl -w kern.maxfiles=1048600
kern.maxfiles: 12288 -> 1048600
$ sudo sysctl -w kern.maxfilesperproc=1048576
kern.maxfilesperproc: 10240 -> 1048576
$ ulimit -S -n
256
$ ulimit -S -n 1048576
$ ulimit -S -n
1048576

But this doesn't seem to solve the issue, is a reboot required specifically on OSX? I need it for a singular test so I wasn't planning on making it permanent in /etc/sysctl.conf

Socket creation:

 #if os(Linux)
            fileDescriptor = Glibc.socket(AF_INET, Int32(SOCK_STREAM.rawValue), 0)
        #else
            fileDescriptor = Darwin.socket(AF_INET, SOCK_STREAM, 0)
        #endif

And the accepting part:

let result = withUnsafePointer(to: &address) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { sockAddress in
                // Do nothing
                bind(fileDescriptor, sockAddress, UInt32(MemoryLayout<sockaddr_in>.size))
            }
        }

'

let clientFD = accept(fileDescriptor, nil, nil)
        if( clientFD == EMFILE || clientFD == ENFILE ) {
            print("[\(type(of: self))] WARNING: Maximum number of open connections has been reached")
            close(clientFD)
            return nil
        }

Notes

libtls ( LibreSSL 2.5.5 ) is used after accept().

EN_FILE is the value returned, where I'd personally expect EM_FILE


Solution

  • You're comparing the accepted file descriptor against error codes. That doesn't make sense. Since file descriptors and error codes are both typically small integers, of course you're going to get a "match" eventually.

    You want to compare clientFD to -1 and then check errno against EMFILE or ENFILE.