Load Sharing using IP Network Address Translation (RFC 2391, LSNAT).

LSNAT links are first created by either PacketAliasRedirectPort() or
PacketAliasRedirectAddress() and then set up by one or more calls to
PacketAliasAddServer().
This commit is contained in:
Ruslan Ermilov 2000-04-27 17:37:03 +00:00
parent b61bde0916
commit 6d20a77450
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=59702
6 changed files with 300 additions and 54 deletions

View File

@ -51,6 +51,11 @@ struct alias_link;
struct in_addr, u_short,
u_char);
extern int
PacketAliasAddServer(struct alias_link *link,
struct in_addr addr,
u_short port);
extern int
PacketAliasPptp(struct in_addr);

View File

@ -237,6 +237,13 @@ struct tcp_dat
int fwhole; /* Which firewall record is used for this hole? */
};
struct server /* LSNAT server pool (circular list) */
{
struct in_addr addr;
u_short port;
struct server *next;
};
struct alias_link /* Main data structure */
{
struct in_addr src_addr; /* Address and port information */
@ -247,6 +254,7 @@ struct alias_link /* Main data structure */
u_short dst_port;
u_short alias_port;
u_short proxy_port;
struct server *server;
int link_type; /* Type of link: TCP, UDP, ICMP, PPTP, frag */
@ -778,6 +786,17 @@ DeleteLink(struct alias_link *link)
ClearFWHole(link);
#endif
/* Free memory allocated for LSNAT server pool */
if (link->server != NULL) {
struct server *head, *curr, *next;
head = curr = link->server;
do {
next = curr->next;
free(curr);
} while ((curr = next) != head);
}
/* Adjust output table pointers */
link_last = link->last_out;
link_next = link->next_out;
@ -871,6 +890,7 @@ AddLink(struct in_addr src_addr,
link->src_port = src_port;
link->dst_port = dst_port;
link->proxy_port = 0;
link->server = NULL;
link->link_type = link_type;
link->sockfd = -1;
link->flags = 0;
@ -1044,6 +1064,7 @@ _FindLinkOut(struct in_addr src_addr,
while (link != NULL)
{
if (link->src_addr.s_addr == src_addr.s_addr
&& link->server == NULL
&& link->dst_addr.s_addr == dst_addr.s_addr
&& link->dst_port == dst_port
&& link->src_port == src_port
@ -1207,39 +1228,39 @@ _FindLinkIn(struct in_addr dst_addr,
if (link_fully_specified != NULL)
{
link_fully_specified->timestamp = timeStamp;
return link_fully_specified;
link = link_fully_specified;
}
else if (link_unknown_dst_port != NULL)
{
return replace_partial_links
? ReLink(link_unknown_dst_port,
link_unknown_dst_port->src_addr, dst_addr, alias_addr,
link_unknown_dst_port->src_port, dst_port, alias_port,
link_type)
: link_unknown_dst_port;
}
link = link_unknown_dst_port;
else if (link_unknown_dst_addr != NULL)
{
return replace_partial_links
? ReLink(link_unknown_dst_addr,
link_unknown_dst_addr->src_addr, dst_addr, alias_addr,
link_unknown_dst_addr->src_port, dst_port, alias_port,
link_type)
: link_unknown_dst_addr;
}
link = link_unknown_dst_addr;
else if (link_unknown_all != NULL)
{
return replace_partial_links
? ReLink(link_unknown_all,
link_unknown_all->src_addr, dst_addr, alias_addr,
link_unknown_all->src_port, dst_port, alias_port,
link_type)
: link_unknown_all;
}
link = link_unknown_all;
else
return (NULL);
if (replace_partial_links &&
(link->flags & LINK_PARTIALLY_SPECIFIED || link->server != NULL))
{
return(NULL);
struct in_addr src_addr;
u_short src_port;
if (link->server != NULL) { /* LSNAT link */
src_addr = link->server->addr;
src_port = link->server->port;
link->server = link->server->next;
} else {
src_addr = link->src_addr;
src_port = link->src_port;
}
link = ReLink(link,
src_addr, dst_addr, alias_addr,
src_port, dst_port, alias_port,
link_type);
}
return (link);
}
static struct alias_link *
@ -1527,7 +1548,13 @@ FindOriginalAddress(struct in_addr alias_addr)
}
else
{
if (link->src_addr.s_addr == INADDR_ANY)
if (link->server != NULL) { /* LSNAT link */
struct in_addr src_addr;
src_addr = link->server->addr;
link->server = link->server->next;
return (src_addr);
} else if (link->src_addr.s_addr == INADDR_ANY)
return aliasAddress;
else
return link->src_addr;
@ -2035,6 +2062,7 @@ UninitPacketAliasLog(void)
-- "outside world" means other than alias*.c routines --
PacketAliasRedirectPort()
PacketAliasAddServer()
PacketAliasRedirectPptp()
PacketAliasRedirectAddr()
PacketAliasRedirectDelete()
@ -2092,6 +2120,36 @@ PacketAliasRedirectPort(struct in_addr src_addr, u_short src_port,
return link;
}
/* Add server to the pool of servers */
int
PacketAliasAddServer(struct alias_link *link, struct in_addr addr, u_short port)
{
struct server *server;
server = malloc(sizeof(struct server));
if (server != NULL) {
struct server *head;
server->addr = addr;
server->port = port;
head = link->server;
if (head == NULL)
server->next = server;
else {
struct server *s;
for (s = head; s->next != head; s = s->next);
s->next = server;
server->next = head;
}
link->server = server;
return (0);
} else
return (-1);
}
/* Translate PPTP packets to a machine on the inside
* XXX This function is made obsolete by PacketAliasRedirectPptp().
*/

View File

@ -376,6 +376,14 @@ is called to change the address after
.Fn PacketAliasRedirectPort
is called, a zero reference will track this change.
.Pp
If the link is further set up to operate for a load sharing, then
.Fa local_addr
and
.Fa local_port
are ignored, and are selected dynamically from the server pool, as described in
.Fn PacketAliasAddServer
below.
.Pp
If
.Fa remote_addr
is zero, this indicates to redirect packets from any remote address.
@ -434,6 +442,12 @@ is called to change the address after
.Fn PacketAliasRedirectAddr
is called, a zero reference will track this change.
.Pp
If the link is further set up to operate for a load sharing, then
.Fa local_addr
is ignored, and is selected dynamically from the server pool, as described in
.Fn PacketAliasAddServer
below.
.Pp
If subsequent calls to
.Fn PacketAliasRedirectAddr
use the same aliasing address, all new incoming traffic to this aliasing
@ -471,6 +485,52 @@ If
is returned, then the function call did not complete successfully.
.Ed
.Pp
.Ft int
.Fo PacketAliasAddServer
.Fa "struct alias_link *link"
.Fa "struct in_addr addr"
.Fa "u_short port"
.Fc
.Bd -ragged -offset indent
This function sets the
.Fa link
up for Load Sharing using IP Network Address Translation (RFC 2391, LSNAT).
LSNAT operates as follows.
A client attempts to access a server by using the server virtual address.
The LSNAT router transparently redirects the request to one of the hosts
in server pool, selected using a real-time load sharing algorithm.
Multiple sessions may be initiated from the same client, and each session
could be directed to a different host based on load balance across server
pool hosts at the time.
If load share is desired for just a few specific services, the configuration
on LSNAT could be defined to restrict load share for just the services
desired.
.Pp
Currently, only the simplest selection algorithm is implemented, where a
host is selected on a round-robin basis only, without regard to load on
the host.
.Pp
First, the
.Fa link
is created by either
.Fn PacketAliasRedirectPort
or
.Fn PacketAliasRedirectAddr .
Then,
.Fn PacketAliasAddServer
is called multiple times to add entries to the
.Fa link Ns 's
server pool.
.Pp
For links created with
.Fn PacketAliasRedirectAddr ,
the
.Fa port
argument is ignored and could have any value, e.g. htons(~0).
.Pp
This function returns 0 on success, -1 otherwise.
.Ed
.Pp
.Ft void
.Fn PacketAliasRedirectDelete "struct alias_link *link"
.Bd -ragged -offset indent

View File

@ -51,6 +51,11 @@ struct alias_link;
struct in_addr, u_short,
u_char);
extern int
PacketAliasAddServer(struct alias_link *link,
struct in_addr addr,
u_short port);
extern int
PacketAliasPptp(struct in_addr);

View File

@ -237,6 +237,13 @@ struct tcp_dat
int fwhole; /* Which firewall record is used for this hole? */
};
struct server /* LSNAT server pool (circular list) */
{
struct in_addr addr;
u_short port;
struct server *next;
};
struct alias_link /* Main data structure */
{
struct in_addr src_addr; /* Address and port information */
@ -247,6 +254,7 @@ struct alias_link /* Main data structure */
u_short dst_port;
u_short alias_port;
u_short proxy_port;
struct server *server;
int link_type; /* Type of link: TCP, UDP, ICMP, PPTP, frag */
@ -778,6 +786,17 @@ DeleteLink(struct alias_link *link)
ClearFWHole(link);
#endif
/* Free memory allocated for LSNAT server pool */
if (link->server != NULL) {
struct server *head, *curr, *next;
head = curr = link->server;
do {
next = curr->next;
free(curr);
} while ((curr = next) != head);
}
/* Adjust output table pointers */
link_last = link->last_out;
link_next = link->next_out;
@ -871,6 +890,7 @@ AddLink(struct in_addr src_addr,
link->src_port = src_port;
link->dst_port = dst_port;
link->proxy_port = 0;
link->server = NULL;
link->link_type = link_type;
link->sockfd = -1;
link->flags = 0;
@ -1044,6 +1064,7 @@ _FindLinkOut(struct in_addr src_addr,
while (link != NULL)
{
if (link->src_addr.s_addr == src_addr.s_addr
&& link->server == NULL
&& link->dst_addr.s_addr == dst_addr.s_addr
&& link->dst_port == dst_port
&& link->src_port == src_port
@ -1207,39 +1228,39 @@ _FindLinkIn(struct in_addr dst_addr,
if (link_fully_specified != NULL)
{
link_fully_specified->timestamp = timeStamp;
return link_fully_specified;
link = link_fully_specified;
}
else if (link_unknown_dst_port != NULL)
{
return replace_partial_links
? ReLink(link_unknown_dst_port,
link_unknown_dst_port->src_addr, dst_addr, alias_addr,
link_unknown_dst_port->src_port, dst_port, alias_port,
link_type)
: link_unknown_dst_port;
}
link = link_unknown_dst_port;
else if (link_unknown_dst_addr != NULL)
{
return replace_partial_links
? ReLink(link_unknown_dst_addr,
link_unknown_dst_addr->src_addr, dst_addr, alias_addr,
link_unknown_dst_addr->src_port, dst_port, alias_port,
link_type)
: link_unknown_dst_addr;
}
link = link_unknown_dst_addr;
else if (link_unknown_all != NULL)
{
return replace_partial_links
? ReLink(link_unknown_all,
link_unknown_all->src_addr, dst_addr, alias_addr,
link_unknown_all->src_port, dst_port, alias_port,
link_type)
: link_unknown_all;
}
link = link_unknown_all;
else
return (NULL);
if (replace_partial_links &&
(link->flags & LINK_PARTIALLY_SPECIFIED || link->server != NULL))
{
return(NULL);
struct in_addr src_addr;
u_short src_port;
if (link->server != NULL) { /* LSNAT link */
src_addr = link->server->addr;
src_port = link->server->port;
link->server = link->server->next;
} else {
src_addr = link->src_addr;
src_port = link->src_port;
}
link = ReLink(link,
src_addr, dst_addr, alias_addr,
src_port, dst_port, alias_port,
link_type);
}
return (link);
}
static struct alias_link *
@ -1527,7 +1548,13 @@ FindOriginalAddress(struct in_addr alias_addr)
}
else
{
if (link->src_addr.s_addr == INADDR_ANY)
if (link->server != NULL) { /* LSNAT link */
struct in_addr src_addr;
src_addr = link->server->addr;
link->server = link->server->next;
return (src_addr);
} else if (link->src_addr.s_addr == INADDR_ANY)
return aliasAddress;
else
return link->src_addr;
@ -2035,6 +2062,7 @@ UninitPacketAliasLog(void)
-- "outside world" means other than alias*.c routines --
PacketAliasRedirectPort()
PacketAliasAddServer()
PacketAliasRedirectPptp()
PacketAliasRedirectAddr()
PacketAliasRedirectDelete()
@ -2092,6 +2120,36 @@ PacketAliasRedirectPort(struct in_addr src_addr, u_short src_port,
return link;
}
/* Add server to the pool of servers */
int
PacketAliasAddServer(struct alias_link *link, struct in_addr addr, u_short port)
{
struct server *server;
server = malloc(sizeof(struct server));
if (server != NULL) {
struct server *head;
server->addr = addr;
server->port = port;
head = link->server;
if (head == NULL)
server->next = server;
else {
struct server *s;
for (s = head; s->next != head; s = s->next);
s->next = server;
server->next = head;
}
link->server = server;
return (0);
} else
return (-1);
}
/* Translate PPTP packets to a machine on the inside
* XXX This function is made obsolete by PacketAliasRedirectPptp().
*/

View File

@ -376,6 +376,14 @@ is called to change the address after
.Fn PacketAliasRedirectPort
is called, a zero reference will track this change.
.Pp
If the link is further set up to operate for a load sharing, then
.Fa local_addr
and
.Fa local_port
are ignored, and are selected dynamically from the server pool, as described in
.Fn PacketAliasAddServer
below.
.Pp
If
.Fa remote_addr
is zero, this indicates to redirect packets from any remote address.
@ -434,6 +442,12 @@ is called to change the address after
.Fn PacketAliasRedirectAddr
is called, a zero reference will track this change.
.Pp
If the link is further set up to operate for a load sharing, then
.Fa local_addr
is ignored, and is selected dynamically from the server pool, as described in
.Fn PacketAliasAddServer
below.
.Pp
If subsequent calls to
.Fn PacketAliasRedirectAddr
use the same aliasing address, all new incoming traffic to this aliasing
@ -471,6 +485,52 @@ If
is returned, then the function call did not complete successfully.
.Ed
.Pp
.Ft int
.Fo PacketAliasAddServer
.Fa "struct alias_link *link"
.Fa "struct in_addr addr"
.Fa "u_short port"
.Fc
.Bd -ragged -offset indent
This function sets the
.Fa link
up for Load Sharing using IP Network Address Translation (RFC 2391, LSNAT).
LSNAT operates as follows.
A client attempts to access a server by using the server virtual address.
The LSNAT router transparently redirects the request to one of the hosts
in server pool, selected using a real-time load sharing algorithm.
Multiple sessions may be initiated from the same client, and each session
could be directed to a different host based on load balance across server
pool hosts at the time.
If load share is desired for just a few specific services, the configuration
on LSNAT could be defined to restrict load share for just the services
desired.
.Pp
Currently, only the simplest selection algorithm is implemented, where a
host is selected on a round-robin basis only, without regard to load on
the host.
.Pp
First, the
.Fa link
is created by either
.Fn PacketAliasRedirectPort
or
.Fn PacketAliasRedirectAddr .
Then,
.Fn PacketAliasAddServer
is called multiple times to add entries to the
.Fa link Ns 's
server pool.
.Pp
For links created with
.Fn PacketAliasRedirectAddr ,
the
.Fa port
argument is ignored and could have any value, e.g. htons(~0).
.Pp
This function returns 0 on success, -1 otherwise.
.Ed
.Pp
.Ft void
.Fn PacketAliasRedirectDelete "struct alias_link *link"
.Bd -ragged -offset indent