Bug 23086

Summary: implement rfc1122 3.2.2.1, react to ICMP administratively prohibited
Product: Base System Reporter: jesper <jesper>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: jesper
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description jesper 2000-11-24 22:30:01 UTC
	We currently does not react to ICMP administratively prohibited messages
send by routers when they deny our traffic, this causes a timeout when trying to
connect to TCP ports/services on a remote host, which is blocked by routers or
firewalls.

	rfc1122 (Requirements for Internet Hosts) section 3.2.2.1 actually require
that we treat such a message for a TCP session, that we treat it like if we had
recieved a RST.

quote begin.

            A Destination Unreachable message that is received MUST be
            reported to the transport layer.  The transport layer SHOULD
            use the information appropriately; for example, see Sections
            4.1.3.3, 4.2.3.9, and 4.2.4 below.  A transport protocol
            that has its own mechanism for notifying the sender that a
            port is unreachable (e.g., TCP, which sends RST segments)
            MUST nevertheless accept an ICMP Port Unreachable for the
            same purpose.

quote end.

I've written a small extension that implement this, it also create a sysctl
"net.inet.tcp.icmp_admin_prohib_like_rst" to control if this new behaviour
is activated.

When it's activated (set to 1) we'll treat a ICMP administratively prohibited 
message (icmp type 3 code 9, 10 and 13) for a TCP sessions, as if we recived 
a TCP RST, but only if the TCP session is in SYN_SENT state.

The reason for only reacting when in SYN_SENT state, is that this will solve
the problem, and at the same time minimize the risk of this being abused.

I suggest that we enable this new behaviour by default, but it would be a 
change of current behaviour, so if people prefer to leave it disabled by 
default, at least for now, this would be ok for me, the attached diff 
actually have the sysctl set to 0 by default.

Fix: Apply the below diff
How-To-Repeat: 
	Try to telnet to any host where this is blocked by a router/firewall
that sends ICMP administratively prohibited messages, and do this with this 
sysctl set to 0 and to 1, like below:

tam# sysctl -w net.inet.tcp.icmp_admin_prohib_like_rst=0
net.inet.tcp.icmp_admin_prohib_like_rst: 1 -> 0
tam# time telnet 193.89.247.125 25
Trying 193.89.247.125...
telnet: connect to address 193.89.247.125: Connection refused
telnet: Unable to connect to remote host
0.012u 0.000s 0:45.06 0.0%      88+164k 0+0io 0pf+0w
tam# sysctl -w net.inet.tcp.icmp_admin_prohib_like_rst=1
net.inet.tcp.icmp_admin_prohib_like_rst: 0 -> 1
tam# time telnet 193.89.247.125 25
Trying 193.89.247.125...
telnet: connect to address 193.89.247.125: Connection refused
telnet: Unable to connect to remote host
0.012u 0.000s 0:00.06 16.6%     88+152k 0+0io 0pf+0w

This saved 45 seconds ...
Comment 1 Poul-Henning Kamp freebsd_committer freebsd_triage 2000-12-16 19:47:34 UTC
State Changed
From-To: open->closed

Committed, thanks!