[-]
[+]
|
Changed |
crossroads.spec
|
|
[-]
[+]
|
Changed |
crossroads-makefile.patch
^
|
@@ -1,18 +1,11 @@
---- Makefile.orig 2008-08-08 09:51:51.000000000 +0200
-+++ Makefile 2008-08-08 09:52:31.000000000 +0200
-@@ -27,7 +27,7 @@
+--- Makefile.orig 2008-08-16 00:00:07.000000000 +0200
++++ Makefile 2008-08-16 11:59:50.000000000 +0200
+@@ -28,7 +28,7 @@
install: local
mkdir -p $(BINDIR)
- AUTHOR='$(AUTHOR)' MAINTAINER='$(MAINTAINER)' \
+ BASE=$(BASE) AUTHOR='$(AUTHOR)' MAINTAINER='$(MAINTAINER)' \
- VER='$(VER)' BINDIR=$(BINDIR) $(MAKE) -C xr install
+ VER='$(VER)' BINDIR=$(DESTDIR)$(BINDIR) $(MAKE) -C xr install
@echo
@echo ' The balancer program xr is now installed to $(BINDIR).'
- @echo ' Consider configuring xrctl/xrctl and copying it to $(BINDIR) too.'
-@@ -52,4 +52,4 @@
- test `svn status | grep '^\?' | wc -l` -eq 0 || \
- (echo 'SVN not fully up to date' && exit 1)
- svn commit
--
-\ Kein Zeilenumbruch am Dateiende.
-+
+ @echo ' Consider configuring xrctl/xrctl and copying it to $(BINDIR).'
|
[-]
[+]
|
Changed |
crossroads-devel.ChangeLog
^
|
@@ -1 +1,38 @@
+2.05 [KK 2008-08-15]
+Thrown errors now based on std::exeception.
+"xr -V" shows compilation settings.
+Code reorganized into directory hierarchy.
+
+2.04 [KK 2008-08-11]
+Mutex in Thread class is now a static.
+Implemented dispatching algorithm "stored clent ip", in the variants
+strict and lax.
+Flag -n / --tryout implemented. Implemented in xrctl.
+
+2.03 [KK 2008-08-10]
+Updated docs regarding the mailing list.
+Fixed verbose display upon accepting a client ("current back end
+states").
+Implemented dispatching algorithm "hashed client ip", in the variants
+strict and lax.
+
+2.02 [KK 2008-08-09] Changes to the Makefile & some sources to avoid
+warnings under RHL (thanks, Simon M.).
+Bytes processed by a back end is now administered in
+TcpDispatcher::writechunk() and not readchunk(). Reason: In HTTP mode,
+the target back end is not yet known upon the first read -- the first read
+from the client comes before dispatching. Thanks Simon M. for the bug
+report.
+All select()'s now check for errno==EINTR, incase XR gets a signal -1
+(for status report).
+
+2.01 [KK 2008-08-08] Implemented flag -C (--close-sockets-fast): this
+option *can* be used under heavy stress when too many network sockets
+remain in TIME_WAIT state (try with 'netstat -n | grep TIME_WAIT').
+Syntax of xrctl is checked upon "make commit".
+Added documentation about Solaris tcp_time_wait_interval and Linux
+ip_conntrack_max.
+Added documentation about binding XR to the same port, using different
+bind-to IP's.
+
2.00 [KK 2008-08-07] Release of 2.00.
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/ChangeLog
^
|
@@ -1 +1,38 @@
+2.05 [KK 2008-08-15]
+Thrown errors now based on std::exeception.
+"xr -V" shows compilation settings.
+Code reorganized into directory hierarchy.
+
+2.04 [KK 2008-08-11]
+Mutex in Thread class is now a static.
+Implemented dispatching algorithm "stored clent ip", in the variants
+strict and lax.
+Flag -n / --tryout implemented. Implemented in xrctl.
+
+2.03 [KK 2008-08-10]
+Updated docs regarding the mailing list.
+Fixed verbose display upon accepting a client ("current back end
+states").
+Implemented dispatching algorithm "hashed client ip", in the variants
+strict and lax.
+
+2.02 [KK 2008-08-09] Changes to the Makefile & some sources to avoid
+warnings under RHL (thanks, Simon M.).
+Bytes processed by a back end is now administered in
+TcpDispatcher::writechunk() and not readchunk(). Reason: In HTTP mode,
+the target back end is not yet known upon the first read -- the first read
+from the client comes before dispatching. Thanks Simon M. for the bug
+report.
+All select()'s now check for errno==EINTR, incase XR gets a signal -1
+(for status report).
+
+2.01 [KK 2008-08-08] Implemented flag -C (--close-sockets-fast): this
+option *can* be used under heavy stress when too many network sockets
+remain in TIME_WAIT state (try with 'netstat -n | grep TIME_WAIT').
+Syntax of xrctl is checked upon "make commit".
+Added documentation about Solaris tcp_time_wait_interval and Linux
+ip_conntrack_max.
+Added documentation about binding XR to the same port, using different
+bind-to IP's.
+
2.00 [KK 2008-08-07] Release of 2.00.
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/Makefile
^
|
@@ -1,11 +1,12 @@
# Top-level Makefile for XR
# -------------------------
-VER = 2.00
+VER = 2.05
BINDIR = /usr/sbin
TAR = /tmp/crossroads-$(VER).tar.gz
AUTHOR = Karel Kubat <karel@kubat.nl>
MAINTAINER = Karel Kubat <karel@kubat.nl>
+BASE = $(shell pwd)
foo:
@echo
@@ -21,18 +22,18 @@
mkdir -p xr/build
xr/etc/gettools /usr/local/bin xr/etc c-conf e-ver
xr/etc/e-ver ChangeLog $(VER)
- AUTHOR='$(AUTHOR)' MAINTAINER='$(MAINTAINER)' VER='$(VER)'\
- $(MAKE) -C xr
+ BASE=$(BASE) AUTHOR='$(AUTHOR)' MAINTAINER='$(MAINTAINER)' \
+ VER='$(VER)' $(MAKE) -C xr
install: local
mkdir -p $(BINDIR)
- AUTHOR='$(AUTHOR)' MAINTAINER='$(MAINTAINER)' \
+ BASE=$(BASE) AUTHOR='$(AUTHOR)' MAINTAINER='$(MAINTAINER)' \
VER='$(VER)' BINDIR=$(BINDIR) $(MAKE) -C xr install
@echo
@echo ' The balancer program xr is now installed to $(BINDIR).'
- @echo ' Consider configuring xrctl/xrctl and copying it to $(BINDIR) too.'
- @echo ' The helper xrctl is not installed automatically.'
- @echo ' Have fun with Crossroads $(VER)!'
+ @echo ' Consider configuring xrctl/xrctl and copying it to $(BINDIR).'
+ @echo ' The helper xrctl is not installed automatically!!'
+ @echo ' Have fun with Crossroads $(VER),'
@echo ' -- $(MAINTAINER)'
@echo
@@ -50,6 +51,7 @@
commit: local clean
test `svn status | grep '^\?' | wc -l` -eq 0 || \
- (echo 'SVN not fully up to date' && exit 1)
+ (echo 'SVN not fully up to date: run "svn status"' && exit 1)
+ perl -c xrctl/xrctl
svn commit
\ No newline at end of file
|
|
Changed |
crossroads-devel.tar.gz/doc/xr.odt
^
|
|
Changed |
crossroads-devel.tar.gz/doc/xr.pdf
^
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/test
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/test/iphashtest.cc
^
|
@@ -0,0 +1,51 @@
+// C
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+// C++
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+int main () {
+ for (int a = 0; a <= 255; a++) {
+ ostringstream o;
+ o << "192.168.1." << a;
+
+ struct in_addr ad;
+ inet_aton (o.str().c_str(), &ad);
+
+ unsigned index = 0;
+ for (char *cp = (char*) &ad;
+ unsigned(cp - (char*)&ad) < sizeof(struct in_addr);
+ cp++) {
+ index += *cp;
+ index %= 60;
+ //cout << " " << "byte: " << hex << *cp
+ // << ", index: " << index << "\n";
+ }
+
+ cout << inet_ntoa(ad) << ": " << dec << index << "\n";
+ }
+
+ return (0);
+}
+
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/test/xr-test
^
|
@@ -0,0 +1,36 @@
+#!/usr/bin/perl
+
+use strict;
+use LWP::UserAgent;
+use Time::HiRes qw(sleep gettimeofday tv_interval);
+
+die ("Usage: $0 URL TRIALS\n") if ($#ARGV != 1);
+$|++;
+
+my $n = 0;
+my $totaltime = 0;
+
+my $ua = LWP::UserAgent->new();
+$ua->timeout(5);
+while ($n < $ARGV[1]) {
+ my $success = 0;
+ for my $i (1..10) {
+ my $t0 = [ gettimeofday() ];
+ my $resp = $ua->get($ARGV[0]);
+ if ($resp->is_success()) {
+ $success++;
+ $n++;
+ $totaltime += tv_interval ($t0);
+ last;
+ }
+ if ($i == 3) {
+ die ($resp->status_line(), "\n");
+ }
+ sleep (1);
+ }
+ sleep (0.1);
+ printf ("\rN: %5d Tot:%8.3g Avg:%8.3g", $n, $totaltime, $totaltime / $n)
+ if (! ($n % 10));
+}
+
+print ("\n");
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/Checkers
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/Checkers/checkupthread
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/Checkers/checkupthread/checkupthread
^
|
@@ -0,0 +1,14 @@
+#ifndef _CHECKUPTHREAD_
+#define _CHECKUPTHREAD_
+
+#include "sys/sys"
+#include "thread/thread"
+#include "balancer/balancer"
+#include "error/error"
+
+class Checkupthread: public Thread {
+public:
+ void execute();
+};
+
+#endif
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/Checkers/checkupthread/execute.cc
^
|
(renamed to xr/Checkers/checkupthread/execute.cc)
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/Checkers/checkupthread/execute.cc
^
|
(renamed to xr/Checkers/checkupthread/execute.cc)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/Checkers/wakeupthread
^
|
+(directory)
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/Checkers/wakeupthread/execute.cc
^
|
(renamed to xr/Checkers/wakeupthread/execute.cc)
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/Checkers/wakeupthread/execute.cc
^
|
(renamed to xr/Checkers/wakeupthread/execute.cc)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/Checkers/wakeupthread/wakeupthread
^
|
@@ -0,0 +1,14 @@
+#ifndef _WAKEUPTHREAD_
+#define _WAKEUPTHREAD_
+
+#include "sys/sys"
+#include "thread/thread"
+#include "balancer/balancer"
+#include "error/error"
+
+class Wakeupthread: public Thread {
+public:
+ void execute();
+};
+
+#endif
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/algorithm
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/algorithm/algorithm
^
|
@@ -0,0 +1,12 @@
+#ifndef _ALGORITHM_
+#define _ALGORITHM_
+
+#include "thread/thread"
+
+class Algorithm: public Thread {
+public:
+ virtual ~Algorithm();
+ virtual int target(struct in_addr clientip) = 0;
+};
+
+#endif
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/algorithm/algorithm.cc
^
|
(renamed to xr/DispatchAlgorithms/algorithm/algorithm.cc)
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/algorithm/algorithm.cc
^
|
(renamed to xr/DispatchAlgorithms/algorithm/algorithm.cc)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/external
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/external/external
^
|
@@ -0,0 +1,15 @@
+#ifndef _EXTERNAL_
+#define _EXTERNAL_
+
+#include "sys/sys"
+#include "error/error"
+#include "DispatchAlgorithms/algorithm/algorithm"
+#include "balancer/balancer"
+#include "config/config"
+
+class External: public Algorithm {
+public:
+ int target(struct in_addr clientip);
+};
+
+#endif
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/external/target.cc
^
|
@@ -0,0 +1,34 @@
+#include "external"
+
+int External::target(struct in_addr clientip) {
+ // Prepare command to run
+ ostringstream o;
+ o << config.externalalgorithm() << ' ' << balancer.nbackends();
+ for (unsigned i = 0; i < balancer.nbackends(); i++)
+ o << ' ' << balancer.backend(i).description() << ' '
+ << balancer.backend(i).availablestr()
+ << ' ' << balancer.backend(i).connections();
+ msg ("External algorithm: invoking '" + o.str() + "'\n");
+
+ FILE *f;
+ if (! (f = popen (o.str().c_str(), "r")) )
+ throw static_cast<Error>("Cannot start '") + o.str() + "': " +
+ strerror(errno);
+ int i;
+ if (fscanf (f, "%d", &i) < 1)
+ throw static_cast<Error>("External algorithm '") + o.str() +
+ "' did not reply with a number";
+
+ ostringstream n;
+ n << i;
+ msg ("External algorithm says: " + n.str() + "\n");
+
+ if (i < 0 || i >= (int)balancer.nbackends())
+ throw static_cast<Error>("External algorithm '") + o.str() +
+ "': answer " + n.str() + " out of bounds";
+ if (pclose (f))
+ throw static_cast<Error>("External algorithm '") + o.str() +
+ "' terminated with error";
+
+ return (i);
+}
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/firstactive
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/firstactive/firstactive
^
|
@@ -0,0 +1,14 @@
+#ifndef _FIRSTACTIVE_
+#define _FIRSTACTIVE_
+
+#include "sys/sys"
+#include "error/error"
+#include "DispatchAlgorithms/algorithm/algorithm"
+#include "balancer/balancer"
+
+class Firstactive: public Algorithm {
+public:
+ int target(struct in_addr clientip);
+};
+
+#endif
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/firstactive/target.cc
^
|
@@ -0,0 +1,9 @@
+#include "firstactive"
+
+int Firstactive::target(struct in_addr clientip) {
+ for (unsigned i = 0; i < balancer.nbackends(); i++)
+ if (balancer.backend(i).available())
+ return ( (int) i);
+ throw static_cast<Error>("First-active algorithm: no available back ends");
+}
+
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/hashedip
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/hashedip/hashedip
^
|
@@ -0,0 +1,16 @@
+#ifndef _HASHEDIP_
+#define _HASHEDIP_
+
+#include "sys/sys"
+#include "error/error"
+#include "balancer/balancer"
+#include "config/config"
+#include "DispatchAlgorithms/algorithm/algorithm"
+#include "DispatchAlgorithms/leastconn/leastconn"
+
+class HashedIp: public Algorithm {
+public:
+ int target(struct in_addr clientip);
+};
+
+#endif
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/hashedip/target.cc
^
|
@@ -0,0 +1,40 @@
+#include "hashedip"
+
+int HashedIp::target(struct in_addr clientip) {
+ // Hash the client's IP into an index
+ unsigned h = 0;
+ for (char *cp = (char*)&clientip;
+ unsigned(cp - (char*)&clientip) < sizeof(struct in_addr);
+ cp++) {
+ h += *cp;
+ h %= balancer.nbackends();
+ }
+ int index = int(h);
+
+ if (config.verbose()) {
+ ostringstream o;
+ o << index;
+ msg ("Client IP " + (string)inet_ntoa(clientip) + " hashes to " +
+ o.str() + ", back end " +
+ balancer.backend(index).description() +
+ "\n");
+ }
+
+ // In strict mode, back end must be available, or don't proceed
+ // In lax mode, fall back to least-connections dispatching
+ if (! balancer.backend(index).available()) {
+ if (config.dispatchmode() == Dispatchmode::m_strict_hashed_ip)
+ throw static_cast<Error>("Hashed-IP algorithm: target back end ") +
+ balancer.backend(index).description() + " unavailable";
+ else {
+ msg ("Hashed-IP algorithm: target back end " +
+ balancer.backend(index).description() + " unavailable, "
+ "falling back to least-connections\n");
+ Leastconn l;
+ index = l.target(clientip);
+ }
+ }
+
+ // Got it
+ return (index);
+}
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/leastconn
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/leastconn/leastconn
^
|
@@ -0,0 +1,14 @@
+#ifndef _LEASTCONN_
+#define _LEASTCONN_
+
+#include "sys/sys"
+#include "error/error"
+#include "balancer/balancer"
+#include "DispatchAlgorithms/algorithm/algorithm"
+
+class Leastconn: public Algorithm {
+public:
+ int target(struct in_addr clientip);
+};
+
+#endif
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/leastconn/target.cc
^
|
@@ -0,0 +1,23 @@
+#include "leastconn"
+
+int Leastconn::target(struct in_addr clientip) {
+ bool found = false;
+ unsigned nconn;
+ int t;
+
+ for (unsigned i = 0; i < balancer.nbackends(); i++) {
+ if (!balancer.backend(i).available())
+ continue;
+ if (!found ||
+ balancer.backend(i).connections() < nconn) {
+ nconn = balancer.backend(i).connections();
+ t = i;
+ found = true;
+ }
+ }
+
+ if (!found)
+ throw static_cast<Error>
+ ("Least-connections algorithm: no available back ends");
+ return (t);
+}
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/roundrobin
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/roundrobin/roundrobin
^
|
@@ -0,0 +1,14 @@
+#ifndef _ROUNDROBIN_
+#define _ROUNDROBIN_
+
+#include "sys/sys"
+#include "error/error"
+#include "balancer/balancer"
+#include "DispatchAlgorithms/algorithm/algorithm"
+
+class Roundrobin: public Algorithm {
+public:
+ int target(struct in_addr clientip);
+};
+
+#endif
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/roundrobin/target.cc
^
|
@@ -0,0 +1,27 @@
+#include "roundrobin"
+
+int Roundrobin::target(struct in_addr clientip) {
+ static int last = -1;
+ int t = last + 1;
+
+ if (last == -1) {
+ lock();
+ last = 0;
+ unlock();
+ }
+
+ while (1) {
+ if (balancer.backend(t).available()) {
+ lock();
+ last = t;
+ unlock();
+ return (t);
+ }
+ t++;
+ t %= balancer.nbackends();
+ if (t == last)
+ throw static_cast<Error>
+ ("Round-robin algorithm: no available back ends");
+ }
+}
+
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/storedip
^
|
+(directory)
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/storedip/storedip
^
|
@@ -0,0 +1,16 @@
+#ifndef _STOREDIP_
+#define _STOREDIP_
+
+#include "sys/sys"
+#include "error/error"
+#include "balancer/balancer"
+#include "config/config"
+#include "DispatchAlgorithms/algorithm/algorithm"
+#include "DispatchAlgorithms/leastconn/leastconn"
+
+class StoredIp: public Algorithm {
+public:
+ int target(struct in_addr clientip);
+};
+
+#endif
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/DispatchAlgorithms/storedip/target.cc
^
|
@@ -0,0 +1,85 @@
+#include "storedip"
+
+struct ClientData {
+ int targetbackend;
+ time_t lastaccess;
+};
+
+struct ClientDataCmp {
+ bool operator() (struct in_addr a, struct in_addr b) const {
+ long la = *((long*)&a);
+ long lb = *((long*)&b);
+ return (la - lb) < 0;
+ }
+};
+
+static map<struct in_addr, ClientData, ClientDataCmp> store;
+
+int StoredIp::target(struct in_addr clientip) {
+ int target;
+ time_t now = time(0);
+
+ // Is the client already known in the map, and not timed out?
+ map<struct in_addr, ClientData, ClientDataCmp>::iterator hit =
+ store.find(clientip);
+ if (store.count(clientip) > 0) {
+ time_t diff = now - store[clientip].lastaccess;
+ ostringstream o;
+ o << diff;
+ msg ("Client IP " + string(inet_ntoa(clientip)) +
+ " last visited on " + timestamp(store[clientip].lastaccess) +
+ ", " + o.str() + " sec ago, and went to " +
+ balancer.backend(store[clientip].targetbackend).description() +
+ "\n");
+ if (diff <= config.ipstoretimeout()) {
+ // Recent 'nuff
+ target = store[clientip].targetbackend;
+ if (! balancer.backend(target).available()) {
+ // Historical target down - get new one if in lax mode
+ if (config.dispatchmode() == Dispatchmode::m_strict_stored_ip)
+ throw static_cast<Error>
+ ("Stored-IP algorithm: target back end ") +
+ balancer.backend(target).description() +
+ "unavailable";
+ else {
+ msg ("Stored IP algorithm: target back end " +
+ balancer.backend(target).description() +
+ " unavailable, falling back to least-connections\n");
+ Leastconn l;
+ target = l.target(clientip);
+ }
+ }
+ } else {
+ // Not recent anymore
+ msg ("Visit too long ago, re-dispatching with least-connections\n");
+ Leastconn l;
+ target = l.target(clientip);
+ }
+ } else {
+ // Historical target unknown, fetch new one
+ msg ("New visit from " + (string)inet_ntoa(clientip) + "\n");
+ Leastconn l;
+ target = l.target(clientip);
+ }
+
+ // Update the info.
+ ClientData entry = {target, now};
+ store[clientip] = entry;
+
+ // Weed out store
+ map<struct in_addr, ClientData, ClientDataCmp>::iterator
+ iter = store.begin();
+ while (iter != store.end()) {
+ if (config.debug())
+ debugmsg ("Stored-IP: " +
+ (string)inet_ntoa((*iter).first) + " visited on " +
+ timestamp((*iter).second.lastaccess) + "\n");
+ if (now - ((*iter).second.lastaccess) > config.ipstoretimeout())
+ store.erase(iter);
+ else
+ iter++;
+ }
+
+ // Return target to caller
+ return (target);
+}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/Makefile
^
|
@@ -1,12 +1,13 @@
# Configuration
-DIRS = $(shell find . -type d -mindepth 1 -maxdepth 1)
+DIRS = $(shell find . -mindepth 1 -type d | grep -v .svn)
BUILDDIR = build
BIN = $(BUILDDIR)/xr
LIB = $(BUILDDIR)/libxr.a
-CC = $(shell etc/c-conf -vc $(BUILDDIR)/config.cache c++-compiler)
TMPXR = /tmp/xr-$(shell whoami)
-
+CONF_CC = $(shell etc/c-conf -vc $(BUILDDIR)/config.cache c++-compiler)
+CONF_LIB = $(shell etc/c-conf -vc $(BUILDDIR)/config.cache lib \
+ ucb nsl pthread socket m alf)
foo:
$(MAKE) subdirs
$(MAKE) $(BIN)
@@ -22,9 +23,10 @@
@for f in $(DIRS) ; \
do \
echo "Making: $$f"; \
- CC=$(CC) BUILDDIR=$(BUILDDIR) VER='$(VER)' \
+ BASE=$(BASE) CC=$(CONF_CC) BUILDDIR=$(BUILDDIR) VER='$(VER)' \
AUTHOR='$(AUTHOR)' MAINTAINER='$(MAINTAINER)' \
- $(MAKE) -C $$f -f ../etc/Makefile.class \
+ CONF_CC='$(CONF_CC)' CONF_LIB='$(CONF_LIB)' \
+ $(MAKE) -C $$f -f $(BASE)/xr//etc/Makefile.class \
|| exit 1; \
done
ar rs $(LIB) */*.o
@@ -33,9 +35,7 @@
etc/e-txt2c USAGE <etc/usage.txt >$(BUILDDIR)/usage.h
$(BIN): $(BUILDDIR)/libxr.a
- $(CC) -g -o $(BIN) -L$(BUILDDIR) -lxr \
- $(shell etc/c-conf -vc $(BUILDIR)/config.cache lib \
- ucb nsl pthread socket m alf)
+ $(CONF_CC) -g -o $(BIN) -L$(BUILDDIR) -lxr $(CONF_LIB)
clean:
rm -f $(BIN) $(LIB) core obj/*.o etc/usage.h $(BUILDDIR)/config.cache
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/algorithm
^
|
-(directory)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/algorithm/algorithm
^
|
@@ -1,12 +0,0 @@
-#ifndef _ALGORITHM_
-#define _ALGORITHM_
-
-#include "../thread/thread"
-
-class Algorithm: public Thread {
-public:
- virtual ~Algorithm();
- virtual int target() = 0;
-};
-
-#endif
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/backend/check.cc
^
|
@@ -2,5 +2,5 @@
void Backend::check() {
connect();
- close (clsocket);
+ socketclose (clsocket);
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/backend/connect.cc
^
|
@@ -6,12 +6,14 @@
// Create client socket
if ( (clsocket = socket (PF_INET, SOCK_STREAM, 0)) < 0 )
- throw ((Error)"Failed to create client socket: " + strerror(errno));
+ throw static_cast<Error>("Failed to create client socket: ") +
+ strerror(errno);
// Resolve hostname, prepare binding
struct hostent *hostaddr;
if (! (hostaddr = gethostbyname(bdef.server().c_str())) )
- throw ((Error)"Failed to resolve backend host '" + bdef.server());
+ throw static_cast<Error>("Failed to resolve backend host '") +
+ bdef.server();
struct sockaddr_in backendaddr;
backendaddr.sin_family = AF_INET;
backendaddr.sin_port = htons(bdef.port());
@@ -22,9 +24,10 @@
// and enforce a timeout later.
int flags;
if ( (flags = fcntl (clsocket, F_GETFL, 0)) == -1 )
- throw ((Error) "Failed to get fd flags: " + strerror(errno));
+ throw static_cast<Error>("Failed to get fd flags: ") + strerror(errno);
if (fcntl (clsocket, F_SETFL, flags | O_NONBLOCK) == -1)
- throw ((Error) "Failed to fd in nonblocking mode: " + strerror(errno));
+ throw static_cast<Error>("Failed to fd in nonblocking mode: ") +
+ strerror(errno);
// Do the connect
int conres = ::connect (clsocket, (struct sockaddr *)&backendaddr,
@@ -33,8 +36,8 @@
// Put socket again in blocking mode.
if (fcntl (clsocket, F_SETFL, flags) == -1)
- throw ((Error) "Failed to put fd in blocking mode: " +
- strerror(errno));
+ throw static_cast<Error>("Failed to put fd in blocking mode: ") +
+ strerror(errno);
// Check on the outcome of the connect
if (!conres || conerrno == EINPROGRESS) {
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/backenddef/backenddef1.cc
^
|
@@ -4,10 +4,10 @@
srv(server), prt(0), max(0) {
if (sscanf (port.c_str(), "%d", &prt) < 1)
- throw ((Error) "Bad backend port specifier: '" + port +
- "' is not a number");
+ throw static_cast<Error>("Bad backend port specifier: '") + port +
+ "' is not a number";
if (maxclients.size() &&
sscanf (maxclients.c_str(), "%u", &max) < 1)
- throw ((Error) "Bad maximum connections specifier: '" +
- maxclients + "' is not a number");
+ throw static_cast<Error>("Bad maximum connections specifier: '") +
+ maxclients + "' is not a number";
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/balancer/balancer
^
|
@@ -1,15 +1,17 @@
#ifndef _BALANCER_
#define _BALANCER_
-#include "../sys/sys"
+#include "sys/sys"
-#include "../backend/backend"
-#include "../backenddef/backenddef"
-#include "../config/config"
-#include "../wakeupthread/wakeupthread"
-#include "../checkupthread/checkupthread"
-#include "../fdset/fdset"
-#include "../error/error"
+#include "backend/backend"
+#include "backenddef/backenddef"
+#include "config/config"
+#include "fdset/fdset"
+#include "error/error"
+
+// Check ups of back ends
+#include "Checkers/wakeupthread/wakeupthread"
+#include "Checkers/checkupthread/checkupthread"
using namespace std;
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/balancer/serve.cc
^
|
@@ -21,8 +21,8 @@
if (config.pidfile() != "") {
FILE *f;
if (! (f = fopen (config.pidfile().c_str(), "w")) )
- throw ((Error) "Cannot write pid file " + config.pidfile() +
- ": " + strerror(errno));
+ throw static_cast<Error>("Cannot write pid file ") +
+ config.pidfile() + ": " + strerror(errno);
fprintf (f, "%u\n", getpid());
fclose (f);
}
@@ -40,7 +40,7 @@
msg ("Interrupt seen\n");
if (terminate()) {
msg ("Termination requested, XR will stop.\n");
- close (server_fd);
+ socketclose (server_fd);
shutdown (server_fd, SHUT_RDWR);
unsigned prev_conn = 0x19081962;
while (1) {
@@ -90,7 +90,7 @@
size = sizeof(clname);
if ( (clsock = accept (server_fd, (struct sockaddr *) &clname,
(socklen_t*) &size)) < 0 )
- throw ((Error)"Failed to accept network connection");
+ throw static_cast<Error>("Failed to accept network connection");
string clientip = inet_ntoa(clname.sin_addr);
@@ -107,7 +107,7 @@
if (!allowed) {
msg ("Not serving client " + clientip +
": no match in allow list\n");
- close (clsock);
+ socketclose (clsock);
continue;
}
}
@@ -122,7 +122,7 @@
if (denied) {
msg ("Not serving client " + clientip +
": match in deny list\n");
- close (clsock);
+ socketclose (clsock);
continue;
}
@@ -132,6 +132,9 @@
o << clsock;
msg ("Accepted connection from " + clientip +
" as client fd " + o.str() +"\n");
+ ostringstream n;
+ n << connections();
+ msg ("Balancer is serving " + n.str() + " clients\n");
msg ("Current back end states:\n");
for (unsigned i = 0; i < nbackends(); i++) {
ostringstream status;
@@ -139,11 +142,8 @@
if (backend(i).maxconn())
status << " (max " << backend(i).maxconn() << ")";
status << ", status " << backend(i).availablestr();
- msg ("Back end " + backend(i).description() + ": " +
+ msg (" Back end " + backend(i).description() + ": " +
status.str() + "\n");
- ostringstream n;
- n << connections();
- msg ("Balancer is serving " + n.str() + " clients\n");
}
}
@@ -154,20 +154,21 @@
o << connections() << " connections (max "
<< config.maxconn() << ")";
msg ("Not serving client: already " + o.str() + "\n");
- close (clsock);
+ socketclose (clsock);
continue;
}
TcpDispatcher *d;
switch (config.stype()) {
case Servertype::t_tcp:
- d = new TcpDispatcher (clsock, clientip);
+ d = new TcpDispatcher (clsock, clname.sin_addr);
break;
case Servertype::t_http:
- d = new HttpDispatcher (clsock, clientip);
+ d = new HttpDispatcher (clsock, clname.sin_addr);
break;
default:
- throw ((Error) "Internal error, can't choose dispatcher");
+ throw static_cast<Error>("Internal error, "
+ "can't choose dispatcher");
break;
}
@@ -185,15 +186,18 @@
} else {
// If fd-serving, serve and close. Don't thread it up.
TcpDispatcher *d;
+ struct in_addr dummy;
+ inet_aton ("0.0.0.0", &dummy);
switch (config.stype()) {
case Servertype::t_tcp:
- d = new TcpDispatcher (server_fd, "0.0.0.0");
+ d = new TcpDispatcher (server_fd, dummy);
break;
case Servertype::t_http:
- d = new HttpDispatcher (server_fd, "0.0.0.0");
+ d = new HttpDispatcher (server_fd, dummy);
break;
default:
- throw ((Error) "Internal error, can't choose dispatcher");
+ throw static_cast<Error>("Internal error, "
+ "can't choose dispatcher");
break;
}
d->execute();
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/buffer/add.cc
^
|
@@ -5,7 +5,7 @@
set (b, len);
else {
if (! (buf_data = (char*)realloc (buf_data, buf_len + len)) )
- throw ((Error) "Memory fault in Buffer::add");
+ throw static_cast<Error>("Memory fault in Buffer::add");
memcpy (buf_data + buf_len, b, len);
buf_len += len;
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/buffer/copy.cc
^
|
@@ -6,7 +6,7 @@
buf_len = 0;
} else {
if (! (buf_data = (char*)malloc (other.buf_len)) )
- throw ((Error) "Memory fault in Buffer::copy");
+ throw static_cast<Error>("Memory fault in Buffer::copy");
memcpy (buf_data, other.buf_data, other.buf_len);
buf_len = other.buf_len;
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/buffer/insertat2.cc
^
|
@@ -4,7 +4,7 @@
if (index >= buf_len)
return;
if (! (buf_data = (char*)realloc (buf_data, buf_len + len)) )
- throw ((Error) "Memory fault in Buffer::insertat");
+ throw static_cast<Error>("Memory fault in Buffer::insertat");
memmove (buf_data + index + len,
buf_data + index,
buf_len - index);
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/buffer/set.cc
^
|
@@ -3,7 +3,7 @@
void Buffer::set (char const *b, unsigned len) {
destroy();
if (! (buf_data = (char*)malloc (len)) )
- throw ((Error) "Memory fault in Buffer::set");
+ throw static_cast<Error>("Memory fault in Buffer::set");
memcpy (buf_data, b, len);
buf_len = len;
}
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/checkupthread
^
|
-(directory)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/checkupthread/checkupthread
^
|
@@ -1,14 +0,0 @@
-#ifndef _CHECKUPTHREAD_
-#define _CHECKUPTHREAD_
-
-#include "../sys/sys"
-#include "../thread/thread"
-#include "../balancer/balancer"
-#include "../error/error"
-
-class Checkupthread: public Thread {
-public:
- void execute();
-};
-
-#endif
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/addallow.cc
^
|
@@ -3,6 +3,6 @@
void Config::addallow (string a) {
struct in_addr in;
if (!inet_aton (a.c_str(), &in))
- throw ((Error) "Bad allow-from specfier '" + a + "'");
+ throw static_cast<Error>("Bad allow-from specfier '") + a + "'";
allowlist.push_back (in);
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/adddeny.cc
^
|
@@ -3,6 +3,6 @@
void Config::adddeny (string d) {
struct in_addr in;
if (!inet_aton (d.c_str(), &in))
- throw ((Error) "Bad deny-from specfier '" + d + "'");
+ throw static_cast<Error>("Bad deny-from specfier '") + d + "'";
denylist.push_back (in);
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/config
^
|
@@ -44,6 +44,10 @@
string serverheader (unsigned n) { return (serverheaders[n]); }
unsigned nallow() const { return (allowlist.size()); }
unsigned ndeny() const { return (denylist.size()); }
+ bool fastclose() const { return (fast_close); }
+ void fastclose (bool f) { fast_close = f; }
+ int ipstoretimeout() const { return (ipstore_timeout); }
+ void ipstoretimeout(int t) { ipstore_timeout = t; }
struct in_addr allow(unsigned n) const {
return (allowlist[n]);
@@ -90,6 +94,8 @@
static vector<string> serverheaders;
static vector<struct in_addr> allowlist;
static vector<struct in_addr> denylist;
+ static bool fast_close;
+ static int ipstore_timeout;
};
extern Config config;
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/config1.cc
^
|
@@ -23,6 +23,8 @@
vector<string> Config::serverheaders;
vector<struct in_addr> Config::allowlist;
vector<struct in_addr> Config::denylist;
+bool Config::fast_close = false;
+int Config::ipstore_timeout;
Config::Config () {
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/parsecmdline.cc
^
|
@@ -13,7 +13,8 @@
}
// Not a single argument? Usage.
if (ac == 1)
- throw ((Error) "Bad command line '" + cmdline + "'\n" + USAGE);
+ throw static_cast<Error>("Bad command line '") +
+ cmdline + "'\n" + USAGE;
static struct option longopts[] = {
{ "allow-from", required_argument, 0, 'a' },
@@ -21,12 +22,14 @@
{ "backend", required_argument, 0, 'b' },
{ "buffer-size", required_argument, 0, 'B' },
{ "checkup-interval", required_argument, 0, 'c' },
+ { "close-sockets-fast", no_argument, 0, 'C' },
{ "debug", no_argument, 0, 'D' },
{ "dispatch-mode", required_argument, 0, 'd' },
{ "foreground", no_argument, 0, 'f' },
{ "help", no_argument, 0, 'h' },
{ "add-server-header", required_argument, 0, 'H' },
{ "max-connections", required_argument, 0, 'm' },
+ { "tryout", no_argument, 0, 'n' },
{ "prefix-timestamp", no_argument, 0, 'P' },
{ "pidfile", required_argument, 0, 'p' },
{ "server", required_argument, 0, 's' },
@@ -43,7 +46,9 @@
int opt;
bool backend_set = false;
- while ( (opt = getopt_long (ac, av, "?a:A:B:b:c:Dd:fhH:m:p:Ss:t:T:vVw:xX",
+ bool tryout = false;
+ while ( (opt = getopt_long (ac, av,
+ "?a:A:B:b:c:Dd:fhH:m:np:Ss:t:T:vVw:xX",
longopts, 0)) > 0) {
switch (opt) {
case 'a':
@@ -62,6 +67,9 @@
case 'c':
checkup = setinteger (optarg);
break;
+ case 'C':
+ fast_close = true;
+ break;
case 'D':
verbose_flag = true;
debug_flag = true;
@@ -73,7 +81,7 @@
foreground_mode = true;
break;
case 'h':
- throw ((Error) USAGE);
+ throw static_cast<Error>(USAGE);
break;
case 'H':
addserverheader (optarg);
@@ -81,6 +89,9 @@
case 'm':
max_conn = (unsigned)setinteger (optarg);
break;
+ case 'n':
+ tryout = true;
+ break;
case 'P':
prefix_timestamp = true;
break;
@@ -103,10 +114,13 @@
verbose_flag = true;
break;
case 'V':
- cout << "This is XR V" << VER << "\n"
- << "Written by: " << AUTHOR << "\n"
- << "Maintained by: " << MAINTAINER << "\n"
- << "Please report bugs to the maintainer.\n";
+ cout << "XR version : " << VER << "\n"
+ << "Written by : " << AUTHOR << "\n"
+ << "Maintained by : " << MAINTAINER << "\n"
+ << "Compiled with :\n"
+ << "C++ compiler : " << CONF_CC << "\n"
+ << "Libraries : " << CONF_LIB << "\n"
+ ;
exit (0);
case 'w':
wakeup = setinteger (optarg);
@@ -118,18 +132,23 @@
add_x_forwarded_for = true;
break;
default:
- throw ((Error) "Unknown flag, try 'xr -h' for usage");
+ throw static_cast<Error>("Unknown flag, try 'xr -h' for usage");
break;
}
}
if (ac != optind)
- throw ((Error) "Bad command line '" + cmdline + "'\n" + USAGE);
+ throw static_cast<Error>("Bad command line '") + cmdline + "'\n" +
+ USAGE;
if (!backend_set)
- throw ((Error)
- "No backend defined, use '-b...' at least once, "
- "or try 'xr -h' for usage");
+ throw static_cast<Error>
+ ("No backend defined, use '-b...' at least once, "
+ "or try 'xr -h' for usage");
+
+ // In tryout mode, stop now.
+ if (tryout)
+ exit (0);
msg ("+--------------------------------------------+\n");
msg ("| Welcome to xr V" VER " |\n");
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/setbackend.cc
^
|
@@ -11,8 +11,8 @@
if (str.length() > 0)
parts.push_back (str);
if (parts.size() < 2 || parts.size() > 3)
- throw((Error) "Bad back end specifier in '-b" + str +
- "', expected: SERVER:PORT or SERVER:PORT:MAXCONNECTIONS");
+ throw static_cast<Error>("Bad back end specifier in '-b") + str +
+ "', expected: SERVER:PORT or SERVER:PORT:MAXCONNECTIONS";
if (parts.size() == 2) {
BackendDef bd (parts[0], parts[1]);
blist.push_back (bd);
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/setdispatcmode.cc
^
|
@@ -1,23 +1,38 @@
#include "config"
void Config::setdispatchmode (string s) {
- if (s == "r" || s == "round-robin")
- dmode.mode (Dispatchmode::m_roundrobin);
- else if (s == "l" || s == "least-connections")
- dmode.mode (Dispatchmode::m_leastconn);
- else if (s == "f" || s == "first-available")
- dmode.mode (Dispatchmode::m_firstactive);
- else if (s.substr(0, 2) == "e:") {
+ if (s.substr(0, 2) == "e:") {
dmode.mode (Dispatchmode::m_external);
external_algorithm = s.substr (2);
} else if (s.substr (0, 9) == "external:") {
dmode.mode (Dispatchmode::m_external);
external_algorithm = s.substr(9);
- }
- else
- throw ((Error) "Bad dispatch mode -d" + s);
+ } else if (s == "f" || s == "first-available")
+ dmode.mode (Dispatchmode::m_firstactive);
+ else if (s == "h" || s == "strict-hashed-ip")
+ dmode.mode (Dispatchmode::m_strict_hashed_ip);
+ else if (s == "H" || s == "lax-hashed-ip")
+ dmode.mode (Dispatchmode::m_lax_hashed_ip);
+ else if (s == "l" || s == "least-connections")
+ dmode.mode (Dispatchmode::m_leastconn);
+ else if (s == "r" || s == "round-robin")
+ dmode.mode (Dispatchmode::m_roundrobin);
+ else if (s.substr(0, 2) == "s:") {
+ dmode.mode (Dispatchmode::m_strict_stored_ip);
+ ipstoretimeout(setinteger(s.substr(2)));
+ } else if (s.substr(0, 17) == "strict-stored-ip:") {
+ dmode.mode (Dispatchmode::m_strict_stored_ip);
+ ipstoretimeout(setinteger(s.substr(17)));
+ } else if (s.substr(0, 2) == "S:") {
+ dmode.mode (Dispatchmode::m_lax_stored_ip);
+ ipstoretimeout(setinteger(s.substr(2)));
+ } else if (s.substr(0, 14) == "lax-stored-ip:") {
+ dmode.mode (Dispatchmode::m_strict_stored_ip);
+ ipstoretimeout(setinteger(s.substr(14)));
+ } else
+ throw static_cast<Error>("Bad dispatch mode -d") + s;
if (dmode.mode() == Dispatchmode::m_external &&
external_algorithm.size() < 1)
- throw ((Error) "External algorithm handler missing");
+ throw static_cast<Error>("External algorithm handler missing");
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/setinteger.cc
^
|
@@ -3,7 +3,7 @@
int Config::setinteger (string s) const {
int ret;
if (sscanf (s.c_str(), "%d", &ret) < 1)
- throw ((Error) "Bad numeric specifier in '" + s +
- ": not a number");
+ throw static_cast<Error>("Bad numeric specifier in '") + s +
+ ": not a number";
return (ret);
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/config/setserver.cc
^
|
@@ -12,7 +12,8 @@
if (str.length() > 0)
parts.push_back (str);
if (parts.size() != 3)
- throw((Error) "Bad server specifier, expected: TYPE:IPADDRESS:PORT");
+ throw static_cast<Error>
+ ("Bad server specifier, expected: TYPE:IPADDRESS:PORT");
// Store type, IP and port
styp.type (parts[0]);
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/dispatchmode/dispatchmode
^
|
@@ -13,6 +13,10 @@
m_roundrobin,
m_firstactive,
m_external,
+ m_strict_hashed_ip,
+ m_lax_hashed_ip,
+ m_strict_stored_ip,
+ m_lax_stored_ip,
};
Dispatchmode() : mymode(m_leastconn) {
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/error/error
^
|
@@ -12,7 +12,7 @@
Error &operator+ (Error const &other);
Error &operator+ (string const s);
Error &operator+ (int i);
- string txt() const;
+ char const *what() const throw ();
private:
string desc;
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/error/txt.cc
^
|
@@ -1,10 +0,0 @@
-#include "error"
-#include "../config/config"
-
-string Error::txt() const {
- ostringstream o;
- if (config.prefixtimestamp())
- o << timestamp() << ' ';
- o << pthread_self() << " ERROR: " << desc;
- return (o.str());
-}
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/error/what.cc
^
|
@@ -0,0 +1,10 @@
+#include "error"
+#include "../config/config"
+
+char const *Error::what() const throw (){
+ ostringstream o;
+ if (config.prefixtimestamp())
+ o << timestamp() << ' ';
+ o << pthread_self() << " ERROR: " << desc;
+ return (o.str().c_str());
+}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/etc/Makefile.class
^
|
@@ -1,9 +1,12 @@
SRC = $(wildcard *.cc)
-OBJ = $(patsubst %.cc, ../$(BUILDDIR)/$(DIR)_%.o, $(SRC))
+OBJ = $(patsubst %.cc, $(BASE)/xr/$(BUILDDIR)/$(DIR)_%.o, $(SRC))
DIR = $(shell pwd | sed 's:.*/::')
class-compile: $(OBJ)
-../$(BUILDDIR)/$(DIR)_%.o: %.cc
+$(BASE)/xr/$(BUILDDIR)/$(DIR)_%.o: %.cc
$(CC) -DVER='"$(VER)"' -DAUTHOR='"$(AUTHOR)"' \
- -DMAINTAINER='"$(MAINTAINER)"' -c -g -Wall -o $@ $<
+ -DMAINTAINER='"$(MAINTAINER)"' \
+ -DCONF_CC='"$(CONF_CC)"' -DCONF_LIB='"$(CONF_LIB)"' \
+ -I$(BASE)/xr \
+ -c -g -Wall -o $@ $<
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/etc/usage.txt
^
|
@@ -12,6 +12,8 @@
defines the maximum connections for the back end.
-b SIZE, --buffer-size SIZE
Sets the network buffer size, default is 2048 (in bytes)
+ -C, --close-sockets-fast
+ Sockets are closed faster to avoid TIME_WAIT states.
-c SEC, --checkup-interval SEC
Defines the back end checking period. Each SEC seconds, every back end
is checked whether it is alive. Default is 0 (off).
@@ -19,10 +21,21 @@
Sets debugging on, more verbosity on top of -v
-d METHOD, --dispatch-mode METHOD
Defines how to dispatch over back ends, the method may be:
- r, round-robin - back ends take turns
- l, least-connections - back end with least TCP connections is taken
- f, first-active - first live back end gets all traffic
- e:EXT, external:EXT - external program EXT is queried
+ f, first-available - first live back end gets all traffic
+ e:EXT, external:EXT - external program EXT is queried
+ h, strict-hashed-ip - client IP is hashed to determine a back
+ end, client is denied when back end is down
+ H, lax-hashed-ip - client IP is hashed, fallback to least-
+ connections when target back end is down
+ l, least-connections - back end with least connections is taken
+ r, round-robin - back ends take turns
+ s:SEC, strict-stored-ip:SEC - if client connected before within SEC
+ seconds, then the same backend is used.
+ Client is denied if that backend is down.
+ Else a new is found by least-connections.
+ S:SEC, lax-stored-ip:SEC - same as strict-stored-ip, but falls back
+ to least-connections when a previously
+ used back end is down
Default method is l (least-connections). When external mode is selected,
program EXT is started with arguments <nbackends> <b0> <b0-availability>
<b0-connections> (b0 repeated for all back ends). Here <b0> is the back
@@ -39,6 +52,8 @@
-m MAX, --max-connections MAX
Sets the maximum number of connections to the balancer. Default is 0,
no maximum.
+ -n, --tryout
+ Validates all flags and stops; does not start the balancer.
-P, --prefix-timestamp
Messages (verbose, debug, error etc.) are prefixed with a time stamp.
-p FILE, --pidfile FILE
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/etc/xr-test
^
|
@@ -1,36 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use LWP::UserAgent;
-use Time::HiRes qw(sleep gettimeofday tv_interval);
-
-die ("Usage: $0 URL TRIALS\n") if ($#ARGV != 1);
-$|++;
-
-my $n = 0;
-my $totaltime = 0;
-
-my $ua = LWP::UserAgent->new();
-$ua->timeout(5);
-while ($n < $ARGV[1]) {
- my $success = 0;
- for my $i (1..10) {
- my $t0 = [ gettimeofday() ];
- my $resp = $ua->get($ARGV[0]);
- if ($resp->is_success()) {
- $success++;
- $n++;
- $totaltime += tv_interval ($t0);
- last;
- }
- if ($i == 3) {
- die ($resp->status_line(), "\n");
- }
- sleep (1);
- }
- sleep (0.1);
- printf ("\rN: %5d Tot:%8.3g Avg:%8.3g", $n, $totaltime, $totaltime / $n)
- if (! ($n % 50));
-}
-
-print ("\n");
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/external
^
|
-(directory)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/external/external
^
|
@@ -1,14 +0,0 @@
-#ifndef _EXTERNAL_
-#define _EXTERNAL_
-
-#include "../sys/sys"
-#include "../error/error"
-#include "../algorithm/algorithm"
-#include "../balancer/balancer"
-#include "../config/config"
-
-class External: public Algorithm {
- int target();
-};
-
-#endif
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/external/target.cc
^
|
@@ -1,33 +0,0 @@
-#include "external"
-
-int External::target() {
- // Prepare command to run
- ostringstream o;
- o << config.externalalgorithm() << ' ' << balancer.nbackends();
- for (unsigned i = 0; i < balancer.nbackends(); i++)
- o << ' ' << balancer.backend(i).description() << ' '
- << balancer.backend(i).availablestr()
- << ' ' << balancer.backend(i).connections();
- msg ("External algorithm: invoking '" + o.str() + "'\n");
-
- FILE *f;
- if (! (f = popen (o.str().c_str(), "r")) )
- throw ((Error) "Cannot start '" + o.str() + "': " + strerror(errno));
- int i;
- if (fscanf (f, "%d", &i) < 1)
- throw ((Error) "External algorithm '" + o.str() + "' did not reply "
- "with a number");
-
- ostringstream n;
- n << i;
- msg ("External algorithm says: " + n.str() + "\n");
-
- if (i < 0 || i >= (int)balancer.nbackends())
- throw ((Error) "External algorithm '" + o.str() + "': answer " +
- n.str() + " out of bounds");
- if (pclose (f))
- throw ((Error) "External algorithm '" + o.str() + "' terminated "
- "with error");
-
- return (i);
-}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/fdset/readable.cc
^
|
@@ -28,8 +28,9 @@
// the caller can handle them gracefully.
if (select (FD_SETSIZE, &readset, 0, &exceptset, tvp) < 0) {
if (errno != EINTR)
- throw ((Error) "Select failure: "
- "failed to wait for readable state: " + strerror(errno));
+ throw static_cast<Error>
+ ("Select failure: failed to wait for readable state: ") +
+ strerror(errno);
else
return (-1);
}
@@ -37,7 +38,7 @@
// Check for exceptions.
for (unsigned i = 0; i < set.size(); i++)
if (FD_ISSET (set[i], &exceptset))
- throw ((Error) "Exception on fd/socket " + set[i]);
+ throw static_cast<Error>("Exception on fd/socket ") + set[i];
// Check what's readable.
for (unsigned i = 0; i < set.size(); i++)
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/fdset/readwriteable.cc
^
|
@@ -27,13 +27,19 @@
tvp = 0;
// Run the select.
- if (select (FD_SETSIZE, &readset, &writeset, &exceptset, tvp) < 0)
- throw ((Error) "Select failure: failed to wait for rw state");
+ if (select (FD_SETSIZE, &readset, &writeset, &exceptset, tvp) < 0) {
+ if (errno != EINTR)
+ throw static_cast<Error>
+ ("Select failure: failed to wait for read/writeablestate: ")
+ + strerror(errno);
+ else
+ return (-1);
+ }
// Check for exceptions.
for (unsigned i = 0; i < set.size(); i++)
if (FD_ISSET (set[i], &exceptset))
- throw ((Error) "Exception on fd/socket " + set[i]);
+ throw static_cast<Error>("Exception on fd/socket ") + set[i];
// Check what's active.
for (unsigned i = 0; i < set.size(); i++)
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/fdset/writeable.cc
^
|
@@ -25,13 +25,19 @@
tvp = 0;
// Run the select.
- if (select (FD_SETSIZE, 0, &writeset, &exceptset, tvp) < 0)
- throw ((Error) "Select failure: failed to wait for writable state");
+ if (select (FD_SETSIZE, 0, &writeset, &exceptset, tvp) < 0) {
+ if (errno != EINTR)
+ throw static_cast<Error>
+ ("Select failure: failed to wait for writable state: ") +
+ strerror(errno);
+ else
+ return (-1);
+ }
// Check for exceptions.
for (unsigned i = 0; i < set.size(); i++)
if (FD_ISSET (set[i], &exceptset))
- throw ((Error) "Exception on fd/socket " + set[i]);
+ throw static_cast<Error>("Exception on fd/socket ") + set[i];
// Check what's writeable.
for (unsigned i = 0; i < set.size(); i++)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/firstactive
^
|
-(directory)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/firstactive/firstactive
^
|
@@ -1,13 +0,0 @@
-#ifndef _FIRSTACTIVE_
-#define _FIRSTACTIVE_
-
-#include "../sys/sys"
-#include "../error/error"
-#include "../algorithm/algorithm"
-#include "../balancer/balancer"
-
-class Firstactive: public Algorithm {
- int target();
-};
-
-#endif
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/firstactive/target.cc
^
|
@@ -1,9 +0,0 @@
-#include "firstactive"
-
-int Firstactive::target() {
- for (unsigned i = 0; i < balancer.nbackends(); i++)
- if (balancer.backend(i).available())
- return ( (int) i);
- throw ((Error) "First-active algorithm: no available back ends");
-}
-
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/httpdispatcher/dispatch.cc
^
|
@@ -5,7 +5,7 @@
// Get the client's request. May need for cookie inspection.
if (!getclientrequest())
- throw ((Error) "Didn't receive a valid client request.\n");
+ throw static_cast<Error>("Didn't receive a valid client request.\n");
// Dispatch as a normal backend if sticky HTTP is off, or if the
// sticky target is badly specified.
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/httpdispatcher/handle.cc
^
|
@@ -12,7 +12,8 @@
if (config.addxrversion())
clientrequest.setheader ("XR", VER);
if (config.addxforwardedfor())
- clientrequest.addheader ("X-Forwarded-For", clientip());
+ clientrequest.addheader ("X-Forwarded-For",
+ string(inet_ntoa(clientip())));
for (unsigned n = 0; n < config.nserverheaders(); n++)
clientrequest.addheader (config.serverheader(n));
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/httpdispatcher/httpdispatcher
^
|
@@ -7,7 +7,7 @@
class HttpDispatcher: public TcpDispatcher {
public:
- HttpDispatcher (int fd, string ip);
+ HttpDispatcher (int fd, struct in_addr ip);
void dispatch();
void handle();
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/httpdispatcher/httpdispatcher1.cc
^
|
@@ -1,5 +1,5 @@
#include "httpdispatcher"
-HttpDispatcher::HttpDispatcher (int fd, string ip) :
+HttpDispatcher::HttpDispatcher (int fd, struct in_addr ip) :
TcpDispatcher (fd, ip), clientrequest(), serverresponse() {
}
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/leastconn
^
|
-(directory)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/leastconn/leastconn
^
|
@@ -1,13 +0,0 @@
-#ifndef _LEASTCONN_
-#define _LEASTCONN_
-
-#include "../sys/sys"
-#include "../error/error"
-#include "../algorithm/algorithm"
-#include "../balancer/balancer"
-
-class Leastconn: public Algorithm {
- int target();
-};
-
-#endif
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/leastconn/target.cc
^
|
@@ -1,23 +0,0 @@
-#include "leastconn"
-
-int Leastconn::target() {
- bool found = false;
- unsigned nconn;
- int t;
-
- for (unsigned i = 0; i < balancer.nbackends(); i++) {
- if (!balancer.backend(i).available())
- continue;
- if (!found ||
- balancer.backend(i).connections() < nconn) {
- nconn = balancer.backend(i).connections();
- t = i;
- found = true;
- }
- }
-
- if (!found)
- throw ((Error) "Least-connections algorithm: "
- "no available back ends");
- return (t);
-}
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/roundrobin
^
|
-(directory)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/roundrobin/roundrobin
^
|
@@ -1,13 +0,0 @@
-#ifndef _ROUNDROBIN_
-#define _ROUNDROBIN_
-
-#include "../sys/sys"
-#include "../error/error"
-#include "../algorithm/algorithm"
-#include "../balancer/balancer"
-
-class Roundrobin: public Algorithm {
- int target();
-};
-
-#endif
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/roundrobin/target.cc
^
|
@@ -1,26 +0,0 @@
-#include "roundrobin"
-
-int Roundrobin::target() {
- static int last = -1;
- int t = last + 1;
-
- if (last == -1) {
- lock();
- last = 0;
- unlock();
- }
-
- while (1) {
- if (balancer.backend(t).available()) {
- lock();
- last = t;
- unlock();
- return (t);
- }
- t++;
- t %= balancer.nbackends();
- if (t == last)
- throw ((Error) "Round-robin algorithm: no available back ends");
- }
-}
-
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/servertype/type1.cc
^
|
@@ -6,6 +6,6 @@
else if (id == "http")
t = t_http;
else
- throw ((Error) "Bad server type '" + id +
- "', supported are 'tcp' or 'http'");
+ throw static_cast<Error>("Bad server type '") + id +
+ "', supported are 'tcp' or 'http'";
}
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/stopthread
^
|
-(directory)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/stopthread/execute.cc
^
|
@@ -1,30 +0,0 @@
-#include "stopthread"
-
-void Stopthread::execute() {
- static int stopping;
- static int last_connections;
- int loc_stopping;
-
- if ( (loc_stopping = stopping) ) {
- msg ("XR is waiting to shut down.\n");
- return;
- }
-
- lock();
- stopping++;
- unlock();
- msg ("XR will shut down.\n");
-
- while (1) {
- if (balancer.connections()) {
- ostringstream o;
- o << balancer.connections();
- msg ("There are still " + o.str() + " connections, "
- "XR will stop when they do.\n");
- sleep (1);
- continue;
- }
- msg ("No active connections, terminating XR.\n");
- exit (0);
- }
-}
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/stopthread/stopthread
^
|
@@ -1,13 +0,0 @@
-#ifndef _STOPTHREAD_
-#define _STOPTHREAD_
-
-#include "../sys/sys"
-#include "../thread/thread"
-#include "../balancer/balancer"
-
-class Stopthread: public Thread {
-public:
- void execute();
-};
-
-#endif
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/sys/main.cc
^
|
@@ -1,9 +1,8 @@
-#include "../sys/sys"
-#include "../config/config"
-#include "../balancer/balancer"
-#include "../error/error"
-#include "../stopthread/stopthread"
+#include "sys/sys"
+#include "config/config"
+#include "balancer/balancer"
+#include "error/error"
using namespace std;
@@ -17,11 +16,6 @@
balancer.terminate(true);
}
-static void out_of_memory() {
- cerr << "ERROR: Out of memory\n";
- exit (1);
-}
-
int main (int argc, char **argv) {
static int relevant_sig[] = {
SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGTERM, SIGSTOP, SIGPIPE
@@ -42,8 +36,8 @@
// Configure the balancer and start serving.
balancer.init();
balancer.serve();
- } catch (Error e) {
- cerr << e.txt() << endl;
+ } catch (Error const &e) {
+ cerr << e.what() << endl;
return (1);
} catch (...) {
cerr << "ERROR: Unidentified exception caught" << endl;
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/sys/serversocket.cc
^
|
@@ -6,12 +6,12 @@
// Create the server socket, set options
if ( (sock = socket (PF_INET, SOCK_STREAM, 0)) < 0 )
- throw ((Error) "Failed to create " + desc + " socket: " +
- strerror(errno));
+ throw static_cast<Error>("Failed to create ") + desc + " socket: " +
+ strerror(errno);
int val = 1;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)))
- throw ((Error) "Failed to set socket options for " + desc + ": " +
- strerror(errno));
+ throw static_cast<Error>("Failed to set socket options for ") +
+ desc + ": " + strerror(errno);
// Prepare binding
struct sockaddr_in saddr;
@@ -24,8 +24,8 @@
if (addr[0] != '0') {
msg ("Binding balancer to specific IP address " + addr + "\n");
if ( (saddr.sin_addr.s_addr = inet_addr (addr.c_str())) == INADDR_NONE )
- throw ((Error) "Cannot convert " + desc + " IP '" + addr +
- "' to network bytes");
+ throw static_cast<Error>("Cannot convert ") + desc + " IP '" +
+ addr + "' to network bytes";
display_ip << addr;
} else {
saddr.sin_addr.s_addr = htonl (INADDR_ANY);
@@ -35,14 +35,13 @@
// Bind and listen
if (bind (sock, (sockaddr*) &saddr, sizeof(saddr)) < 0)
- throw ((Error) "Failed to bind " + desc + " to " + display_ip.str() +
- ": " + strerror(errno));
+ throw static_cast<Error>("Failed to bind ") + desc + " to " +
+ display_ip.str() + ": " + strerror(errno);
if (listen (sock, 5) < 0)
- throw ((Error) "Failed to listen to " + desc + " IP " +
- display_ip.str() + ": " + strerror(errno));
+ throw static_cast<Error>("Failed to listen to ") + desc + " IP " +
+ display_ip.str() + ": " + strerror(errno);
msg ("TCP server for " + desc + " listening to " + display_ip.str() + "\n");
return (sock);
}
-
|
[-]
[+]
|
Added |
crossroads-devel.tar.gz/xr/sys/socketclose.cc
^
|
@@ -0,0 +1,12 @@
+#include "sys"
+#include "../config/config"
+
+void socketclose (int fd) {
+ if (config.fastclose()) {
+ struct linger l;
+ l.l_onoff = 1;
+ l.l_linger = 0;
+ setsockopt (fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
+ }
+ close (fd);
+}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/sys/sys
^
|
@@ -24,6 +24,7 @@
#include <sys/types.h>
// C++
+#include <exception>
#include <iostream>
#include <map>
#include <sstream>
@@ -38,7 +39,8 @@
void debugmsg (string const &s);
void reportmsg (string const &s);
int serversocket (string addr, int port, string description);
-string timestamp();
+string timestamp(time_t s = 0);
bool ipmatch (struct in_addr addr, struct in_addr mask);
+void socketclose (int fd);
#endif
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/sys/timestamp.cc
^
|
@@ -1,8 +1,14 @@
#include "sys"
-string timestamp() {
+string timestamp(time_t s) {
struct timeval tv;
- gettimeofday (&tv, 0);
+
+ if (! s)
+ gettimeofday (&tv, 0);
+ else {
+ tv.tv_sec = s;
+ tv.tv_usec = 0;
+ }
struct tm *tmp = localtime(&tv.tv_sec);
@@ -10,6 +16,6 @@
sprintf (buf, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d,%3.3d",
tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec,
- tv.tv_usec / 1000);
+ int(tv.tv_usec / 1000));
return (buf);
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/tcpdispatcher/dispatch.cc
^
|
@@ -5,7 +5,7 @@
bool connected = false;
while (!connected) {
- target_backend = algorithm->target();
+ target_backend = algorithm->target(clientip());
tb = balancer.backend(target_backend);
if (!tb.connect()) {
lock();
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/tcpdispatcher/execute.cc
^
|
@@ -7,9 +7,9 @@
try {
dispatch();
- } catch (Error e) {
- cerr << e.txt() << "\n";
- close (clientfd());
+ } catch (Error const &e) {
+ cerr << e.what() << "\n";
+ socketclose (clientfd());
return;
}
@@ -27,16 +27,16 @@
try {
handle();
- } catch (Error e) {
- cerr << e.txt() << "\n";
+ } catch (Error const &e) {
+ cerr << e.what() << "\n";
}
lock();
balancer.backend(target_backend).endconnection();
unlock();
- close (clientfd());
- close (backendfd());
+ socketclose (clientfd());
+ socketclose (backendfd());
msg ("Done dispatching client fd " + co.str() + " at " +
balancer.backend(target_backend).description() + "\n");
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/tcpdispatcher/readchunk.cc
^
|
@@ -3,9 +3,7 @@
unsigned TcpDispatcher::readchunk (int src) {
ssize_t nread = read (src, data_buf, config.buffersize());
if (nread < 0)
- throw ((Error) "Read failed on fd " + src);
-
- balancer.backend(targetbackend()).addbytes (databufsize());
+ throw static_cast<Error>("Read failed on fd ") + src;
if (config.debug() && nread) {
ostringstream o;
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/tcpdispatcher/tcpdispatcher
^
|
@@ -1,20 +1,24 @@
#ifndef _TCPDISPATCHER_
#define _TCPDISPATCHER_
-#include "../sys/sys"
-#include "../balancer/balancer"
-#include "../config/config"
-#include "../thread/thread"
-#include "../algorithm/algorithm"
-#include "../roundrobin/roundrobin"
-#include "../firstactive/firstactive"
-#include "../leastconn/leastconn"
-#include "../external/external"
+#include "sys/sys"
+#include "balancer/balancer"
+#include "config/config"
+#include "thread/thread"
+
+// Dispatching algorithm workers
+#include "DispatchAlgorithms/algorithm/algorithm"
+#include "DispatchAlgorithms/roundrobin/roundrobin"
+#include "DispatchAlgorithms/firstactive/firstactive"
+#include "DispatchAlgorithms/leastconn/leastconn"
+#include "DispatchAlgorithms/external/external"
+#include "DispatchAlgorithms/hashedip/hashedip"
+#include "DispatchAlgorithms/storedip/storedip"
class TcpDispatcher: public Thread {
public:
- TcpDispatcher (int fd, string ip);
+ TcpDispatcher (int fd, struct in_addr ip);
virtual ~TcpDispatcher();
virtual void execute();
@@ -24,7 +28,7 @@
int targetbackend() const { return target_backend; }
void targetbackend(int t) { target_backend = t; }
- string clientip() const { return client_ip; }
+ struct in_addr clientip() const { return client_ip; }
int clientfd() const { return client_fd; }
void clientfd(int c) { client_fd = c; }
int backendfd() const { return backend_fd; }
@@ -37,7 +41,7 @@
private:
string printable (char ch) const;
- string client_ip;
+ struct in_addr client_ip;
int target_backend, client_fd, backend_fd;
char *data_buf;
unsigned data_bufsz;
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/tcpdispatcher/tcpdispatcher1.cc
^
|
@@ -1,6 +1,6 @@
#include "tcpdispatcher"
-TcpDispatcher::TcpDispatcher(int cfd, string cip):
+TcpDispatcher::TcpDispatcher(int cfd, struct in_addr cip):
Thread(), client_ip(cip), target_backend(-1), client_fd(cfd),
backend_fd(-1), data_bufsz(0) {
@@ -12,14 +12,23 @@
case Dispatchmode::m_roundrobin:
algorithm = new Roundrobin;
break;
- case Dispatchmode::m_leastconn:
- algorithm = new Leastconn;
- break;
case Dispatchmode::m_firstactive:
algorithm = new Firstactive;
break;
case Dispatchmode::m_external:
algorithm = new External;
break;
+ case Dispatchmode::m_strict_hashed_ip:
+ case Dispatchmode::m_lax_hashed_ip:
+ algorithm = new HashedIp;
+ break;
+ case Dispatchmode::m_strict_stored_ip:
+ case Dispatchmode::m_lax_stored_ip:
+ algorithm = new StoredIp;
+ break;
+ case Dispatchmode::m_leastconn:
+ default:
+ algorithm = new Leastconn;
+ break;
}
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/tcpdispatcher/writechunk.cc
^
|
@@ -10,8 +10,10 @@
ssize_t nwritten = write (dst, (void*) (b + totwritten),
blen - totwritten);
if (nwritten < 1)
- throw ((Error) "Write failed");
+ throw static_cast<Error>("Write failed");
+ balancer.backend(targetbackend()).addbytes (nwritten);
+
if (config.debug()) {
ostringstream o;
o << "Sent " << nwritten << " bytes to fd " << dst << ": ";
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/thread/lock.cc
^
|
@@ -1,7 +1,13 @@
#include "thread"
void Thread::lock() {
- int res;
- if ( (res = pthread_mutex_lock (&thread_mutex)) )
- throw ((Error) "Failed to obtain mutex lock: " + strerror(res));
+ if (!initialized) {
+ if (int res = pthread_mutex_init (&thread_mutex, 0))
+ throw static_cast<Error>("Failed to initialize mutex: ") +
+ strerror(res);
+ initialized = true;
+ }
+ if (int res = pthread_mutex_lock (&thread_mutex))
+ throw static_cast<Error>("Failed to obtain mutex lock: ") +
+ strerror(res);
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/thread/start.cc
^
|
@@ -5,8 +5,8 @@
try {
t->execute();
- } catch (Error e) {
- cerr << e.txt() << "\n";
+ } catch (Error const &e) {
+ cerr << e.what() << "\n";
}
// Cleanups
@@ -26,9 +26,9 @@
int res;
if (pthread_attr_init (&attr))
- throw ((Error) "Cannot initialize thread attributes");
+ throw static_cast<Error>("Cannot initialize thread attributes");
if (pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED))
- throw ((Error) "Cannot set thread state as detached");
+ throw static_cast<Error>("Cannot set thread state as detached");
for (int i = 0; i < 3; i++) {
res = pthread_create (&th, &attr, _run, (void*) this);
if (!res) {
@@ -41,11 +41,13 @@
continue;
} else {
pthread_attr_destroy (&attr);
- throw ((Error) "Failed to start thread: " + strerror(res));
+ throw static_cast<Error>("Failed to start thread: ") +
+ strerror(res);
}
}
- throw ((Error) "Failed to start thread: "
- "Resources unavailable after 3 tries, giving up");
+ throw static_cast<Error>("Failed to start thread: "
+ "Resources unavailable after 3 tries, "
+ "giving up");
}
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/thread/thread
^
|
@@ -16,7 +16,8 @@
void unlock();
virtual void execute();
private:
- pthread_mutex_t thread_mutex;
+ static pthread_mutex_t thread_mutex;
+ static bool initialized;
};
#endif
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/thread/thread1.cc
^
|
@@ -1,8 +1,6 @@
#include "thread"
+pthread_mutex_t Thread::thread_mutex;
+bool Thread::initialized = false;
Thread::Thread() {
- int res;
-
- if ( (res = pthread_mutex_init (&thread_mutex, 0)) )
- throw ((Error) "Failed to initialize mutex: " + strerror(res));
}
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xr/thread/unlock.cc
^
|
@@ -1,7 +1,7 @@
#include "thread"
void Thread::unlock() {
- int res;
- if ( (res = pthread_mutex_unlock (&thread_mutex)) )
- throw ((Error) "Failed to release mutex lock: " + strerror(res));
+ if (int res = pthread_mutex_unlock (&thread_mutex))
+ throw static_cast<Error>("Failed to release mutex lock: ") +
+ strerror(res);
}
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/wakeupthread
^
|
-(directory)
|
[-]
[+]
|
Deleted |
crossroads-devel.tar.gz/xr/wakeupthread/wakeupthread
^
|
@@ -1,14 +0,0 @@
-#ifndef _WAKEUPTHREAD_
-#define _WAKEUPTHREAD_
-
-#include "../sys/sys"
-#include "../thread/thread"
-#include "../balancer/balancer"
-#include "../error/error"
-
-class Wakeupthread: public Thread {
-public:
- void execute();
-};
-
-#endif
|
[-]
[+]
|
Changed |
crossroads-devel.tar.gz/xrctl/xrctl
^
|
@@ -37,24 +37,6 @@
my %services =
(
- # Basically just a port forwarder to localhost:80. I use it for
- # benchmarking.
- 'fwd1' =>
- { '--server' => [ qw(tcp:0:10000) ],
- '--backend' => [ qw(localhost:80) ],
- # '--verbose' => undef,
- # '--debug' => undef,
- },
-
- # Same thing, but a HTTP forwarder that adds X-Forwarded-For headers.
- # I use it for benchmarking HTTP handling.
- 'fwd2' =>
- { '--server' => [ qw(http:0:10001) ],
- '--backend' => [ qw(localhost:80) ],
- # '--verbose' => undef,
- },
-
-
# Web servers balancing to 3 back ends at 10.0.0.1 thru 3. The
# balancer will use HTTP mode and add X-Forwarded-For headers.
'webone' =>
@@ -78,7 +60,8 @@
# An Access Control List (ACL) example, again using web balancing.
# Allowed clients are 127.0.0.1 (localhost) and 192.168.*.*, except
- # for 192.168.1.250.
+ # for 192.168.1.250. Also, flag -C / --close-sockets-fast is added to
+ # avoid TIME_WAIT states under heavy load.
'webthree' =>
{ '--server' => [ qw(http:0:82) ],
'--backend' => [ qw(10.1.1.1:80 10.1.1.2:80 10.1.1.3:80) ],
@@ -86,9 +69,9 @@
'--add-x-forwarded-for' => undef,
'--allow-from' => [ qw(127.0.0.1 192.168.255.255) ],
'--deny-from' => [ qw(192.168.1.250) ],
+ '--close-sockets-fast' => undef,
},
-
# An SSH session balancer on port 2222. We set the client time out
# to 2 hours. Requests are balanced to server1, server2 and server3,
# all to port 22.
@@ -113,14 +96,14 @@
# in, this reaches some proxy - or localhost:3128, which is a local squid.
# I configure my browser to use localhost:8080 as proxy, and don't have
# to reconfigure browsers anymore. Note the dispatch method which is
- # first-active, the first downstream proxy that works is OK for me.
+ # first-available, the first downstream proxy that works is OK for me.
# Note also that the server type is TCP, I don't need HTTP goodies.
# Also the server listens to 127.0.0.1 - only for localhost usage.
'proxy' =>
{ '--server' => [ qw(tcp:127.0.0.1:8080) ],
'--backend' => [ qw(10.120.114.2:8080 192.168.1.250:80
localhost:3128) ],
- '--dispatch-mode' => [ qw(first-active) ],
+ '--dispatch-mode' => [ qw(first-available) ],
'--verbose' => undef,
},
@@ -154,6 +137,9 @@
}
}
+# Verify the configuration
+verifyconf (@ARGV);
+
# Take appropriate action
if ($action eq 'list') {
list(@ARGV);
@@ -325,6 +311,23 @@
}
}
}
+
+# Verify a configuration
+# ----------------------
+sub verifyconf {
+ for my $s (@_) {
+ my @p = xrcommand($s);
+ my $cmd = "$p[0] -n";
+ for my $i (2..$#p) {
+ $cmd .= " '$p[$i]'";
+ }
+ if (system ($cmd)) {
+ die ("xrctl: Configuration of service '$s' probably bad\n",
+ "Testing command was:\n",
+ " $cmd\n");
+ }
+ }
+}
# Get the status of one balancer service
# --------------------------------------
|