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(); }