Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet Add inet4 part of the rfc6056 code contributed b...



details:   https://anonhg.NetBSD.org/src/rev/b1916524837e
branches:  trunk
changeset: 769823:b1916524837e
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Sep 24 17:18:17 2011 +0000

description:
Add inet4 part of the rfc6056 code contributed by Vlad Balan as part of
Google SoC-2011

diffstat:

 sys/netinet/files.netinet |    3 +-
 sys/netinet/in_pcb.c      |   64 +-
 sys/netinet/in_pcb.h      |    4 +-
 sys/netinet/in_pcb_hdr.h  |    3 +-
 sys/netinet/rfc6056.c     |  952 ++++++++++++++++++++++++++++++++++++++++++++++
 sys/netinet/rfc6056.h     |   54 ++
 sys/netinet/udp.h         |    5 +-
 sys/netinet/udp_usrreq.c  |   36 +-
 sys/netinet/udp_var.h     |    6 +-
 9 files changed, 1077 insertions(+), 50 deletions(-)

diffs (truncated from 1323 to 300 lines):

diff -r cdbdc13c58ec -r b1916524837e sys/netinet/files.netinet
--- a/sys/netinet/files.netinet Sat Sep 24 17:09:29 2011 +0000
+++ b/sys/netinet/files.netinet Sat Sep 24 17:18:17 2011 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.netinet,v 1.22 2011/05/03 18:28:45 dyoung Exp $
+#      $NetBSD: files.netinet,v 1.23 2011/09/24 17:18:17 christos Exp $
 
 defflag opt_tcp_debug.h                TCP_DEBUG
 defparam opt_tcp_debug.h       TCP_NDEBUG
@@ -43,3 +43,4 @@
 file   netinet/tcp_vtw.c       inet | inet6
 
 file   netinet/udp_usrreq.c    inet | inet6
+file   netinet/rfc6056.c       inet | inet6
diff -r cdbdc13c58ec -r b1916524837e sys/netinet/in_pcb.c
--- a/sys/netinet/in_pcb.c      Sat Sep 24 17:09:29 2011 +0000
+++ b/sys/netinet/in_pcb.c      Sat Sep 24 17:18:17 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_pcb.c,v 1.138 2011/05/03 18:28:45 dyoung Exp $      */
+/*     $NetBSD: in_pcb.c,v 1.139 2011/09/24 17:18:17 christos Exp $    */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -93,7 +93,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.138 2011/05/03 18:28:45 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.139 2011/09/24 17:18:17 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -124,6 +124,7 @@
 #include <netinet/in_pcb.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_var.h>
+#include <netinet/rfc6056.h>
 
 #ifdef INET6
 #include <netinet/ip6.h>
@@ -202,11 +203,13 @@
        splx(s);
        if (inp == NULL)
                return (ENOBUFS);
-       memset((void *)inp, 0, sizeof(*inp));
+       memset(inp, 0, sizeof(*inp));
        inp->inp_af = AF_INET;
        inp->inp_table = table;
        inp->inp_socket = so;
        inp->inp_errormtu = -1;
+       inp->inp_rfc6056algo = RFC6056_ALGO_DEFAULT;
+       inp->inp_bindportonsend = false;
 #if defined(IPSEC) || defined(FAST_IPSEC)
        error = ipsec_init_pcbpolicy(so, &inp->inp_sp);
        if (error != 0) {
@@ -232,8 +235,6 @@
 {
        struct inpcbtable *table = inp->inp_table;
        struct socket *so = inp->inp_socket;
-       int        cnt;
-       u_int16_t  mymin, mymax;
        u_int16_t *lastport;
        u_int16_t lport = 0;
        enum kauth_network_req req;
@@ -246,14 +247,10 @@
                req = KAUTH_REQ_NETWORK_BIND_PORT;
 #endif
 
-               mymin = lowportmin;
-               mymax = lowportmax;
                lastport = &table->inpt_lastlow;
        } else {
                req = KAUTH_REQ_NETWORK_BIND_PORT;
 
-               mymin = anonportmin;
-               mymax = anonportmax;
                lastport = &table->inpt_lastport;
        }
 
@@ -263,38 +260,13 @@
        if (error)
                return (EACCES);
 
-       if (mymin > mymax) {    /* sanity check */
-               u_int16_t swp;
-
-               swp = mymin;
-               mymin = mymax;
-               mymax = swp;
-       }
-
-       lport = *lastport - 1;
-       for (cnt = mymax - mymin + 1; cnt; cnt--, lport--) {
-               vestigial_inpcb_t vestigial;
+       /*
+        * Use RFC6056 randomized port selection
+        */
+       error = rfc6056_randport(&lport, &inp->inp_head, cred);
+       if (error)
+               return error;
 
-               if (lport < mymin || lport > mymax)
-                       lport = mymax;
-               if (!in_pcblookup_port(table, sin->sin_addr, htons(lport), 1,
-                                      &vestigial) && !vestigial.valid) {
-                       /* We have a free port, check with the secmodel(s). */
-                       sin->sin_port = lport;
-                       error = kauth_authorize_network(cred,
-                           KAUTH_NETWORK_BIND, req, so, sin, NULL);
-                       if (error) {
-                               /* Secmodel says no. Keep looking. */
-                               continue;
-                       }
-
-                       goto found;
-               }
-       }
-
-       return (EAGAIN);
-
- found:
        inp->inp_flags |= INP_ANONPORT;
        *lastport = lport;
        lport = htons(lport);
@@ -569,6 +541,18 @@
        }
        inp->inp_faddr = sin->sin_addr;
        inp->inp_fport = sin->sin_port;
+
+        /* Late bind, if needed */
+       if (inp->inp_bindportonsend) {
+               struct sockaddr_in lsin = *((const struct sockaddr_in *)
+                   inp->inp_socket->so_proto->pr_domain->dom_sa_any);
+               lsin.sin_addr = inp->inp_laddr;
+               lsin.sin_port = 0;
+
+               if ((error = in_pcbbind_port(inp, &lsin, l->l_cred)) != 0)
+                       return error;
+       }
+
        in_pcbstate(inp, INP_CONNECTED);
 #if defined(IPSEC) || defined(FAST_IPSEC)
        if (inp->inp_socket->so_type == SOCK_STREAM)
diff -r cdbdc13c58ec -r b1916524837e sys/netinet/in_pcb.h
--- a/sys/netinet/in_pcb.h      Sat Sep 24 17:09:29 2011 +0000
+++ b/sys/netinet/in_pcb.h      Sat Sep 24 17:18:17 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_pcb.h,v 1.48 2011/05/03 18:28:45 dyoung Exp $       */
+/*     $NetBSD: in_pcb.h,v 1.49 2011/09/24 17:18:17 christos Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -80,6 +80,7 @@
 #define inp_af         inp_head.inph_af
 #define inp_ppcb       inp_head.inph_ppcb
 #define inp_state      inp_head.inph_state
+#define inp_rfc6056algo inp_head.inph_rfc6056algo
 #define inp_socket     inp_head.inph_socket
 #define inp_table      inp_head.inph_table
 #define inp_sp         inp_head.inph_sp
@@ -92,6 +93,7 @@
        struct    ip_moptions *inp_moptions; /* IP multicast options */
        int       inp_errormtu;         /* MTU of last xmit status = EMSGSIZE */
        uint8_t   inp_ip_minttl;
+       bool      inp_bindportonsend;
 };
 
 #define        inp_faddr       inp_ip.ip_dst
diff -r cdbdc13c58ec -r b1916524837e sys/netinet/in_pcb_hdr.h
--- a/sys/netinet/in_pcb_hdr.h  Sat Sep 24 17:09:29 2011 +0000
+++ b/sys/netinet/in_pcb_hdr.h  Sat Sep 24 17:18:17 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_pcb_hdr.h,v 1.6 2011/05/03 18:28:45 dyoung Exp $    */
+/*     $NetBSD: in_pcb_hdr.h,v 1.7 2011/09/24 17:18:17 christos Exp $  */
 
 /*
  * Copyright (C) 2003 WIDE Project.
@@ -77,6 +77,7 @@
        int       inph_af;              /* address family - AF_INET */
        void *    inph_ppcb;            /* pointer to per-protocol pcb */
        int       inph_state;           /* bind/connect state */
+       int       inph_rfc6056algo;
        struct    socket *inph_socket;  /* back pointer to socket */
        struct    inpcbtable *inph_table;
 #if 1 /* IPSEC */
diff -r cdbdc13c58ec -r b1916524837e sys/netinet/rfc6056.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/netinet/rfc6056.c     Sat Sep 24 17:18:17 2011 +0000
@@ -0,0 +1,952 @@
+/*     $NetBSD: rfc6056.c,v 1.1 2011/09/24 17:18:17 christos Exp $     */
+
+/*
+ * Copyright 2011 Vlad Balan
+ *
+ * Written by Vlad Balan for the NetBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: rfc6056.c,v 1.1 2011/09/24 17:18:17 christos Exp $");
+
+#include "opt_inet.h"
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/kauth.h>
+#include <sys/uidinfo.h>
+#include <sys/domain.h>
+#include <sys/md5.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_var.h>
+#include <netinet/ip_var.h>
+
+#ifdef INET6
+#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+#include <netinet6/in6_pcb.h>
+#endif
+
+#include <netinet/tcp_vtw.h>
+
+#include "rfc6056.h"
+
+#define NPROTO 2
+#define RFC6056_TCP 0
+#define RFC6056_UDP 1
+
+#define NAF 2
+#define RFC6056_IPV4 0
+#define RFC6056_IPV6 1
+
+#define NRANGES 2
+#define RFC6056_LOWPORT 0
+#define RFC6056_HIGHPORT 1
+
+#define RFC6056_DEBUG 1
+
+#if RFC6056_DEBUG
+static bool rfc6056_debug = true;
+#define DPRINTF if (rfc6056_debug) printf
+#else
+#define DPRINTF while (/*CONSTCOND*/0) printf
+#endif
+
+#ifdef INET
+static int inet4_rfc6056algo = RFC6056_ALGO_BSD;
+#endif
+#ifdef INET6
+static int inet6_rfc6056algo = RFC6056_ALGO_BSD;
+#endif
+
+typedef struct {
+       const char *name;
+       int (*func)(int, uint16_t *, struct inpcb_hdr *, kauth_cred_t);
+} rfc6056_algorithm_t;
+
+static int algo_bsd(int, uint16_t *, struct inpcb_hdr *, kauth_cred_t);
+static int algo_random_start(int, uint16_t *, struct inpcb_hdr *, kauth_cred_t);
+static int algo_random_pick(int, uint16_t *, struct inpcb_hdr *, kauth_cred_t);
+static int algo_hash(int, uint16_t *, struct inpcb_hdr *, kauth_cred_t);
+static int algo_doublehash(int, uint16_t *, struct inpcb_hdr *, kauth_cred_t);
+static int algo_randinc(int, uint16_t *, struct inpcb_hdr *, kauth_cred_t);
+
+static const rfc6056_algorithm_t algos[] = {
+       {
+               .name = "bsd",
+               .func = algo_bsd
+       },
+       {
+               .name = "random_start",
+               .func = algo_random_start
+       },



Home | Main Index | Thread Index | Old Index