Module Name:    src
Committed By:   rmind
Date:           Fri Jul  9 18:42:46 UTC 2010

Modified Files:
        src/sys/netinet: ip_input.c

Log Message:
ip_input: move lookup for fragment queue a little bit further.  OK m...@.


To generate a diff of this commit:
cvs rdiff -u -r1.286 -r1.287 src/sys/netinet/ip_input.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/ip_input.c
diff -u src/sys/netinet/ip_input.c:1.286 src/sys/netinet/ip_input.c:1.287
--- src/sys/netinet/ip_input.c:1.286	Thu Apr  1 01:23:32 2010
+++ src/sys/netinet/ip_input.c	Fri Jul  9 18:42:46 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_input.c,v 1.286 2010/04/01 01:23:32 tls Exp $	*/
+/*	$NetBSD: ip_input.c,v 1.287 2010/07/09 18:42:46 rmind Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.286 2010/04/01 01:23:32 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.287 2010/07/09 18:42:46 rmind Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -930,7 +930,7 @@
 	 * but it's not worth the time; just let them time out.)
 	 */
 	if (ip->ip_off & ~htons(IP_DF|IP_RF)) {
-		uint16_t off;
+		u_int off;
 		/*
 		 * Prevent TCP blind data attacks by not allowing non-initial
 		 * fragments to start at less than 68 bytes (minimal fragment
@@ -942,31 +942,6 @@
 			IP_STATINC(IP_STAT_BADFRAGS);
 			goto bad;
 		}
-		/*
-		 * Look for queue of fragments
-		 * of this datagram.
-		 */
-		IPQ_LOCK();
-		hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
-		LIST_FOREACH(fp, &ipq[hash], ipq_q) {
-			if (ip->ip_id == fp->ipq_id &&
-			    in_hosteq(ip->ip_src, fp->ipq_src) &&
-			    in_hosteq(ip->ip_dst, fp->ipq_dst) &&
-			    ip->ip_p == fp->ipq_p) {
-				/*
-				 * Make sure the TOS is matches previous
-				 * fragments.
-				 */
-				if (ip->ip_tos != fp->ipq_tos) {
-					IP_STATINC(IP_STAT_BADFRAGS);
-					IPQ_UNLOCK();
-					goto bad;
-				}
-				goto found;
-			}
-		}
-		fp = 0;
-found:
 
 		/*
 		 * Adjust ip_len to not reflect header,
@@ -976,20 +951,44 @@
 		ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
 		mff = (ip->ip_off & htons(IP_MF)) != 0;
 		if (mff) {
-		        /*
-		         * Make sure that fragments have a data length
+			/*
+			 * Make sure that fragments have a data length
 			 * that's a non-zero multiple of 8 bytes.
-		         */
+			 */
 			if (ntohs(ip->ip_len) == 0 ||
 			    (ntohs(ip->ip_len) & 0x7) != 0) {
 				IP_STATINC(IP_STAT_BADFRAGS);
-				IPQ_UNLOCK();
 				goto bad;
 			}
 		}
 		ip->ip_off = htons((ntohs(ip->ip_off) & IP_OFFMASK) << 3);
 
 		/*
+		 * Look for queue of fragments of this datagram.
+		 */
+		IPQ_LOCK();
+		hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
+		LIST_FOREACH(fp, &ipq[hash], ipq_q) {
+			if (ip->ip_id != fp->ipq_id)
+				continue;
+			if (!in_hosteq(ip->ip_src, fp->ipq_src))
+				continue;
+			if (!in_hosteq(ip->ip_dst, fp->ipq_dst))
+				continue;
+			if (ip->ip_p != fp->ipq_p)
+				continue;
+			/*
+			 * Make sure the TOS is matches previous fragments.
+			 */
+			if (ip->ip_tos != fp->ipq_tos) {
+				IP_STATINC(IP_STAT_BADFRAGS);
+				IPQ_UNLOCK();
+				goto bad;
+			}
+			break;
+		}
+
+		/*
 		 * If datagram marked as having more fragments
 		 * or if this is not the first fragment,
 		 * attempt reassembly; if it succeeds, proceed.
@@ -1008,7 +1007,7 @@
 			ipqe->ipqe_m = m;
 			ipqe->ipqe_ip = ip;
 			m = ip_reass(ipqe, fp, &ipq[hash]);
-			if (m == 0) {
+			if (m == NULL) {
 				IPQ_UNLOCK();
 				return;
 			}
@@ -1016,9 +1015,9 @@
 			ip = mtod(m, struct ip *);
 			hlen = ip->ip_hl << 2;
 			ip->ip_len = htons(ntohs(ip->ip_len) + hlen);
-		} else
-			if (fp)
-				ip_freef(fp);
+		} else if (fp) {
+			ip_freef(fp);
+		}
 		IPQ_UNLOCK();
 	}
 

Reply via email to