Failing immediately on ICMP Unreachable responses

This is where we can discuss what we would like to see added or changed in OpenVPN.
Post Reply
petiepooo
OpenVPN User
Posts: 11
Joined: Tue Oct 26, 2010 10:08 am

Failing immediately on ICMP Unreachable responses

Post by petiepooo » Fri Jun 23, 2017 6:37 pm

It would be very handy for a connection to fail immediately if an ICMP Destination Unreachable (icmptype 3) response was received. Such a response indicates a hard error where resending is not expected to result in a different outcome (as opposed to a soft error such as no response which could just be a dropped packet)

Where I would like to use this is in the ability to use multiple remote directives where their visibility depends on the host's current network. Eg. I currently have two remotes in my client config; one with an IETF1918 internal IP, and the other with an external public IP. When I'm in my network, the internal IP is visible and it connects right away. When I'm connected to the internet, I've verified that attempts to connect to the internal IP are greeted with the ICMP port unreachable response (RFC 792, type 3, subtype 3). Yet the client keeps trying until it reaches the ping-restart timeout before it switches to the second remote IP.

A large VPN provider could use this with all public IPs to help segregate clients on connect by their source IP range. Eg. server1 accepts only 0..63 8-bit subnets. server2 accepts comcast-specific IP blocks. server3 accepts 64-127. No client-specific ranges or geo-loc tricks with DNS are needed.

The pertinent portion of v2.4's man page under the remote directive makes the current failure condition clear:
The client will move on to the next host in the list, in the event of connection failure. Note that at any given time, the OpenVPN client will at most be connected to one server.

Note that since UDP is connectionless, connection failure is defined by the --ping and --ping-restart options.
My research indicates that there may be issues with receiving async responses such as ICMP on an unconnected UDP socket. I don't know the sockets interfaces and how they work enough to know if this is a simple fix or just plain impossible. A good test environment would mean routing the test connections via a host that can inject these ICMP responses at will, such as via iptables.

An even more useful solution would be to try all remote IPs at once and connect only to the first one to respond, but that's an old wish that didn't even rate a response.. viewtopic.php?f=10&t=16790

A possible alternate solution would be to apply the --connect-timeout setting to UDP connections too. Perhaps start a timer on initial connection, and when it expires, if it's still in the initial state, fail it. Maybe I can try to put a pull request together for that..

petiepooo
OpenVPN User
Posts: 11
Joined: Tue Oct 26, 2010 10:08 am

Re: Failing immediately on ICMP Unreachable responses

Post by petiepooo » Wed Jul 05, 2017 5:25 pm

Ok, so I see the alternate solution already exists as --server-poll-timeout. Setting that to a sufficiently low value allows me to specify multiple remotes, the first of which will only be accessible from a specific network, and stick with a single config with only a small connection delay.

Setting it low enough (like 1-2 seconds) allows the client to cycle through the remotes fast enough that advancing on ICMP or TCP-RST doesn't save much time, especially considering that there's no guarantee you'll even get an ICMP or RST, so you'd still want a fast poll.

I should really read the man page cover to cover before posting.. :) This program has so many features that there's very little that hasn't been thought through. Thanks again to all authors and contributors!

Post Reply