crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs | LICENSE

commit 42b59853f31cfc5a45104fc891507377a0a85de2
parent a9e440801e66c92ffbdf8cc7362fc0af36d32345
Author: finwo <finwo@pm.me>
Date:   Sat,  3 Jan 2026 19:35:59 +0100

2.16

Diffstat:
MChangeLog | 8++++++++
MMakefile | 2+-
Mdoc/xr.odt | 0
Mdoc/xr.pdf | 0
Mxr/config/config | 25+++++++++++++++++--------
Mxr/config/config1.cc | 8++++----
Mxr/config/parsecmdline.cc | 2+-
Mxr/etc/status.xslt | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mxr/etc/usage.txt | 5+++--
Mxr/sys/fdwrite.cc | 10++++++----
Mxr/sys/sys | 1+
Axr/sys/warnmsg.cc | 12++++++++++++
Mxr/webinterface/answer.cc | 99++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mxr/webinterface/answerstatus.cc | 5+++++
14 files changed, 253 insertions(+), 36 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,11 @@ +2.16 +- Enhanced web interface to show debug, verbose and traffic log states +- Altering parameters for the web interface get sent in encoded form +- Option --log-traffic was renamed to --log-traffic-dir for + consistency +- Enhanced web interface to modify client and back end timeouts +- Enhanced web interface to modify wakeup / checkup intervals. + 2.15 - Sanity checks in Config::parsecmdline(): -w/-c together throws error. - Network sends are now using write(), unless under Solaris, which diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ # Top-level Makefile for XR # ------------------------- -VER = 2.15 +VER = 2.16 BINDIR = /usr/sbin TAR = /tmp/crossroads-$(VER).tar.gz AUTHOR = Karel Kubat <karel@kubat.nl> diff --git a/doc/xr.odt b/doc/xr.odt Binary files differ. diff --git a/doc/xr.pdf b/doc/xr.pdf Binary files differ. diff --git a/xr/config/config b/xr/config/config @@ -19,7 +19,10 @@ public: // Accessors bool verbose() const { return (verbose_flag); } + void verbose (bool v) { verbose_flag = v; } + bool debug() const { return (debug_flag); } + void debug (bool d) { debug_flag = d; } Servertype::Type stype() const { return (styp.type()); } string stypestr() const { return (styp.typestr()); } @@ -28,11 +31,17 @@ public: int backends() const { return (blist.size()); } - int client_timeout() const { return (c_timeout); } - int backend_timeout() const { return (b_timeout); } + unsigned client_timeout() const { return (c_timeout); } + void client_timeout (unsigned c) { c_timeout = c; } + + unsigned backend_timeout() const { return (b_timeout); } + void backend_timeout (unsigned b) { b_timeout = b; } + + unsigned wakeupsec() const { return (wakeup); } + void wakeupsec (unsigned w) { wakeup = w; } - int wakeupsec() const { return (wakeup); } - int checkupsec() const { return (checkup); } + unsigned checkupsec() const { return (checkup); } + void checkupsec (unsigned w) { checkup = w; } unsigned buffersize() const { return (bufsize); } void buffersize (unsigned b); @@ -111,10 +120,10 @@ private: static string sip; static vector<BackendDef> blist; static Dispatchmode dmode; - static int c_timeout; - static int b_timeout; - static int wakeup; - static int checkup; + static unsigned c_timeout; + static unsigned b_timeout; + static unsigned wakeup; + static unsigned checkup; static unsigned bufsize; static bool foreground_mode; static bool add_xr_version; diff --git a/xr/config/config1.cc b/xr/config/config1.cc @@ -6,10 +6,10 @@ Servertype Config::styp; string Config::sip = "0"; vector<BackendDef> Config::blist; Dispatchmode Config::dmode; -int Config::c_timeout = 30; -int Config::b_timeout = 30; -int Config::wakeup = 5; -int Config::checkup = 0; +unsigned Config::c_timeout = 30; +unsigned Config::b_timeout = 30; +unsigned Config::wakeup = 5; +unsigned Config::checkup = 0; unsigned Config::bufsize = 2048; bool Config::foreground_mode = false; bool Config::add_xr_version = false; diff --git a/xr/config/parsecmdline.cc b/xr/config/parsecmdline.cc @@ -30,7 +30,7 @@ void Config::parsecmdline (int ac, char **av) { { "foreground", no_argument, 0, 'f' }, { "help", no_argument, 0, 'h' }, { "add-server-header", required_argument, 0, 'H' }, - { "log-traffic", required_argument, 0, 'l' }, + { "log-traffic-dir", required_argument, 0, 'l' }, { "max-connections", required_argument, 0, 'm' }, { "host-match", required_argument, 0, 'M' }, { "tryout", no_argument, 0, 'n' }, diff --git a/xr/etc/status.xslt b/xr/etc/status.xslt @@ -40,7 +40,9 @@ if (el) { var value = el.value; if (value != "") - document.location = uri + value; + document.location = uri + encodeURIComponent(value); + else + document.location = uri; } } } @@ -71,41 +73,125 @@ <td colspan="3"> <xsl:value-of select="type"/> </td> </tr> <tr> - <td>Timeouts</td> - <td>client: <xsl:value-of select="clienttimeout"/></td> - <td colspan="2">backend: <xsl:value-of select="backendtimeout"/></td> - </tr> + <td>Dispatch mode</td> + <td colspan="3"> <xsl:value-of select="dispatchmode"/> </td> + </tr> <tr> <td>Checks</td> - <td>wakeups</td> - <td colspan="2"> + <td>Wakeup interval</td> + <td> <xsl:choose> <xsl:when test="checks/wakeupinterval = 0"> off </xsl:when> <xsl:otherwise> - each <xsl:value-of select="checks/wakeupinterval"/> sec. + sec </xsl:otherwise> </xsl:choose> </td> + <td> + <input type="text" size="8" name="wakeupinterval" + id="wakeupinterval" value="{checks/wakeupinterval}" + onchange="goto('/server/wakeupinterval/', 'wakeupinterval');"/> + </td> </tr> <tr> <td></td> - <td>checkups</td> - <td colspan="2"> + <td>Checkup interval</td> + <td> <xsl:choose> <xsl:when test="checks/checkupinterval = 0"> off </xsl:when> <xsl:otherwise> - each <xsl:value-of select="checks/checkupinterval"/> sec. + sec </xsl:otherwise> </xsl:choose> </td> + <td> + <input type="text" size="8" name="checkupinterval" + id="checkupinterval" value="{checks/checkupinterval}" + onchange="goto('/server/checkupinterval/', 'checkupinterval');"/> + </td> </tr> <tr> - <td>Dispatch mode</td> - <td colspan="3"> <xsl:value-of select="dispatchmode"/> </td> + <td>Timeouts</td> + <td>Client</td> + <td> + <xsl:choose> + <xsl:when test="clienttimeout = 0"> + unlimited + </xsl:when> + <xsl:otherwise> + sec + </xsl:otherwise> + </xsl:choose> + </td> + <td> + <input type="text" size="8" name="clienttimeout" + id="clienttimeout" value="{clienttimeout}" + onchange="goto('/server/clienttimeout/', 'clienttimeout');"/> + </td> + </tr> + <tr> + <td></td> + <td>Backend</td> + <td> + <xsl:choose> + <xsl:when test="backendtimeout = 0"> + unlimited + </xsl:when> + <xsl:otherwise> + sec + </xsl:otherwise> + </xsl:choose> + </td> + <td> + <input type="text" size="8" name="backendtimeout" + id="backendtimeout" value="{backendtimeout}" + onchange="goto('/server/backendtimeout/', 'backendtimeout');"/> + </td> + </tr> + <tr> + <td>Debugging</td> + <td colspan="2">Verbose logging</td> + <td> + <xsl:choose> + <xsl:when test="debugging/verbose = 0"> + <input type="text" size="8" name="verbose" id="verbose" value="off" + onchange="goto('/server/verbose/', 'verbose');"/> + </xsl:when> + <xsl:otherwise> + <input type="text" size="8" name="verbose" id="verbose" value="on" + onchange="goto('/server/verbose/', 'verbose');"/> + </xsl:otherwise> + </xsl:choose> + </td> + </tr> + <tr> + <td></td> + <td colspan="2">Debug logging</td> + <td> + <xsl:choose> + <xsl:when test="debugging/debug = 0"> + <input type="text" size="8" name="debug" id="debug" value="off" + onchange="goto('/server/debug/', 'debug');"/> + </xsl:when> + <xsl:otherwise> + <input type="text" size="8" name="debug" id="debug" value="on" + onchange="goto('/server/debug/', 'debug');"/> + </xsl:otherwise> + </xsl:choose> + </td> + </tr> + <tr> + <td></td> + <td colspan="2">Traffic log directory</td> + <td> + <input type="text" size="8" name="logtrafficdir" id="logtrafficdir" + value="{debugging/logtrafficdir}" + onchange="goto('/server/logtrafficdir/', 'logtrafficdir');"/> + </td> </tr> <tr> <td>Network buffer size</td> diff --git a/xr/etc/usage.txt b/xr/etc/usage.txt @@ -52,8 +52,9 @@ may not exist on your platform): This text. -H HDR, --add-server-header HDR Inserts HDR into back end bound HTTP messages. - -l DIR, --log-traffic DIR - Log passing traffic with dumps in DIR. Only for debugging, very slow! + -l DIR, --log-traffic-dir DIR + Log passing traffic with dumps in DIR. Only for debugging, slows + down the balancer. -m MAX, --max-connections MAX Sets the maximum number of connections to the balancer. Default is 0, no maximum. diff --git a/xr/sys/fdwrite.cc b/xr/sys/fdwrite.cc @@ -17,10 +17,12 @@ void fdwrite (int fd, int timeout, char const *buf, unsigned buflen) { FILE *f; if ( (!(f = fopen (of.str().c_str(), "a"))) && (!(f = fopen (of.str().c_str(), "w"))) ) - throw static_cast<Error>("Cannot write traffic log ") + - of.str() + ": " + strerror(errno); - fwrite (buf, 1, buflen, f); - fclose (f); + warnmsg ("Cannot write traffic log " + of.str() + ": " + + strerror(errno) + "\n"); + else { + fwrite (buf, 1, buflen, f); + fclose (f); + } } // Send to the socket diff --git a/xr/sys/sys b/xr/sys/sys @@ -53,6 +53,7 @@ bool ipmatch (struct in_addr addr, struct in_addr mask); void socketclose (int fd); vector<string> str2parts (string const &s, char sep); void fdwrite (int fd, int timeout, char const *buf, unsigned buflen); +void warnmsg (string const &s); #ifndef HAVE_INET_ATON int inet_aton (char const *name, struct in_addr *addr); diff --git a/xr/sys/warnmsg.cc b/xr/sys/warnmsg.cc @@ -0,0 +1,12 @@ +#include "sys" +#include "config/config" +#include "ThreadsAndMutexes/mutex/mutex" + +void warnmsg (string const &s) { + Mutex::lock(&cerr); + if (config.prefixtimestamp()) + cerr << timestamp() << ' '; + cerr << pthread_self() << " WARNING: " << s; + cerr.flush(); + Mutex::unlock(&cerr); +} diff --git a/xr/webinterface/answer.cc b/xr/webinterface/answer.cc @@ -55,6 +55,8 @@ string decode (string const &s) { }else { ret += '%'; } + } else if (*cp == '+') { + ret += ' '; } else { ret += *cp; cp++; @@ -99,10 +101,13 @@ void Webinterface::answer(Httpbuffer req) { return; } + // /server/maxconnections/ // /server/maxconnections/NUMBER - if (parts.size() == 3 && - parts[0] == "server" && parts[1] == "maxconnections") { - unsigned num = str2uns (parts[2], "server weight"); + if ( (parts.size() == 2 || parts.size() == 3) && + (parts[0] == "server" && parts[1] == "maxconnections") ) { + unsigned num = 0; + if (parts.size() == 3) + num = str2uns (parts[2], "server weight"); config.maxconn(num); answer_status(); return; @@ -154,6 +159,94 @@ void Webinterface::answer(Httpbuffer req) { return; } + // /server/verbose + // /server/verbose/VALUE + if ( (parts.size() == 2 || parts.size() == 3) && + (parts[0] == "server" && parts[1] == "verbose") ) { + if (parts.size() == 2 || parts[2] == "off" || parts[2] == "0") + config.verbose(false); + else + config.verbose(true); + answer_status(); + return; + } + + // /server/debug + // /server/debug/VALUE + if ( (parts.size() == 2 || parts.size() == 3) && + (parts[0] == "server" && parts[1] == "debug") ) { + if (parts.size() == 2 || parts[2] == "off" || parts[2] == "0") + config.debug(false); + else + config.debug(true); + answer_status(); + return; + } + + // /server/logtrafficdir + // /server/logtrafficdir/VALUE + if ( (parts.size() == 2 || parts.size() == 3) && + (parts[0] == "server" && parts[1] == "logtrafficdir") ) { + if (parts.size() == 2) + config.dumpdir(""); + else + config.dumpdir(parts[2]); + answer_status(); + return; + } + + // /server/clienttimeout + // /server/clienttimeout/NUMBER + if ( (parts.size() == 2 || parts.size() == 3) && + (parts[0] == "server" && parts[1] == "clienttimeout") ) { + unsigned num = 0; + if (parts.size() == 3) + num = str2uns (parts[2], "client timeout"); + config.client_timeout(num); + answer_status(); + return; + } + + // /server/backendtimeout + // /server/backendtimeout/NUMBER + if ( (parts.size() == 2 || parts.size() == 3) && + (parts[0] == "server" && parts[1] == "backendtimeout") ) { + unsigned num = 0; + if (parts.size() == 3) + num = str2uns (parts[2], "client timeout"); + config.backend_timeout(num); + answer_status(); + return; + } + + // /server/wakeupinterval + // /server/wakeupinterval/NUMBER + if ( (parts.size() == 2 || parts.size() == 3) && + (parts[0] == "server" && parts[1] == "wakeupinterval") ) { + unsigned num = 0; + if (parts.size() == 3) + num = str2uns (parts[2], "wakeup interval"); + if (num) + config.checkupsec(0); + config.wakeupsec(num); + answer_status(); + return; + } + + // /server/checkupinterval + // /server/checkupinterval/NUMBER + if ( (parts.size() == 2 || parts.size() == 3) && + (parts[0] == "server" && parts[1] == "checkupinterval") ) { + unsigned num = 0; + if (parts.size() == 3) + num = str2uns (parts[2], "checkup interval"); + if (num) + config.wakeupsec(0); + config.checkupsec(num); + answer_status(); + return; + } + // /backend/NR/weight/NUMBER if (parts.size() == 4 && parts[0] == "backend" && parts[2] == "weight") { diff --git a/xr/webinterface/answerstatus.cc b/xr/webinterface/answerstatus.cc @@ -23,6 +23,11 @@ void Webinterface::answer_status() { " <wakeupinterval>" << config.wakeupsec() << "</wakeupinterval>\n" " <checkupinterval>" << config.checkupsec() << "</checkupinterval>\n" " </checks>\n" + " <debugging>\n" + " <verbose>" << config.verbose() << "</verbose>\n" + " <debug>" << config.debug() << "</debug>\n" + " <logtrafficdir>" << config.dumpdir() << "</logtrafficdir>\n" + " </debugging>\n" " <http>\n" " <addxrversion>" << config.addxrversion() << "</addxrversion>\n" " <addxforwardedfor>" << config.addxforwardedfor() << "</addxforwardedfor>\n"