diff options
author | phk <phk@FreeBSD.org> | 2000-12-16 19:42:06 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2000-12-16 19:42:06 +0000 |
commit | 7c7359c504e271891625f81ed6c0fa9e7f8e2f7b (patch) | |
tree | 335a89b20197e63564e09fa2c29b77118ea8679d /sys/netinet/ip_icmp.c | |
parent | 10d3e9963aa4451ef5328ff50b0e57d9fe52d71b (diff) | |
download | FreeBSD-src-7c7359c504e271891625f81ed6c0fa9e7f8e2f7b.zip FreeBSD-src-7c7359c504e271891625f81ed6c0fa9e7f8e2f7b.tar.gz |
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
requi re 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.
PR: 23086
Submitted by: Jesper Skriver <jesper@skriver.dk>
Diffstat (limited to 'sys/netinet/ip_icmp.c')
-rw-r--r-- | sys/netinet/ip_icmp.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 5a44807..11cb500 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -328,6 +328,11 @@ icmp_input(m, off, proto) case ICMP_UNREACH_NET_UNKNOWN: case ICMP_UNREACH_NET_PROHIB: + if (icp->icmp_ip.ip_p == IPPROTO_TCP) { + code = PRC_UNREACH_PORT; + break; + } + case ICMP_UNREACH_TOSNET: code = PRC_UNREACH_NET; break; @@ -335,11 +340,21 @@ icmp_input(m, off, proto) case ICMP_UNREACH_HOST_UNKNOWN: case ICMP_UNREACH_ISOLATED: case ICMP_UNREACH_HOST_PROHIB: + if (icp->icmp_ip.ip_p == IPPROTO_TCP) { + code = PRC_UNREACH_PORT; + break; + } + case ICMP_UNREACH_TOSHOST: code = PRC_UNREACH_HOST; break; case ICMP_UNREACH_FILTER_PROHIB: + if (icp->icmp_ip.ip_p == IPPROTO_TCP) { + code = PRC_UNREACH_PORT; + break; + } + case ICMP_UNREACH_HOST_PRECEDENCE: case ICMP_UNREACH_PRECEDENCE_CUTOFF: code = PRC_UNREACH_PORT; |