From b3e08f68b86b8fdfc12ed867172fdb8a3887efcc Mon Sep 17 00:00:00 2001 From: ru Date: Thu, 27 Apr 2000 17:55:17 +0000 Subject: Load Sharing using IP Network Address Translation (RFC 2391, LSNAT). --- sbin/natd/natd.8 | 42 +++++++++++++++++++++++++++-- sbin/natd/natd.c | 82 +++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 106 insertions(+), 18 deletions(-) (limited to 'sbin/natd') diff --git a/sbin/natd/natd.8 b/sbin/natd/natd.8 index fbdbb97..1feabd1 100644 --- a/sbin/natd/natd.8 +++ b/sbin/natd/natd.8 @@ -35,7 +35,7 @@ Network Address Translation Daemon .Op Fl interface Ar interface .Op Fl config Ar configfile .Op Fl redirect_port Ar linkspec -.Op Fl redirect_address Ar localIP publicIP +.Op Fl redirect_address Ar linkspec .Op Fl reverse .Op Fl proxy_only .Op Fl proxy_rule Ar proxyspec @@ -163,7 +163,45 @@ the incoming traffic will be directed to the last translated local address (192.168.0.4), but outgoing traffic to the first two addresses will still be aliased to specified public address. - +.It Fl redirect_port Ar proto Xo +.Ar targetIP Ns : Ns Xo +.Ar targetPORT Ns Oo , Ns +.Ar targetIP Ns : Ns Xo +.Ar targetPORT Ns Oo , Ns +.Ar ... +.Oc Oc +.Xc +.Xc +.Op Ar aliasIP Ns : Ns Xo +.Ar aliasPORT +.Xc +.Oo Ar remoteIP Ns +.Op : Ns Ar remotePORT +.Oc +.Xc +.It Fl redirect_address Xo +.Ar localIP Ns Oo , Ns +.Ar localIP Ns Oo , Ns +.Ar ... +.Oc Oc +.Ar publicIP +.Xc +These forms of +.Fl redirect_port +and +.Fl redirect_address +are used to transparently offload network load on a single server and +distribute the load across a pool of servers. +This function is known as +.Em LSNAT +(RFC 2391). +For example, the argument +.Pp +.Dl Ar tcp www1:http,www2:http,www3:http www:http +.Pp +means that incoming HTTP requests for host www will be transparently +redirected to one of the www1, www2 or www3, where a host is selected +simply on a round-robin basis, without regard to load on the net. .It Fl dynamic If the .Fl n diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c index 6bc4c5d..2714a15 100644 --- a/sbin/natd/natd.c +++ b/sbin/natd/natd.c @@ -1021,7 +1021,7 @@ static struct OptionInfo optionTable[] = { { RedirectPort, 0, String, - "tcp|udp local_addr:local_port_range [public_addr:]public_port_range" + "tcp|udp local_addr:local_port_range[,...] [public_addr:]public_port_range" " [remote_addr[:remote_port_range]]", "redirect a port (or ports) for incoming traffic", "redirect_port", @@ -1030,7 +1030,7 @@ static struct OptionInfo optionTable[] = { { RedirectAddress, 0, String, - "local_addr public_addr", + "local_addr[,...] public_addr", "define mapping between local and public addresses", "redirect_address", NULL }, @@ -1348,6 +1348,7 @@ void SetupPortRedirect (const char* parms) { char buf[128]; char* ptr; + char* serverPool; struct in_addr localAddr; struct in_addr publicAddr; struct in_addr remoteAddr; @@ -1362,6 +1363,7 @@ void SetupPortRedirect (const char* parms) char* protoName; char* separator; int i; + struct alias_link *link = NULL; strcpy (buf, parms); /* @@ -1379,11 +1381,20 @@ void SetupPortRedirect (const char* parms) if (!ptr) errx (1, "redirect_port: missing local address"); - if ( StrToAddrAndPortRange (ptr, &localAddr, protoName, &portRange) != 0 ) - errx (1, "redirect_port: invalid local port range"); - - localPort = GETLOPORT(portRange); - numLocalPorts = GETNUMPORTS(portRange); + separator = strchr(ptr, ','); + if (separator) { /* LSNAT redirection syntax. */ + localAddr.s_addr = INADDR_NONE; + localPort = ~0; + numLocalPorts = 1; + serverPool = ptr; + } else { + if ( StrToAddrAndPortRange (ptr, &localAddr, protoName, &portRange) != 0 ) + errx (1, "redirect_port: invalid local port range"); + + localPort = GETLOPORT(portRange); + numLocalPorts = GETNUMPORTS(portRange); + serverPool = NULL; + } /* * Extract public port and optionally address. @@ -1446,13 +1457,30 @@ void SetupPortRedirect (const char* parms) if (numRemotePorts == 1 && remotePort == 0) remotePortCopy = 0; - PacketAliasRedirectPort (localAddr, - htons(localPort + i), - remoteAddr, - htons(remotePortCopy), - publicAddr, - htons(publicPort + i), - proto); + link = PacketAliasRedirectPort (localAddr, + htons(localPort + i), + remoteAddr, + htons(remotePortCopy), + publicAddr, + htons(publicPort + i), + proto); + } + +/* + * Setup LSNAT server pool. + */ + if (serverPool != NULL && link != NULL) { + ptr = strtok(serverPool, ","); + while (ptr != NULL) { + if (StrToAddrAndPortRange(ptr, &localAddr, protoName, &portRange) != 0) + errx(1, "redirect_port: invalid local port range"); + + localPort = GETLOPORT(portRange); + if (GETNUMPORTS(portRange) != 1) + errx(1, "redirect_port: local port must be single in this context"); + PacketAliasAddServer(link, localAddr, htons(localPort)); + ptr = strtok(NULL, ","); + } } } @@ -1460,8 +1488,11 @@ void SetupAddressRedirect (const char* parms) { char buf[128]; char* ptr; + char* separator; struct in_addr localAddr; struct in_addr publicAddr; + char* serverPool; + struct alias_link *link; strcpy (buf, parms); /* @@ -1471,7 +1502,14 @@ void SetupAddressRedirect (const char* parms) if (!ptr) errx (1, "redirect_address: missing local address"); - StrToAddr (ptr, &localAddr); + separator = strchr(ptr, ','); + if (separator) { /* LSNAT redirection syntax. */ + localAddr.s_addr = INADDR_NONE; + serverPool = ptr; + } else { + StrToAddr (ptr, &localAddr); + serverPool = NULL; + } /* * Extract public address. */ @@ -1480,7 +1518,19 @@ void SetupAddressRedirect (const char* parms) errx (1, "redirect_address: missing public address"); StrToAddr (ptr, &publicAddr); - PacketAliasRedirectAddr (localAddr, publicAddr); + link = PacketAliasRedirectAddr(localAddr, publicAddr); + +/* + * Setup LSNAT server pool. + */ + if (serverPool != NULL && link != NULL) { + ptr = strtok(serverPool, ","); + while (ptr != NULL) { + StrToAddr(ptr, &localAddr); + PacketAliasAddServer(link, localAddr, htons(~0)); + ptr = strtok(NULL, ","); + } + } } void StrToAddr (const char* str, struct in_addr* addr) -- cgit v1.1