Skip to content

All sockets get used when unable to reach host when using realtime updates #93

@jangellx

Description

@jangellx

I hit this recently when I changed my wifi network name, but didn't get around to updating the 15 or so HTTP devices I have to the new SSID yet. All these devices are set to do "realtime" updates with the default interval. homebridge is on a Mac running macOS 10.15.5.

Here's an example of a device definition, which uses static IPs:

		{
			"accessory": "Http",
			"switchHandling": "realtime",
			"name": "Heating Register 1",
			"model": "HeatReg01",
			"on_url": "http://192.168.1.220/on",
			"off_url": "http://192.168.1.220/off",
			"status_url": "http://192.168.1.220/status",
			"http_method": "GET",
			"service": "Switch"
		},

After about a day of not being able to connect to any of these devices, I found that nothing on my computer could make any HTTP connections anymore, including Safari, Chrome, Slack, App Store, etc. I finally ran netstat and found that a ridiculous number of connections were open, all targeting the IP addresses of these devices. Every one of them was in the FIN_WAIT_1 state, indicating that they were waiting for a "connection closed" response from the other side. But since they never connected in the first place, this attempt to gracefully close the socket would never get a reply. This meant it was just waiting for the 10 minute timeout before closing the connection.

The reason this is an issue is that "realtime" is checking for status updates frequently, like every 30 seconds or something. So these connections would fail, but the socket would stay open until the 10 minute FIN_WAIT_1 timeout was hit. However, it doesn't wait for the timeout before trying to connect again 30 seconds later. As such, it's allocating a socket every 30 seconds and only closing them every 10 minutes. This would eventually use all 16k available sockets for that port range across the system (apparently this happens around 24 hours for about 15 devices), and thus no more connections would be allowed by anyone at all.

Is it possible for the socket to be immediately hard closed in scenarios where the connection cannot be made to the target device? That would solve this problem nicely.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions