On Sun, Nov 19, 2000 at 10:04:51PM +0100, Jesper Skriver wrote:
> On Sun, Nov 19, 2000 at 04:03:04PM -0500, Louis A. Mamakos wrote:
> > 
> > This patch seems like it will do the wrong thing for ICMP messages that
> > are associated with non-TCP packets.   It looks like ICMP unreachable
> > messages for UDP packets will never get delivered to UDP sockets.
> 
> Yep - I've come to think of this too, I think I'll make it behave like
> before for non-TCP packets, or do you have a better idea ?

New version attached, this time I check that it's a ICMP unreachable for
a TCP packet, if not this code behaves like the current code.

I still need some hints on the sysctl stuff.

/Jesper

-- 
Jesper Skriver, jesper(at)skriver(dot)dk  -  CCIE #5456
Work:    Network manager @ AS3292 (Tele Danmark DataNetworks)
Private: Geek            @ AS2109 (A much smaller network ;-)

One Unix to rule them all, One Resolver to find them,
One IP to bring them all and in the zone to bind them.
diff -u -r sys/netinet.old/ip_icmp.c sys/netinet/ip_icmp.c
--- sys/netinet.old/ip_icmp.c   Thu Nov  2 10:46:23 2000
+++ sys/netinet/ip_icmp.c       Sun Nov 19 22:08:52 2000
@@ -328,6 +328,11 @@
 
                        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 @@
                        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;
diff -u -r sys/netinet.old/tcp_subr.c sys/netinet/tcp_subr.c
--- sys/netinet.old/tcp_subr.c  Fri Oct 27 13:45:41 2000
+++ sys/netinet/tcp_subr.c      Sun Nov 19 21:17:40 2000
@@ -961,6 +961,8 @@
 
        if (cmd == PRC_QUENCH)
                notify = tcp_quench;
+       else if ((cmd == PRC_UNREACH_PORT) && (ip))
+               notify = tcp_drop_syn_sent;
        else if (cmd == PRC_MSGSIZE)
                notify = tcp_mtudisc;
        else if (!PRC_IS_REDIRECT(cmd) &&
@@ -1071,6 +1073,20 @@
 
        if (tp)
                tp->snd_cwnd = tp->t_maxseg;
+}
+
+/*
+ * When a ICMP unreachable is recieved, drop the
+ * TCP connection, but only if in SYN SENT
+ */
+void
+tcp_drop_syn_sent(inp, errno)
+       struct inpcb *inp;
+       int errno;
+{
+       struct tcpcb *tp = intotcpcb(inp);
+       if((tp) && (tp->t_state == TCPS_SYN_SENT))
+                       tcp_drop(tp, errno);
 }
 
 /*
diff -u -r sys/netinet.old/tcp_var.h sys/netinet/tcp_var.h
--- sys/netinet.old/tcp_var.h   Sat Jul 22 01:26:37 2000
+++ sys/netinet/tcp_var.h       Sun Nov 19 21:17:55 2000
@@ -387,6 +387,7 @@
 void    tcp_input __P((struct mbuf *, int, int));
 void    tcp_mss __P((struct tcpcb *, int));
 int     tcp_mssopt __P((struct tcpcb *));
+void    tcp_drop_syn_sent __P((struct inpcb *, int));
 void    tcp_mtudisc __P((struct inpcb *, int));
 struct tcpcb *
         tcp_newtcpcb __P((struct inpcb *));

Reply via email to