Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Feb 2001 22:13:11 +0100
From:      Jesper Skriver <jesper@FreeBSD.org>
To:        net@FreeBSD.org
Subject:   optimize src/sys/netinet/in_pcb.c:in_pcblookup()
Message-ID:  <20010225221311.B76033@skriver.dk>

next in thread | raw e-mail | index | archive | help
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 majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010225221311.B76033>