git: 3a96a25da861 - stable/13 - libalias: Switch to SPLAY trees

Lutz Donnerhacke donner at FreeBSD.org
Tue Jul 6 06:56:39 UTC 2021


The branch stable/13 has been updated by donner:

URL: https://cgit.FreeBSD.org/src/commit/?id=3a96a25da8614d27f717ba8d29d32bafb04a70e8

commit 3a96a25da8614d27f717ba8d29d32bafb04a70e8
Author:     Lutz Donnerhacke <donner at FreeBSD.org>
AuthorDate: 2021-05-27 21:42:54 +0000
Commit:     Lutz Donnerhacke <donner at FreeBSD.org>
CommitDate: 2021-07-06 06:55:53 +0000

    libalias: Switch to SPLAY trees
    
    Current data structure is using a hash of unordered lists.  Those
    unordered lists are quite efficient, because the least recently
    inserted entries are most likely to be used again.  In order to avoid
    long search times in other cases, the lists are hashed into many
    buckets.  Unfortunatly a search for a miss needs an exhaustive
    inspection and a careful definition of the hash.
    
    Splay trees offer a similar feature - almost O(1) for access of the
    least recently used entries), and amortized O(ln(n) - for almost all
    other cases.  Get rid of the hash.
    
    Now the data structure should able to quickly react to external
    packets without eating CPU cycles for breakfast, preventing a DoS.
    
    PR:             192888
    Discussed with: Dimitry Luhtionov
    Differential Revision: https://reviews.freebsd.org/D30516
    Differential Revision: https://reviews.freebsd.org/D30536
    Differential Revision: https://reviews.freebsd.org/D30844
    
    (cherry picked from commit 935fc93af157dee352eb4b6c83f8a2a9e7fd9a4e)
    (cherry picked from commit d261e57deacb0d00d9e827447f235df83dda3e3a)
    (cherry picked from commit f70c98a2f5d993dc518efd606aa341eda99400ef)
    (cherry picked from commit 25392fac9488bcae5c451500df2e2945430484a6)
    (cherry picked from commit 2f4d91f9cb22fc65eb65407e8118b433a5d71976)
    (cherry picked from commit 4060e77f49d1b9fd2254f3f4da94fd64fce83f72)
---
 sys/netinet/libalias/HISTORY       |   3 +-
 sys/netinet/libalias/alias_db.c    | 502 +++----------------------------------
 sys/netinet/libalias/alias_db.h    | 443 ++++++++++++++++++++++++++++++++
 sys/netinet/libalias/alias_local.h |  10 +-
 4 files changed, 489 insertions(+), 469 deletions(-)

diff --git a/sys/netinet/libalias/HISTORY b/sys/netinet/libalias/HISTORY
index 8965290a4f27..87d5b6f8ed76 100644
--- a/sys/netinet/libalias/HISTORY
+++ b/sys/netinet/libalias/HISTORY
@@ -146,4 +146,5 @@ Version 3.2: July, 2000 (Erik Salander, erik at whistle.com and
 
 Version 3.3: May 2021 (donner)
     - Dropped LibAliasCheckNewLink
-    - Refactor the database handling, perfomance improvements.
+    - Refactor the database handling
+    - Switch to more effienct SPLAY trees
diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index b056f55b56a5..783a8ca3baa8 100644
--- a/sys/netinet/libalias/alias_db.c
+++ b/sys/netinet/libalias/alias_db.c
@@ -29,120 +29,6 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/*
-    Alias_db.c encapsulates all data structures used for storing
-    packet aliasing data.  Other parts of the aliasing software
-    access data through functions provided in this file.
-
-    Data storage is based on the notion of a "link", which is
-    established for ICMP echo/reply packets, UDP datagrams and
-    TCP stream connections.  A link stores the original source
-    and destination addresses.  For UDP and TCP, it also stores
-    source and destination port numbers, as well as an alias
-    port number.  Links are also used to store information about
-    fragments.
-
-    There is a facility for sweeping through and deleting old
-    links as new packets are sent through.  A simple timeout is
-    used for ICMP and UDP links.  TCP links are left alone unless
-    there is an incomplete connection, in which case the link
-    can be deleted after a certain amount of time.
-
-    Initial version: August, 1996  (cjm)
-
-    Version 1.4: September 16, 1996 (cjm)
-	Facility for handling incoming links added.
-
-    Version 1.6: September 18, 1996 (cjm)
-	ICMP data handling simplified.
-
-    Version 1.7: January 9, 1997 (cjm)
-	Fragment handling simplified.
-	Saves pointers for unresolved fragments.
-	Permits links for unspecified remote ports
-	  or unspecified remote addresses.
-	Fixed bug which did not properly zero port
-	  table entries after a link was deleted.
-	Cleaned up some obsolete comments.
-
-    Version 1.8: January 14, 1997 (cjm)
-	Fixed data type error in StartPoint().
-	(This error did not exist prior to v1.7
-	and was discovered and fixed by Ari Suutari)
-
-    Version 1.9: February 1, 1997
-	Optionally, connections initiated from packet aliasing host
-	machine will will not have their port number aliased unless it
-	conflicts with an aliasing port already being used. (cjm)
-
-	All options earlier being #ifdef'ed are now available through
-	a new interface, SetPacketAliasMode().  This allows run time
-	control (which is now available in PPP+pktAlias through the
-	'alias' keyword). (ee)
-
-	Added ability to create an alias port without
-	either destination address or port specified.
-	port type = ALIAS_PORT_UNKNOWN_DEST_ALL (ee)
-
-	Removed K&R style function headers
-	and general cleanup. (ee)
-
-	Added packetAliasMode to replace compiler #defines's (ee)
-
-	Allocates sockets for partially specified
-	ports if ALIAS_USE_SOCKETS defined. (cjm)
-
-    Version 2.0: March, 1997
-	SetAliasAddress() will now clean up alias links
-	if the aliasing address is changed. (cjm)
-
-	PacketAliasPermanentLink() function added to support permanent
-	links.  (J. Fortes suggested the need for this.)
-	Examples:
-
-	(192.168.0.1, port 23)  <-> alias port 6002, unknown dest addr/port
-
-	(192.168.0.2, port 21)  <-> alias port 3604, known dest addr
-						     unknown dest port
-
-	These permanent links allow for incoming connections to
-	machines on the local network.  They can be given with a
-	user-chosen amount of specificity, with increasing specificity
-	meaning more security. (cjm)
-
-	Quite a bit of rework to the basic engine.  The portTable[]
-	array, which kept track of which ports were in use was replaced
-	by a table/linked list structure. (cjm)
-
-	SetExpire() function added. (cjm)
-
-	DeleteLink() no longer frees memory association with a pointer
-	to a fragment (this bug was first recognized by E. Eklund in
-	v1.9).
-
-    Version 2.1: May, 1997 (cjm)
-	Packet aliasing engine reworked so that it can handle
-	multiple external addresses rather than just a single
-	host address.
-
-	PacketAliasRedirectPort() and PacketAliasRedirectAddr()
-	added to the API.  The first function is a more generalized
-	version of PacketAliasPermanentLink().  The second function
-	implements static network address translation.
-
-    Version 3.2: July, 2000 (salander and satoh)
-	Added FindNewPortGroup to get contiguous range of port values.
-
-	Added QueryUdpTcpIn and QueryUdpTcpOut to look for an aliasing
-	link but not actually add one.
-
-	Added FindRtspOut, which is closely derived from FindUdpTcpOut,
-	except that the alias port (from FindNewPortGroup) is provided
-	as input.
-
-    See HISTORY file for additional revisions.
-*/
-
 #ifdef _KERNEL
 #include <machine/stdarg.h>
 #include <sys/param.h>
@@ -175,177 +61,11 @@ __FBSDID("$FreeBSD$");
 #include "alias_mod.h"
 #endif
 
+#include "alias_db.h"
+
 static LIST_HEAD(, libalias) instancehead = LIST_HEAD_INITIALIZER(instancehead);
 int LibAliasTime;
 
-/*
-   Constants (note: constants are also defined
-	      near relevant functions or structs)
-*/
-
-/* Timeouts (in seconds) for different link types */
-#define ICMP_EXPIRE_TIME             60
-#define UDP_EXPIRE_TIME              60
-#define PROTO_EXPIRE_TIME            60
-#define FRAGMENT_ID_EXPIRE_TIME      10
-#define FRAGMENT_PTR_EXPIRE_TIME     30
-
-/* TCP link expire time for different cases */
-/* When the link has been used and closed - minimal grace time to
-   allow ACKs and potential re-connect in FTP (XXX - is this allowed?)  */
-#ifndef TCP_EXPIRE_DEAD
-#define TCP_EXPIRE_DEAD           10
-#endif
-
-/* When the link has been used and closed on one side - the other side
-   is allowed to still send data */
-#ifndef TCP_EXPIRE_SINGLEDEAD
-#define TCP_EXPIRE_SINGLEDEAD     90
-#endif
-
-/* When the link isn't yet up */
-#ifndef TCP_EXPIRE_INITIAL
-#define TCP_EXPIRE_INITIAL       300
-#endif
-
-/* When the link is up */
-#ifndef TCP_EXPIRE_CONNECTED
-#define TCP_EXPIRE_CONNECTED   86400
-#endif
-
-/* Dummy port number codes used for FindLinkIn/Out() and AddLink().
-   These constants can be anything except zero, which indicates an
-   unknown port number. */
-
-#define NO_DEST_PORT     1
-#define NO_SRC_PORT      1
-
-/* Matches any/unknown address in FindLinkIn/Out() and AddLink(). */
-static struct in_addr const ANY_ADDR = { INADDR_ANY };
-
-/* Data Structures
-
-    The fundamental data structure used in this program is
-    "struct alias_link".  Whenever a TCP connection is made,
-    a UDP datagram is sent out, or an ICMP echo request is made,
-    a link record is made (if it has not already been created).
-    The link record is identified by the source address/port
-    and the destination address/port. In the case of an ICMP
-    echo request, the source port is treated as being equivalent
-    with the 16-bit ID number of the ICMP packet.
-
-    The link record also can store some auxiliary data.  For
-    TCP connections that have had sequence and acknowledgment
-    modifications, data space is available to track these changes.
-    A state field is used to keep track in changes to the TCP
-    connection state.  ID numbers of fragments can also be
-    stored in the auxiliary space.  Pointers to unresolved
-    fragments can also be stored.
-
-    The link records support two independent chainings.  Lookup
-    tables for input and out tables hold the initial pointers
-    the link chains.  On input, the lookup table indexes on alias
-    port and link type.  On output, the lookup table indexes on
-    source address, destination address, source port, destination
-    port and link type.
-*/
-
-/* used to save changes to ACK/sequence numbers */
-struct ack_data_record {
-	u_long		ack_old;
-	u_long		ack_new;
-	int		delta;
-	int		active;
-};
-
-/* Information about TCP connection */
-struct tcp_state {
-	int		in;	/* State for outside -> inside */
-	int		out;	/* State for inside  -> outside */
-	int		index;	/* Index to ACK data array */
-	/* Indicates whether ACK and sequence numbers been modified */
-	int		ack_modified;
-};
-
-/* Number of distinct ACK number changes
- * saved for a modified TCP stream */
-#define N_LINK_TCP_DATA   3
-struct tcp_dat {
-	struct tcp_state state;
-	struct ack_data_record ack[N_LINK_TCP_DATA];
-	/* Which firewall record is used for this hole? */
-	int		fwhole;
-};
-
-/* LSNAT server pool (circular list) */
-struct server {
-	struct in_addr	addr;
-	u_short		port;
-	struct server  *next;
-};
-
-/* Main data structure */
-struct alias_link {
-	struct libalias *la;
-	/* Address and port information */
-	struct in_addr	src_addr;
-	struct in_addr	dst_addr;
-	struct in_addr	alias_addr;
-	struct in_addr	proxy_addr;
-	u_short		src_port;
-	u_short		dst_port;
-	u_short		alias_port;
-	u_short		proxy_port;
-	struct server  *server;
-	/* Type of link: TCP, UDP, ICMP, proto, frag */
-	int		link_type;
-/* values for link_type */
-#define LINK_ICMP                     IPPROTO_ICMP
-#define LINK_UDP                      IPPROTO_UDP
-#define LINK_TCP                      IPPROTO_TCP
-#define LINK_FRAGMENT_ID              (IPPROTO_MAX + 1)
-#define LINK_FRAGMENT_PTR             (IPPROTO_MAX + 2)
-#define LINK_ADDR                     (IPPROTO_MAX + 3)
-#define LINK_PPTP                     (IPPROTO_MAX + 4)
-
-	int		flags;	/* indicates special characteristics */
-	int		pflags;	/* protocol-specific flags */
-/* flag bits */
-#define LINK_UNKNOWN_DEST_PORT     0x01
-#define LINK_UNKNOWN_DEST_ADDR     0x02
-#define LINK_PERMANENT             0x04
-#define LINK_PARTIALLY_SPECIFIED   0x03	/* logical-or of first two bits */
-#define LINK_UNFIREWALLED          0x08
-
-	int		timestamp;	/* Time link was last accessed */
-#ifndef NO_USE_SOCKETS
-	int		sockfd;		/* socket descriptor */
-#endif
-	/* Linked list of pointers for input and output lookup tables  */
-	union {
-		struct {
-			LIST_ENTRY(alias_link) in;
-			LIST_ENTRY(alias_link) out;
-		} all;
-		struct {
-			LIST_ENTRY(alias_link) list;
-		} pptp;
-	};
-	struct {
-		TAILQ_ENTRY(alias_link) list;
-		int	time;	/* Expire time for link */
-	} expire;
-	/* Auxiliary data */
-	union {
-		char           *frag_ptr;
-		struct in_addr	frag_addr;
-		struct tcp_dat *tcp;
-	} data;
-};
-
-/* Clean up procedure. */
-static void finishoff(void);
-
 /* Kernel module definition. */
 #ifdef _KERNEL
 MALLOC_DEFINE(M_ALIAS, "libalias", "packet aliasing");
@@ -373,96 +93,32 @@ static moduledata_t alias_mod = {
 DECLARE_MODULE(alias, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
 #endif
 
-/* Internal utility routines (used only in alias_db.c)
-
-Lookup table starting points:
-    StartPointIn()           -- link table initial search point for
-				incoming packets
-    StartPointOut()          -- link table initial search point for
-				outgoing packets
-
-Miscellaneous:
-    SeqDiff()                -- difference between two TCP sequences
-    ShowAliasStats()         -- send alias statistics to a monitor file
-*/
-
-/* Local prototypes */
-static struct group_in *
-StartPointIn(struct libalias *, struct in_addr, u_short, int, int);
-static u_int
-StartPointOut(struct in_addr, struct in_addr, u_short, u_short, int);
-static int	SeqDiff(u_long, u_long);
-
-#ifndef NO_FW_PUNCH
-/* Firewall control */
-static void	InitPunchFW(struct libalias *);
-static void	UninitPunchFW(struct libalias *);
-static void	ClearFWHole(struct alias_link *);
-
-#endif
-
-/* Log file control */
-static void	ShowAliasStats(struct libalias *);
-static int	InitPacketAliasLog(struct libalias *);
-static void	UninitPacketAliasLog(struct libalias *);
-
-void		SctpShowAliasStats(struct libalias *la);
-
-#define INGUARD						\
-   if (grp->alias_port != alias_port ||			\
-       grp->link_type != link_type ||			\
-       grp->alias_addr.s_addr != alias_addr.s_addr)	\
-	continue;
+SPLAY_GENERATE(splay_out, alias_link, all.out, cmp_out);
+SPLAY_GENERATE(splay_in, group_in, in, cmp_in);
 
 static struct group_in *
 StartPointIn(struct libalias *la,
     struct in_addr alias_addr, u_short alias_port, int link_type,
     int create)
 {
-	u_int n;
-	struct group_in *grp, *tmp;
-
-	n = alias_addr.s_addr;
-	n += alias_port;
-	n += link_type;
-	n %= LINK_TABLE_IN_SIZE;
+	struct group_in *grp;
+	struct group_in needle = {
+		.alias_addr = alias_addr,
+		.alias_port = alias_port,
+		.link_type = link_type
+	};
 
-	LIST_FOREACH_SAFE(grp, &la->groupTableIn[n], group_in, tmp) {
-		/* Auto cleanup */
-		if (LIST_EMPTY(&grp->full) && LIST_EMPTY(&grp->partial)) {
-			LIST_REMOVE(grp, group_in);
-			free(grp);
-		} else {
-			INGUARD;
-			return (grp);
-		}
-	}
-	if (!create || (grp = malloc(sizeof(*grp))) == NULL)
+	grp = SPLAY_FIND(splay_in, &la->linkSplayIn, &needle);
+	if (grp != NULL || !create || (grp = malloc(sizeof(*grp))) == NULL)
 		return (grp);
 	grp->alias_addr = alias_addr;
 	grp->alias_port = alias_port;
 	grp->link_type = link_type;
 	LIST_INIT(&grp->full);
 	LIST_INIT(&grp->partial);
-	LIST_INSERT_HEAD(&la->groupTableIn[n], grp, group_in);
+	SPLAY_INSERT(splay_in, &la->linkSplayIn, grp);
 	return (grp);
 }
-#undef INGUARD
-
-static u_int
-StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
-    u_short src_port, u_short dst_port, int link_type)
-{
-	u_int n;
-
-	n = src_addr.s_addr;
-	n += dst_addr.s_addr;
-	n += src_port;
-	n += dst_port;
-	n += link_type;
-
-	return (n % LINK_TABLE_OUT_SIZE);
-}
 
 static int
 SeqDiff(u_long x, u_long y)
@@ -531,53 +187,6 @@ void SctpShowAliasStats(struct libalias *la)
 	ShowAliasStats(la);
 }
 
-/* Internal routines for finding, deleting and adding links
-
-Port Allocation:
-    GetNewPort()             -- find and reserve new alias port number
-    GetSocket()              -- try to allocate a socket for a given port
-
-Link creation and deletion:
-    CleanupAliasData()      - remove all link chains from lookup table
-    CleanupLink()           - look for a stale link
-    DeleteLink()            - remove link
-    AddLink()               - add link
-    ReLink()                - change link
-
-Link search:
-    FindLinkOut()           - find link for outgoing packets
-    FindLinkIn()            - find link for incoming packets
-
-Port search:
-    FindNewPortGroup()      - find an available group of ports
-*/
-
-/* Local prototypes */
-static int	GetNewPort(struct libalias *, struct alias_link *, int);
-#ifndef NO_USE_SOCKETS
-static u_short	GetSocket(struct libalias *, u_short, int *, int);
-#endif
-static void	CleanupAliasData(struct libalias *, int);
-static void	CleanupLink(struct libalias *, struct alias_link **, int);
-static void	DeleteLink(struct alias_link **, int);
-static struct alias_link *
-UseLink(struct libalias *, struct alias_link *);
-
-static struct alias_link *
-ReLink(struct alias_link *,
-    struct in_addr, struct in_addr, struct in_addr,
-    u_short, u_short, int, int, int);
-
-static struct alias_link *
-FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
-
-static struct alias_link *
-FindLinkIn(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
-
-static u_short _RandomPort(struct libalias *la);
-
-#define GET_NEW_PORT_MAX_ATTEMPTS       20
-
 /* get random port in network byte order */
 static u_short
 _RandomPort(struct libalias *la) {
@@ -814,25 +423,13 @@ static void
 CleanupAliasData(struct libalias *la, int deletePermanent)
 {
 	struct alias_link *lnk, *lnk_tmp;
-	u_int i;
 
 	LIBALIAS_LOCK_ASSERT(la);
 
 	/* permanent entries may stay */
 	TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, expire.list, lnk_tmp)
 		DeleteLink(&lnk, deletePermanent);
-
-	for (i = 0; i < LINK_TABLE_IN_SIZE; i++) {
-		struct group_in *grp, *grp_tmp;
-
-		LIST_FOREACH_SAFE(grp, &la->groupTableIn[i], group_in, grp_tmp)
-			if (LIST_EMPTY(&grp->full) && LIST_EMPTY(&grp->partial)) {
-				LIST_REMOVE(grp, group_in);
-				free(grp);
-			}
-	}
 }
-
 static void
 CleanupLink(struct libalias *la, struct alias_link **lnk, int deletePermanent)
 {
@@ -881,7 +478,9 @@ DeleteLink(struct alias_link **plnk, int deletePermanent)
 	case LINK_PPTP:
 		LIST_REMOVE(lnk, pptp.list);
 		break;
-	default:
+	default: {
+		struct group_in *grp;
+
 		/* Free memory allocated for LSNAT server pool */
 		if (lnk->server != NULL) {
 			struct server *head, *curr, *next;
@@ -893,11 +492,21 @@ DeleteLink(struct alias_link **plnk, int deletePermanent)
 			} while ((curr = next) != head);
 		} else {
 			/* Adjust output table pointers */
-			LIST_REMOVE(lnk, all.out);
+			SPLAY_REMOVE(splay_out, &la->linkSplayOut, lnk);
 		}
 
 		/* Adjust input table pointers */
 		LIST_REMOVE(lnk, all.in);
+
+		/* Remove intermediate node, if empty */
+		grp = StartPointIn(la, lnk->alias_addr, lnk->alias_port, lnk->link_type, 0);
+		if (grp != NULL &&
+		    LIST_EMPTY(&grp->full) &&
+		    LIST_EMPTY(&grp->partial)) {
+			SPLAY_REMOVE(splay_in, &la->linkSplayIn, grp);
+			free(grp);
+		}
+	}
 		break;
 	}
 
@@ -956,7 +565,6 @@ AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr,
     struct in_addr alias_addr, u_short src_port, u_short dst_port,
     int alias_port_param, int link_type)
 {
-	u_int start_point;
 	struct alias_link *lnk;
 
 	LIBALIAS_LOCK_ASSERT(la);
@@ -1083,9 +691,7 @@ AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr,
 		}
 
 		/* Set up pointers for output lookup table */
-		start_point = StartPointOut(src_addr, dst_addr,
-		    src_port, dst_port, link_type);
-		LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, all.out);
+		SPLAY_INSERT(splay_out, &la->linkSplayOut, lnk);
 
 		/* Set up pointers for input lookup table */
 		if (lnk->flags & LINK_PARTIALLY_SPECIFIED)
@@ -1138,35 +744,25 @@ ReLink(struct alias_link *old_lnk,
 	return (new_lnk);
 }
 
-
-#define OUTGUARD					\
-   if (lnk->src_port != src_port ||			\
-       lnk->src_addr.s_addr != src_addr.s_addr ||	\
-       lnk->dst_addr.s_addr != dst_addr.s_addr ||	\
-       lnk->dst_port != dst_port ||			\
-       lnk->link_type != link_type)			\
-	   continue;
-
 static struct alias_link *
 _SearchLinkOut(struct libalias *la, struct in_addr src_addr,
     struct in_addr dst_addr,
     u_short src_port,
     u_short dst_port,
     int link_type) {
-	u_int i;
 	struct alias_link *lnk;
+	struct alias_link needle = {
+		.src_addr = src_addr,
+		.dst_addr = dst_addr,
+		.src_port = src_port,
+		.dst_port = dst_port,
+		.link_type = link_type
+	};
 
-	i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
-	LIST_FOREACH(lnk, &la->linkTableOut[i], all.out) {
-		OUTGUARD;
-		return (UseLink(la, lnk));
-	}
-
-	return (NULL);
+	lnk = SPLAY_FIND(splay_out, &la->linkSplayOut, &needle);
+	return (UseLink(la, lnk));
 }
 
-#undef OUTGUARD
-
 static struct alias_link *
 _FindLinkOut(struct libalias *la, struct in_addr src_addr,
     struct in_addr dst_addr,
@@ -2331,7 +1927,7 @@ LibAliasAddServer(struct libalias *la, struct alias_link *lnk, struct in_addr ad
 		if (head == NULL) {
 			server->next = server;
 			/* not usable for outgoing connections */
-			LIST_REMOVE(lnk, all.out);
+			SPLAY_REMOVE(splay_out, &la->linkSplayOut, lnk);
 		} else {
 			struct server *s;
 
@@ -2481,8 +2077,6 @@ finishoff(void)
 struct libalias *
 LibAliasInit(struct libalias *la)
 {
-	int i;
-
 	if (la == NULL) {
 #ifdef _KERNEL
 #undef malloc	/* XXX: ugly */
@@ -2506,10 +2100,8 @@ LibAliasInit(struct libalias *la)
 		LibAliasTime = time(NULL);
 #endif
 
-		for (i = 0; i < LINK_TABLE_OUT_SIZE; i++)
-			LIST_INIT(&la->linkTableOut[i]);
-		for (i = 0; i < LINK_TABLE_IN_SIZE; i++)
-			LIST_INIT(&la->groupTableIn[i]);
+		SPLAY_INIT(&la->linkSplayIn);
+		SPLAY_INIT(&la->linkSplayOut);
 		LIST_INIT(&la->pptpList);
 		TAILQ_INIT(&la->checkExpire);
 #ifdef _KERNEL
@@ -2702,20 +2294,6 @@ fill_rule(void *buf, int bufsize, int rulenum,
 	return ((char *)cmd - (char *)buf);
 }
 
-static void ClearAllFWHoles(struct libalias *la);
-
-#define fw_setfield(la, field, num)			\
-do {						\
-    (field)[(num) - la->fireWallBaseNum] = 1;		\
-} /*lint -save -e717 */ while(0)/* lint -restore */
-
-#define fw_clrfield(la, field, num)			\
-do {							\
-    (field)[(num) - la->fireWallBaseNum] = 0;		\
-} /*lint -save -e717 */ while(0)/* lint -restore */
-
-#define fw_tstfield(la, field, num) ((field)[(num) - la->fireWallBaseNum])
-
 static void
 InitPunchFW(struct libalias *la)
 {
diff --git a/sys/netinet/libalias/alias_db.h b/sys/netinet/libalias/alias_db.h
new file mode 100644
index 000000000000..971ca305c1a6
--- /dev/null
+++ b/sys/netinet/libalias/alias_db.h
@@ -0,0 +1,443 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2001 Charles Mott <cm at linktel.net>
+ * All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/*
+    Alias_db.c encapsulates all data structures used for storing
+    packet aliasing data.  Other parts of the aliasing software
+    access data through functions provided in this file.
+
+    Data storage is based on the notion of a "link", which is
+    established for ICMP echo/reply packets, UDP datagrams and
+    TCP stream connections.  A link stores the original source
+    and destination addresses.  For UDP and TCP, it also stores
+    source and destination port numbers, as well as an alias
+    port number.  Links are also used to store information about
+    fragments.
+
+    There is a facility for sweeping through and deleting old
+    links as new packets are sent through.  A simple timeout is
+    used for ICMP and UDP links.  TCP links are left alone unless
+    there is an incomplete connection, in which case the link
+    can be deleted after a certain amount of time.
+
+    Initial version: August, 1996  (cjm)
+
+    Version 1.4: September 16, 1996 (cjm)
+	Facility for handling incoming links added.
+
+    Version 1.6: September 18, 1996 (cjm)
+	ICMP data handling simplified.
+
+    Version 1.7: January 9, 1997 (cjm)
+	Fragment handling simplified.
+	Saves pointers for unresolved fragments.
+	Permits links for unspecified remote ports
+	  or unspecified remote addresses.
+	Fixed bug which did not properly zero port
+	  table entries after a link was deleted.
+	Cleaned up some obsolete comments.
+
+    Version 1.8: January 14, 1997 (cjm)
+	Fixed data type error in StartPoint().
+	(This error did not exist prior to v1.7
+	and was discovered and fixed by Ari Suutari)
+
+    Version 1.9: February 1, 1997
+	Optionally, connections initiated from packet aliasing host
+	machine will will not have their port number aliased unless it
+	conflicts with an aliasing port already being used. (cjm)
+
+	All options earlier being #ifdef'ed are now available through
+	a new interface, SetPacketAliasMode().  This allows run time
+	control (which is now available in PPP+pktAlias through the
+	'alias' keyword). (ee)
+
+	Added ability to create an alias port without
+	either destination address or port specified.
+	port type = ALIAS_PORT_UNKNOWN_DEST_ALL (ee)
+
+	Removed K&R style function headers
+	and general cleanup. (ee)
+
+	Added packetAliasMode to replace compiler #defines's (ee)
+
+	Allocates sockets for partially specified
+	ports if ALIAS_USE_SOCKETS defined. (cjm)
+
+    Version 2.0: March, 1997
+	SetAliasAddress() will now clean up alias links
+	if the aliasing address is changed. (cjm)
+
+	PacketAliasPermanentLink() function added to support permanent
+	links.  (J. Fortes suggested the need for this.)
+	Examples:
+
+	(192.168.0.1, port 23)  <-> alias port 6002, unknown dest addr/port
+
+	(192.168.0.2, port 21)  <-> alias port 3604, known dest addr
+						     unknown dest port
+
+	These permanent links allow for incoming connections to
+	machines on the local network.  They can be given with a
+	user-chosen amount of specificity, with increasing specificity
+	meaning more security. (cjm)
+
+	Quite a bit of rework to the basic engine.  The portTable[]
+	array, which kept track of which ports were in use was replaced
+	by a table/linked list structure. (cjm)
+
+	SetExpire() function added. (cjm)
+
+	DeleteLink() no longer frees memory association with a pointer
+	to a fragment (this bug was first recognized by E. Eklund in
+	v1.9).
+
+    Version 2.1: May, 1997 (cjm)
+	Packet aliasing engine reworked so that it can handle
+	multiple external addresses rather than just a single
+	host address.
+
+	PacketAliasRedirectPort() and PacketAliasRedirectAddr()
+	added to the API.  The first function is a more generalized
+	version of PacketAliasPermanentLink().  The second function
+	implements static network address translation.
+
+    Version 3.2: July, 2000 (salander and satoh)
+	Added FindNewPortGroup to get contiguous range of port values.
+
+	Added QueryUdpTcpIn and QueryUdpTcpOut to look for an aliasing
+	link but not actually add one.
+
+	Added FindRtspOut, which is closely derived from FindUdpTcpOut,
+	except that the alias port (from FindNewPortGroup) is provided
+	as input.
+
+    See HISTORY file for additional revisions.
+*/
+
+#ifndef _ALIAS_DB_H_
+#define _ALIAS_DB_H_
+
+
+/*
+   Constants (note: constants are also defined
+	      near relevant functions or structs)
+*/
+
+/* Timeouts (in seconds) for different link types */
+#define ICMP_EXPIRE_TIME             60
+#define UDP_EXPIRE_TIME              60
+#define PROTO_EXPIRE_TIME            60
+#define FRAGMENT_ID_EXPIRE_TIME      10
+#define FRAGMENT_PTR_EXPIRE_TIME     30
+
+/* TCP link expire time for different cases */
+/* When the link has been used and closed - minimal grace time to
+   allow ACKs and potential re-connect in FTP (XXX - is this allowed?)  */
+#ifndef TCP_EXPIRE_DEAD
+#define TCP_EXPIRE_DEAD           10
+#endif
+
+/* When the link has been used and closed on one side - the other side
+   is allowed to still send data */
+#ifndef TCP_EXPIRE_SINGLEDEAD
+#define TCP_EXPIRE_SINGLEDEAD     90
+#endif
+
+/* When the link isn't yet up */
+#ifndef TCP_EXPIRE_INITIAL
+#define TCP_EXPIRE_INITIAL       300
+#endif
+
+/* When the link is up */
+#ifndef TCP_EXPIRE_CONNECTED
+#define TCP_EXPIRE_CONNECTED   86400
+#endif
+
+/* Dummy port number codes used for FindLinkIn/Out() and AddLink().
+   These constants can be anything except zero, which indicates an
+   unknown port number. */
+
+#define NO_DEST_PORT     1
+#define NO_SRC_PORT      1
+
+/* Matches any/unknown address in FindLinkIn/Out() and AddLink(). */
+static struct in_addr const ANY_ADDR = { INADDR_ANY };
+
+/* Data Structures
+
+    The fundamental data structure used in this program is
+    "struct alias_link".  Whenever a TCP connection is made,
+    a UDP datagram is sent out, or an ICMP echo request is made,
+    a link record is made (if it has not already been created).
+    The link record is identified by the source address/port
+    and the destination address/port. In the case of an ICMP
+    echo request, the source port is treated as being equivalent
+    with the 16-bit ID number of the ICMP packet.
+
+    The link record also can store some auxiliary data.  For
+    TCP connections that have had sequence and acknowledgment
+    modifications, data space is available to track these changes.
+    A state field is used to keep track in changes to the TCP
+    connection state.  ID numbers of fragments can also be
+    stored in the auxiliary space.  Pointers to unresolved
+    fragments can also be stored.
+
+    The link records support two independent chainings.  Lookup
+    tables for input and out tables hold the initial pointers
+    the link chains.  On input, the lookup table indexes on alias
+    port and link type.  On output, the lookup table indexes on
+    source address, destination address, source port, destination
+    port and link type.
+*/
+
+/* used to save changes to ACK/sequence numbers */
+struct ack_data_record {
+	u_long		ack_old;
+	u_long		ack_new;
+	int		delta;
+	int		active;
+};
+
+/* Information about TCP connection */
+struct tcp_state {
+	int		in;	/* State for outside -> inside */
+	int		out;	/* State for inside  -> outside */
+	int		index;	/* Index to ACK data array */
+	/* Indicates whether ACK and sequence numbers been modified */
+	int		ack_modified;
+};
+
+/* Number of distinct ACK number changes
+ * saved for a modified TCP stream */
+#define N_LINK_TCP_DATA   3
+struct tcp_dat {
+	struct tcp_state state;
+	struct ack_data_record ack[N_LINK_TCP_DATA];
+	/* Which firewall record is used for this hole? */
+	int		fwhole;
+};
+
+/* LSNAT server pool (circular list) */
+struct server {
+	struct in_addr	addr;
+	u_short		port;
+	struct server  *next;
+};
+
+/* Main data structure */
+struct alias_link {
+	struct libalias *la;
+	/* Address and port information */
+	struct in_addr	src_addr;
+	struct in_addr	dst_addr;
+	struct in_addr	alias_addr;
+	struct in_addr	proxy_addr;
+	u_short		src_port;
+	u_short		dst_port;
+	u_short		alias_port;
+	u_short		proxy_port;
+	struct server  *server;
+	/* Type of link: TCP, UDP, ICMP, proto, frag */
+	int		link_type;
+/* values for link_type */
+#define LINK_ICMP                     IPPROTO_ICMP
+#define LINK_UDP                      IPPROTO_UDP
+#define LINK_TCP                      IPPROTO_TCP
+#define LINK_FRAGMENT_ID              (IPPROTO_MAX + 1)
+#define LINK_FRAGMENT_PTR             (IPPROTO_MAX + 2)
+#define LINK_ADDR                     (IPPROTO_MAX + 3)
+#define LINK_PPTP                     (IPPROTO_MAX + 4)
+
+	int		flags;	/* indicates special characteristics */
+	int		pflags;	/* protocol-specific flags */
+/* flag bits */
+#define LINK_UNKNOWN_DEST_PORT     0x01
+#define LINK_UNKNOWN_DEST_ADDR     0x02
+#define LINK_PERMANENT             0x04
*** 203 LINES SKIPPED ***


More information about the dev-commits-src-all mailing list