mscdex / node-imap

An IMAP client module for node.js.
MIT License
2.14k stars 379 forks source link

Connection problems when using node-imap against a dual-stack server from a single-stack client. #918

Open Rudd-O opened 1 month ago

Rudd-O commented 1 month ago

As seen in https://github.com/node-red/node-red-nodes/issues/1065 , attempting to connect to a server that has IPv4 and IPv6 addresses from a client that has an IPv6 stack but doesn't have a globally-scoped IPv6 address causes issues:

May 08 00:26:34 assistant Node-RED[3831665]: Error checking: AggregateError
May 08 00:26:34 assistant Node-RED[3831665]: Stack: AggregateError
May 08 00:26:34 assistant Node-RED[3831665]:     at internalConnectMultiple (node:net:1114:18)
May 08 00:26:34 assistant Node-RED[3831665]:     at internalConnectMultiple (node:net:1177:5)
May 08 00:26:34 assistant Node-RED[3831665]:     at Timeout.internalConnectMultipleTimeout (node:net:1687:3)
May 08 00:26:34 assistant Node-RED[3831665]:     at listOnTimeout (node:internal/timers:575:11)
May 08 00:26:34 assistant Node-RED[3831665]:     at process.processTimers (node:internal/timers:514:7)
May 08 00:26:34 assistant Node-RED[3831665]: Errors: Error: connect ETIMEDOUT <IPv4>:993,Error: connect ENETUNREACH <IPv6>:993 - Local (:::0)

(The library's IMAP object is being instantiated here.)

Something in the library appears to try to connect in parallel to both IPv6 and IPv4 addresses (using the healthy 15 second timeout given to it by the caller), and yet immediately the library calls its on.error handler with an aggregate error, signaling a timeout for the server's IPv4 address and a (100% reasonable) ENETUNREACH for the server's IPv6 address.

Please either fix handling of IPv6 (a good fix would be to ensure if either of the two connection modes works, ignore the other error) or provide an option to force only IPv4 or IPv6.

Rudd-O commented 1 month ago

More complete stack trace (yet seems useless to me):

May 08 00:37:34 assistant Node-RED[3833087]: Error0: Error: connect ETIMEDOUT <IPv4>:993
May 08 00:37:34 assistant Node-RED[3833087]: Error0 stack: Error: connect ETIMEDOUT <IPv4>:993
May 08 00:37:34 assistant Node-RED[3833087]:     at createConnectionError (node:net:1634:14)
May 08 00:37:34 assistant Node-RED[3833087]:     at Timeout.internalConnectMultipleTimeout (node:net:1685:38)
May 08 00:37:34 assistant Node-RED[3833087]:     at listOnTimeout (node:internal/timers:575:11)
May 08 00:37:34 assistant Node-RED[3833087]:     at process.processTimers (node:internal/timers:514:7)
May 08 00:37:34 assistant Node-RED[3833087]: Error1: Error: connect ENETUNREACH <IPv6>:993 - Local (:::0)
May 08 00:37:34 assistant Node-RED[3833087]: Error1 stack: Error: connect ENETUNREACH <IPv6>:993 - Local (:::0)
May 08 00:37:34 assistant Node-RED[3833087]:     at internalConnectMultiple (node:net:1176:40)
May 08 00:37:34 assistant Node-RED[3833087]:     at Timeout.internalConnectMultipleTimeout (node:net:1687:3)
May 08 00:37:34 assistant Node-RED[3833087]:     at listOnTimeout (node:internal/timers:575:11)
May 08 00:37:34 assistant Node-RED[3833087]:     at process.processTimers (node:internal/timers:514:7)
Rudd-O commented 1 month ago

Commenters on this issue suggest to use Node version 20: https://github.com/nodejs/node/issues/40702#issuecomment-1900158494

Problem is, I am using Node version 20.

Rudd-O commented 1 month ago

I can confirm that disabling IPv6 completely via sysctl net.ipv6.conf.all.disable_ipv6 resolves the problem.