Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet ip_input: move lookup for fragment queue a littl...



details:   https://anonhg.NetBSD.org/src/rev/1afe07962cde
branches:  trunk
changeset: 756261:1afe07962cde
user:      rmind <rmind%NetBSD.org@localhost>
date:      Fri Jul 09 18:42:46 2010 +0000

description:
ip_input: move lookup for fragment queue a little bit further.  OK matt@.

diffstat:

 sys/netinet/ip_input.c |  71 ++++++++++++++++++++++++-------------------------
 1 files changed, 35 insertions(+), 36 deletions(-)

diffs (128 lines):

diff -r a4f96dfca41a -r 1afe07962cde sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c    Fri Jul 09 18:16:31 2010 +0000
+++ b/sys/netinet/ip_input.c    Fri Jul 09 18:42:46 2010 +0000
@@ -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,18 +951,42 @@
                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);
+                               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;
                }
-               ip->ip_off = htons((ntohs(ip->ip_off) & IP_OFFMASK) << 3);
 
                /*
                 * If datagram marked as having more fragments
@@ -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();
        }
 



Home | Main Index | Thread Index | Old Index