daniel-2k / ioBroker.nanoleaf-lightpanels

ioBroker Adapter for nanoleaf Light Panels / Canvas
MIT License
11 stars 4 forks source link

possible snat port exhaustion #133

Open FernetMenta opened 5 months ago

FernetMenta commented 5 months ago

I have 2 instances for nanoleafs shapes. On both I observe many connection issues, see log image

My iobroker runs in a container, means I can't use SSDP.

Maybe adding a keepAlive agent for the http get method can resolve this issue. https://nodejs.org/api/http.html#http_new_agent_options

daniel-2k commented 4 months ago

That will not solve the problem. You added a TCP keep alive for the event source, which is the SSE connection to the nanoleaf devices. That would only solve problems getting status updates from the nanoleaf device, if TCP connection is closed. But eventsource should handle TCP keep alive automatically, because this is essential for using SSE. But this is not the problem. SSE is used only for event status updates and SSDP for detecting if the nanoleaf device is still available. SSDP UDP packages are sent from nanoleaf device to a multicast address. Depending of the network configuration of your docker container, they also should reach the adapter in the container. Nevertheless you can turn off using SSDP for keep alive and use polling instead (see adapter settings -> additional settings). It looks like you already did it.

But when I look into the error messages, SSDP is not the problem, because the error message then should be : Connection to xxx:xxxx lost, Error: No ssdp:alive detected, ... But you get an ENOTFOUND. And the only case where this error, thrown by auroraAPI library, is the statusUpdate function where status updates are actively will be triggered by calling the getInfo endpoint. And this is used only when SSDP is disabled and polling is used OR SSE is disabled and polling for getting status update are uses (both uses the same polling mechnism). Then the request to "Shapes-A7DB:16021" failed because the host name is not found. Please ensure your container is able to resolve this name (you should use a FQDN). Further it would good to enable debug log and send me the log, after a start of the adapter to get more information. Normally with ENOTFOUND the initial connection to the nanoleaf device already should also not work.

FernetMenta commented 4 months ago

So why does it solve my problem?

You added a TCP keep alive

I don't think so. What it does is that it reuses the socket. TCP keep-alive is a different story: "Not to be confused with the keep-alive value of the Connection header" source: https://nodejs.org/api/http.html#class-httpagent

But when I look into the error messages, SSDP is not the problem

Certainly not, because I use polling (container do not support multicast)

I did enable debug logging but it did not log additional info. Every 60s there is this polling message in the log until it fails again.

Please ensure your container is able to resolve this name (you should use a FQDN).

Of course the container can resolve the host name otherwise it wouldn't be able to connect at all. The problem is that it fails after some hundred successfuls polls.

FernetMenta commented 4 months ago

I think the problem is similar to what is described in this article: https://azureossd.github.io/2022/09/30/Node-applications-on-App-Service-Linux-and-getaddrinfo-ENOTFOUND/

daniel-2k commented 4 months ago

I read the article about SNAT port exhaustion in Azure and now I understood the problem (because the ENOTFOUND didn't make sense with the keep alive without knowing the background). And I reviewed the pull request again and I overlooked, that the agent is passed to the http.request not to the eventsource for the SSE (I looked to fast over the pull request, sorry). Yes, I know that node per default does not reuse sockets, and that there is an option to enable that. Enabling keep alive enable socket reuse. I can add this into a new release. Shouldn't have any side effects for other scenarios. Interesting setup you have. You are running ioBroker in Azure Cloud in Kubernetes? And how do you connect to your local nanoleaf devices, which is in your local area network?

FernetMenta commented 4 months ago

I use the official iobroker docker container: https://github.com/buanet/ioBroker.docker running on a little arm v7 in my local network. I just found the Azure article while searching for the reason of the disconnects I couldn't explain.

btw: thank you very much for this adapter! I wouldn't have bought the nanoleafs without it.

daniel-2k commented 2 months ago

I added the pull request to the latest version 1.5.0. Please check out.

FernetMenta commented 2 months ago

Thanks, I have been running this change since I submitted the PR. Switched to 1.5.0 now.