I have a service with a custom protocol that I'm load balancing and I
didn't find an easy way to get that going with ldirectord. I came up
with a quick modification that enabled what I needed, but would
appreciate comments or, ideally including similar functionality in
future releases.
It's a new service type called simpletcp, and is configured like so:
virtual = 192.168.44.3:10301
protocol = tcp
scheduler = wlc
real = 192.168.45.4:10301 gate 100
real = 192.168.45.5:10301 gate 100
service = simpletcp
request = "command\narg\n.\n"
receive = "^\+OK"
The check simply sends the request string down the connection and tests
against the receive regex. My perl-foo is weak these days, so I'm sure
there are some easy improvements that could be made.
Aaron
===== CUT =====
--- /usr/sbin/ldirectord 2007-08-10 06:15:50.000000000 -0600
+++ ldirectord 2007-09-13 09:30:20.000000000 -0600
@@ -1222,7 +1222,8 @@
$1 eq "radius"||
$1 eq "pgsql" ||
$1 eq "sip" ||
- $1 eq "smtp")
+ $1 eq "smtp" ||
+ $1 eq "simpletcp")
or &config_error($line,
"service must " .
"be dns, ftp, " .
@@ -2220,6 +2221,8 @@
$$r{num_connects} = 0 if
(check_pgsql($v, $r) == $SERVICE_UP);
} elsif ($$v{service} eq "oracle") {
$$r{num_connects} = 0 if
(check_oracle($v, $r) == $SERVICE_UP);
+ } elsif ($$v{service} eq "simpletcp") {
+ $$r{num_connects} = 0 if
(check_simpletcp($v, $r) == $SERVICE_UP);
} else {
$$r{num_connects} = 0 if
(check_none($v, $r) == $SERVICE_UP);
}
@@ -2907,6 +2910,73 @@
}
+sub check_simpletcp
+{
+ my ($v, $r) = @_;
+ my $d_port = ld_checkport($v, $r);
+
+ &ld_debug(2, "Checking simpletcp server=$$r{server} port=$d_port");
+
+ eval {
+ use Socket;
+
+ local $SIG{'__DIE__'} = "DEFAULT";
+ local $SIG{'ALRM'} = sub { die "Timeout Alarm" };
+ &ld_debug(4, "Timeout is $$v{checktimeout}");
+ alarm $$v{negotiatetimeout};
+
+ my $sock = &ld_open_socket($$r{server}, $d_port,
+ $$v{protocol});
+ unless ($sock) {
+ alarm 0;
+ die("Socket Connect Failed");
+ }
+
+ my $s_sockaddr = getsockname($sock);
+ my ($s_port, $s_addr) = sockaddr_in($s_sockaddr);
+ my $s_addr_str = inet_ntoa($s_addr);
+
+ &ld_debug(3, "Connected from $s_addr_str:$s_port to " .
+ $$r{server} . ":$d_port");
+
+ select $sock;
+ $|=1;
+ select STDOUT;
+
+ my $request = $$r{request};
+ $request =~ s/\\n/\n/g ;
+
+ &ld_debug(2, "Checking simpletcp server=$$r{server}
port=$d_port request:\n$request");
+ print $sock $request;
+
+ my $ok;
+ my $reply;
+ while (<$sock>) {
+ &ld_debug(2, "Checking simpletcp server=$$r{server}
port=$d_port receive=" . $$r{receive} ." got: $_\n");
+ if ( $_ =~ /$$r{receive}/ ) {
+ $ok = 1;
+ last;
+ }
+ }
+ alarm 0; # Cancel the alarm
+ close($sock);
+
+ if (!defined $ok) {
+ die "No OK\n";
+ }
+ };
+
+ if ($@) {
+ &service_set($v, $r, "down");
+ &ld_debug(3, "Deactivated service $$r{server}:$$r{port}: $@");
+ return $SERVICE_DOWN;
+ } else {
+ &service_set($v, $r, "up");
+ &ld_debug(3, "Activated service $$r{server}:$$r{port}");
+ return $SERVICE_UP;
+ }
+}
+
sub check_ftp
{
require Net::FTP;
===== CUT =====
|