src/sys/netinet/in_pcb.c:in_pcblookup() currently do a linear search of
all sessions, below is a diff that use in_pcblookup_hash instead, this
should minimize the impact of a ICMP flood.

please review.

/Jesper

Index: in_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.78
diff -u -r1.78 in_pcb.c
--- in_pcb.c    2001/02/22 21:23:45     1.78
+++ in_pcb.c    2001/02/25 20:32:00
@@ -680,7 +680,7 @@
        u_int32_t tcp_sequence;
        int tcp_seq_check;
 {
-       register struct inpcb *inp, *oinp;
+       register struct inpcb *inp;
        struct in_addr faddr;
        u_short fport = fport_arg, lport = lport_arg;
        int errno, s;
@@ -693,36 +693,28 @@
 
        errno = inetctlerrmap[cmd];
        s = splnet();
-       for (inp = LIST_FIRST(head); inp != NULL;) {
+       inp = in_pcblookup_hash(head->lh_first->inp_pcbinfo, faddr, fport,
+               laddr, lport, 0, NULL);
+       if (inp == NULL || inp->inp_socket == NULL)
+               goto out;
 #ifdef INET6
-               if ((inp->inp_vflag & INP_IPV4) == 0) {
-                       inp = LIST_NEXT(inp, inp_list);
-                       continue;
-               }
+       if ((inp->inp_vflag & INP_IPV4) == 0)
+               goto out;
 #endif
-               if (inp->inp_faddr.s_addr != faddr.s_addr ||
-                   inp->inp_socket == 0 || inp->inp_lport != lport ||
-                   inp->inp_laddr.s_addr != laddr.s_addr ||
-                   inp->inp_fport != fport) {
-                               inp = LIST_NEXT(inp, inp_list);
-                               continue;
-               }
-               /*
-                * If tcp_seq_check is set, then skip sessions where
-                * the sequence number is not one of a unacknowledged
-                * packet.
-                *
-                * If it doesn't match, we break the loop, as only a
-                * single session can match on src/dst ip addresses 
-                * and TCP port numbers.
-                */
-               if ((tcp_seq_check == 1) && (tcp_seq_vs_sess(inp, tcp_sequence) == 0))
-                       break;
-               oinp = inp;
-               inp = LIST_NEXT(inp, inp_list);
-               if (notify)
-                       (*notify)(oinp, errno);
-       }
+       /*
+        * If tcp_seq_check is set, then skip sessions where
+        * the sequence number is not one of a unacknowledged
+        * packet.
+        *
+        * If it doesn't match, we break the loop, as only a
+        * single session can match on src/dst ip addresses 
+        * and TCP port numbers.
+        */
+       if ((tcp_seq_check == 1) && (tcp_seq_vs_sess(inp, tcp_sequence) == 0))
+               goto out;
+       if (notify)
+               (*notify)(inp, errno);
+out:
        splx(s);
 }
 

/Jesper

-- 
Jesper Skriver, jesper(at)skriver(dot)dk  -  CCIE #5456
Work:    Network manager   @ AS3292 (Tele Danmark DataNetworks)
Private: FreeBSD committer @ 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.

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-net" in the body of the message

Reply via email to