Oops,

my mail client insist on breaking lines. Sorry for that - this mail attaches 
the patch in it's original form.

// Sven-Ola

Am Freitag, 1. Oktober 2010, um 10:51:32 schrieb Sven-Ola Tuecke:
> Signed-off-by: Sven-Ola Tuecke <sven-ola()gmx.de>

diff --git a/multi.c b/multi.c
index 5d15ea9..ab40e6c 100644
--- a/multi.c
+++ b/multi.c
@@ -974,6 +974,7 @@ multi_learn_addr (struct multi_context *m,
 static struct multi_instance *
 multi_get_instance_by_virtual_addr (struct multi_context *m,
 				    const struct mroute_addr *addr,
+				    bool dynamic_iroute,
 				    bool cidr_routing)
 {
   struct multi_route *route;
@@ -1020,6 +1021,24 @@ multi_get_instance_by_virtual_addr (struct multi_context *m,
 	      break;
 	    }
 	}
+      if (!ret && dynamic_iroute)
+	{
+	  const struct iroute *ir;
+
+	  /* does address match a dynamic_iroute? */
+	  for (ir = m->top.options.dynamic_iroutes; ir != NULL; ir = ir->next)
+	    {
+	      in_addr_t cmp_addr = ntohl(*(in_addr_t*)addr->addr);
+	      ASSERT ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4);
+	      cmp_addr &= netbits_to_netmask (ir->netbits);
+	      if (cmp_addr == ir->network)
+		{
+		  multi_learn_addr (m, m->pending, addr, MULTI_ROUTE_CACHE|MULTI_ROUTE_AGEABLE);
+		  ret = m->pending;
+		  break;
+		}
+	    }
+	}

       mroute_helper_unlock (rh);
     }
@@ -2100,7 +2119,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
 		  c->c2.to_tun.len = 0;
 		}
 	      /* make sure that source address is associated with this client */
-	      else if (multi_get_instance_by_virtual_addr (m, &src, true) != m->pending)
+	      else if (multi_get_instance_by_virtual_addr (m, &src, true, true) != m->pending)
 		{
 		  msg (D_MULTI_DROPPED, "MULTI: bad source address from client [%s], packet dropped",
 		       mroute_addr_print (&src, &gc));
@@ -2118,7 +2137,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
 		  else /* possible client to client routing */
 		    {
 		      ASSERT (!(mroute_flags & MROUTE_EXTRACT_BCAST));
-		      mi = multi_get_instance_by_virtual_addr (m, &dest, true);
+		      mi = multi_get_instance_by_virtual_addr (m, &dest, false, true);

 		      /* if dest addr is a known client, route to it */
 		      if (mi)
@@ -2179,7 +2198,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
 			    }
 			  else /* try client-to-client routing */
 			    {
-			      mi = multi_get_instance_by_virtual_addr (m, &dest, false);
+			      mi = multi_get_instance_by_virtual_addr (m, &dest, false, false);

 			      /* if dest addr is a known client, route to it */
 			      if (mi)
@@ -2302,7 +2321,7 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag
 	    }
 	  else
 	    {
-	      multi_set_pending (m, multi_get_instance_by_virtual_addr (m, &dest, dev_type == DEV_TYPE_TUN));
+	      multi_set_pending (m, multi_get_instance_by_virtual_addr (m, &dest, false, dev_type == DEV_TYPE_TUN));

 	      if (m->pending)
 		{
diff --git a/options.c b/options.c
index 4aec5cb..5c5c4be 100644
--- a/options.c
+++ b/options.c
@@ -417,6 +417,9 @@ static const char usage_message[] =
   "--iroute-ipv6 network/bits : Route IPv6 subnet to client.\n"
   "                  Sets up internal routes only.\n"
   "                  Only valid in a client-specific config file.\n"
+  "--dynamic-iroute network [netmask] : Define subnet for iroute autocreation.\n"
+  "                  Defines a range of IPs to be accepted behind clients.\n"
+  "                  Only useful with a learn-address script.\n"
   "--disable       : Client is disabled.\n"
   "                  Only valid in a client-specific config file.\n"
   "--client-cert-not-required : Don't require client certificate, client\n"
@@ -1150,6 +1153,7 @@ static void
 option_iroute (struct options *o,
 	       const char *network_str,
 	       const char *netmask_str,
+	       bool dynamic_iroute,
 	       int msglevel)
 {
   struct iroute *ir;
@@ -1163,15 +1167,24 @@ option_iroute (struct options *o,
       const in_addr_t netmask = getaddr (GETADDR_HOST_ORDER, netmask_str, 0, NULL, NULL);
       if (!netmask_to_netbits (ir->network, netmask, &ir->netbits))
 	{
-	  msg (msglevel, "in --iroute %s %s : Bad network/subnet specification",
+	  msg (msglevel, "in --%siroute %s %s : Bad network/subnet specification",
+	       dynamic_iroute ? "auto" : "",
 	       network_str,
 	       netmask_str);
 	  return;
 	}
     }

-  ir->next = o->iroutes;
-  o->iroutes = ir;
+  if (dynamic_iroute)
+    {
+      ir->next = o->dynamic_iroutes;
+      o->dynamic_iroutes = ir;
+    }
+  else
+    {
+      ir->next = o->iroutes;
+      o->iroutes = ir;
+    }
 }

 static void
@@ -5377,7 +5390,18 @@ add_option (struct options *options,
 	{
 	  netmask = p[2];
 	}
-      option_iroute (options, p[1], netmask, msglevel);
+      option_iroute (options, p[1], netmask, false, msglevel);
+    }
+  else if (streq (p[0], "dynamic-iroute") && p[1])
+    {
+      const char *netmask = NULL;
+
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      if (p[2])
+	{
+	  netmask = p[2];
+	}
+      option_iroute (options, p[1], netmask, true, msglevel);
     }
   else if (streq (p[0], "iroute-ipv6") && p[1])
     {
diff --git a/options.h b/options.h
index 1ef96ca..70cac55 100644
--- a/options.h
+++ b/options.h
@@ -410,6 +410,7 @@ struct options
   int n_bcast_buf;
   int tcp_queue_limit;
   struct iroute *iroutes;
+  struct iroute *dynamic_iroutes;
   struct iroute_ipv6 *iroutes_ipv6;			/* IPv6 */
   bool push_ifconfig_defined;
   in_addr_t push_ifconfig_local;

Reply via email to