keepalived-0.7.6 v0.7.6
authorAlexandre Cassen <acassen@freebox.fr>
Wed, 20 Nov 2002 23:06:48 +0000 (00:06 +0100)
committerAlexandre Cassen <acassen@freebox.fr>
Mon, 28 Sep 2009 08:58:57 +0000 (10:58 +0200)
* keepalived-0.7.6 released.
* Created a common library for code modularization. This lib will
  be used by all Keepalived components (genhash + Keepalived) to
  reduce repeated and duplicated code.
* Rewrote the genhash utility using the common lib. The design is
  similar to Keepalived core design.
* Reviewed the autoconf and Makefiles for new code architecture.
* Created a html utility lib for HTTP headers manipulations.
* Extended the CHECK_HTTP and CHECK_SSL checkers to support remote
  webserver HTTP header status_code. HTTP status_code is parsed
  according to rfc2616.6.1. The keyword created for the new feature is
  "status_code" inside and "url" declaration. "status_code" feature
  can be mixed with "digest" feature. See the samples directory
  keepalived/samples/keepalived.conf.status_code for example.
* Review the CHECK_HTTP and CHECK_SSL MD5SUM code to use a common
  stream handling function.
* Matthijs van der Klip, <Matthijs.van.der.Klip@tech.omroep.nl> and I
  fixed a bug into the HTTP/SSL code that close the socket fd even
  if remote webserver has not been connected. As a result of fact,
  next socket created were imediatly closed. As a side effect, this
  altered the SMTP notification when remote webserver checked fall. No
  SMTP notification were sent if webserver were detected DOWN. Thanks
  to Matthijs for time debugging and investigation.
* VRRP : Rewrote the previous Gratuitous ARP facility. Created a lib
  (vrrp_arp.c) dealing with PF_PACKET-SOCK_RAW-ETH_P_RARP and
  sockaddr_ll.
* VRRP : Some cosmetics patch for messages logging.
* VRRP : Fixed an issue during VRRP packet building, appending VRRP
  VIPs to the VRRP packet in the network order form.
* VRRP : Reviewed the previous VRRP packet building process to not
  create the ARP header. Removec the previous hacky
  PF_PACKET-SOCK_PACKET-0x300 to use AF_INET-SOCK_RAW-PROTO to leave
  kernel appending ARP header since code doesn t currently support
  VRRP VMAC.
* VRRP : Rewrote the previous vrrp_send_pkt() function to deal with
  sendmsg(). optimization lazzyness :)
* VRRP : Extended the interfaces library to support common utility
  functions (if_setsockopt_hdrincl, if_setsockopt_bindtodevice, ...)
* VRRP : Finally extend the code to support VRRP IPSEC-AH authentication
  method. Created a IPSEC-AH seq_number syncrhonization mecanism during
  VRRP MASTER/BACKUP elections.
* VRRP : Extended the VRRP TSM to speed up instances syncrhonization
  during FAULT->BACKUP & FAULT->MASTER state transition.
* Some cosmetics patches. This release is proposed as a 1.0.0 STABLE
  release candidate.

102 files changed:
ChangeLog
Makefile.in
VERSION
configure
configure.in
genhash/AUTHOR [new file with mode: 0644]
genhash/AUTHORS [deleted file]
genhash/ChangeLog
genhash/INSTALL
genhash/Makefile.in
genhash/TODO [deleted file]
genhash/VERSION [new file with mode: 0644]
genhash/client.c [deleted file]
genhash/client.h [deleted file]
genhash/common.c [deleted file]
genhash/common.h [deleted file]
genhash/http.c [new file with mode: 0644]
genhash/http.h [new file with mode: 0644]
genhash/layer4.c [new file with mode: 0644]
genhash/layer4.h [new file with mode: 0644]
genhash/main.c
genhash/main.h
genhash/sock.c [new file with mode: 0644]
genhash/sock.h [new file with mode: 0644]
genhash/ssl.c [new file with mode: 0644]
genhash/ssl.crt [deleted file]
genhash/ssl.csr [deleted file]
genhash/ssl.h [new file with mode: 0644]
genhash/ssl.key [deleted file]
genhash/ssl.pem [deleted file]
keepalived.spec
keepalived/Makefile.in
keepalived/core/Makefile.in
keepalived/core/daemon.c
keepalived/core/data.c
keepalived/core/layer4.c
keepalived/core/main.c
keepalived/core/parser.c
keepalived/core/pidfile.c
keepalived/core/smtp.c
keepalived/healthcheck/Makefile.in
keepalived/healthcheck/check_api.c
keepalived/healthcheck/check_ci.c
keepalived/healthcheck/check_http.c
keepalived/healthcheck/check_misc.c
keepalived/healthcheck/check_ssl.c
keepalived/healthcheck/check_tcp.c
keepalived/healthcheck/ipfwwrapper.c
keepalived/healthcheck/ipvswrapper.c
keepalived/healthcheck/ipwrapper.c
keepalived/include/check_api.h
keepalived/include/check_ci.h
keepalived/include/check_http.h
keepalived/include/check_misc.h
keepalived/include/check_ssl.h
keepalived/include/check_tcp.h
keepalived/include/daemon.h
keepalived/include/data.h
keepalived/include/ipfwwrapper.h
keepalived/include/ipvswrapper.h
keepalived/include/ipwrapper.h
keepalived/include/layer4.h
keepalived/include/main.h
keepalived/include/parser.h
keepalived/include/pidfile.h
keepalived/include/smtp.h
keepalived/include/vrrp.h
keepalived/include/vrrp_arp.h [new file with mode: 0644]
keepalived/include/vrrp_if.h
keepalived/include/vrrp_ipaddress.h
keepalived/include/vrrp_ipsecah.h
keepalived/include/vrrp_netlink.h
keepalived/include/vrrp_notify.h
keepalived/include/vrrp_scheduler.h
keepalived/include/vrrp_sync.h
keepalived/samples/keepalived.conf.SSL_GET
keepalived/samples/keepalived.conf.status_code [new file with mode: 0644]
keepalived/vrrp/Makefile.in
keepalived/vrrp/vrrp.c
keepalived/vrrp/vrrp_arp.c [new file with mode: 0644]
keepalived/vrrp/vrrp_if.c
keepalived/vrrp/vrrp_ipaddress.c
keepalived/vrrp/vrrp_ipsecah.c
keepalived/vrrp/vrrp_netlink.c
keepalived/vrrp/vrrp_notify.c
keepalived/vrrp/vrrp_scheduler.c
keepalived/vrrp/vrrp_sync.c
lib/Makefile.in [new file with mode: 0644]
lib/html.c [new file with mode: 0644]
lib/html.h [new file with mode: 0644]
lib/list.c [moved from keepalived/core/list.c with 96% similarity]
lib/list.h [moved from keepalived/include/list.h with 96% similarity]
lib/memory.c [moved from keepalived/core/memory.c with 99% similarity]
lib/memory.h [moved from keepalived/include/memory.h with 93% similarity]
lib/scheduler.c [moved from keepalived/core/scheduler.c with 99% similarity]
lib/scheduler.h [moved from keepalived/include/scheduler.h with 98% similarity]
lib/timer.c [moved from keepalived/core/timer.c with 84% similarity]
lib/timer.h [moved from keepalived/include/timer.h with 91% similarity]
lib/utils.c [moved from keepalived/core/utils.c with 98% similarity]
lib/utils.h [moved from keepalived/include/utils.h with 96% similarity]
lib/vector.c [moved from keepalived/core/vector.c with 97% similarity]
lib/vector.h [moved from keepalived/include/vector.h with 95% similarity]

index 9c6cab8..0e45b68 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,50 @@
+2002-11-20  Alexandre Cassen  <acassen@linux-vs.org>
+       * keepalived-0.7.6 released.
+       * Created a common library for code modularization. This lib will
+         be used by all Keepalived components (genhash + Keepalived) to
+         reduce repeated and duplicated code.
+       * Rewrote the genhash utility using the common lib. The design is
+         similar to Keepalived core design.
+       * Reviewed the autoconf and Makefiles for new code architecture.
+       * Created a html utility lib for HTTP headers manipulations.
+       * Extended the CHECK_HTTP and CHECK_SSL checkers to support remote
+         webserver HTTP header status_code. HTTP status_code is parsed
+         according to rfc2616.6.1. The keyword created for the new feature is
+         "status_code" inside and "url" declaration. "status_code" feature
+         can be mixed with "digest" feature. See the samples directory
+         keepalived/samples/keepalived.conf.status_code for example.
+       * Review the CHECK_HTTP and CHECK_SSL MD5SUM code to use a common
+         stream handling function.
+       * Matthijs van der Klip, <Matthijs.van.der.Klip@tech.omroep.nl> and I
+         fixed a bug into the HTTP/SSL code that close the socket fd even
+         if remote webserver has not been connected. As a result of fact,
+         next socket created were imediatly closed. As a side effect, this
+         altered the SMTP notification when remote webserver checked fall. No
+         SMTP notification were sent if webserver were detected DOWN. Thanks
+         to Matthijs for time debugging and investigation.
+       * VRRP : Rewrote the previous Gratuitous ARP facility. Created a lib
+         (vrrp_arp.c) dealing with PF_PACKET-SOCK_RAW-ETH_P_RARP and
+         sockaddr_ll.
+       * VRRP : Some cosmetics patch for messages logging.
+       * VRRP : Fixed an issue during VRRP packet building, appending VRRP
+         VIPs to the VRRP packet in the network order form.
+       * VRRP : Reviewed the previous VRRP packet building process to not
+         create the ARP header. Removec the previous hacky
+         PF_PACKET-SOCK_PACKET-0x300 to use AF_INET-SOCK_RAW-PROTO to leave
+         kernel appending ARP header since code doesn t currently support
+         VRRP VMAC.
+       * VRRP : Rewrote the previous vrrp_send_pkt() function to deal with
+         sendmsg(). optimization lazzyness :)
+       * VRRP : Extended the interfaces library to support common utility
+         functions (if_setsockopt_hdrincl, if_setsockopt_bindtodevice, ...)
+       * VRRP : Finally extend the code to support VRRP IPSEC-AH authentication
+         method. Created a IPSEC-AH seq_number syncrhonization mecanism during
+         VRRP MASTER/BACKUP elections.
+       * VRRP : Extended the VRRP TSM to speed up instances syncrhonization
+         during FAULT->BACKUP & FAULT->MASTER state transition.
+       * Some cosmetics patches. This release is proposed as a 1.0.0 STABLE
+         release candidate.
+
 2002-09-17  Alexandre Cassen  <acassen@linux-vs.org>
        * keepalived-0.7.1 released.
        * Fixed a MISC_CHECK issue when registering next timer checker. Must
index 72b7f22..d7a27b9 100644 (file)
@@ -5,6 +5,7 @@
 # Copyright (C) 2001, 2002 Alexandre Cassen, <acassen@linux-vs.org>
 
 all:
+       $(MAKE) -C lib || exit 1;
        $(MAKE) -C keepalived
        $(MAKE) -C genhash
        @echo ""
@@ -16,10 +17,12 @@ debug:
        @echo "Make complete"
 
 clean:
+       $(MAKE) -C lib clean
        $(MAKE) -C keepalived clean
        $(MAKE) -C genhash clean
 
 distclean:
+       $(MAKE) -C lib distclean
        $(MAKE) -C keepalived distclean
        $(MAKE) -C genhash distclean
        rm -f Makefile
diff --git a/VERSION b/VERSION
index 39e898a..c006218 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.7.1
+0.7.6
index 5bae429..2a25883 100755 (executable)
--- a/configure
+++ b/configure
@@ -1993,7 +1993,7 @@ fi
 done
 
 
-OUTPUT_TARGET="$OUTPUT_TARGET keepalived/Makefile keepalived/healthcheck/Makefile keepalived/vrrp/Makefile"
+OUTPUT_TARGET="$OUTPUT_TARGET keepalived/Makefile keepalived/healthcheck/Makefile keepalived/vrrp/Makefile lib/Makefile"
 if test "$IPVS_SUPPORT" = "_WITH_LVS_"; then
   if test "$KERN" = "_KRNL_2_4_"; then
     OUTPUT_TARGET="$OUTPUT_TARGET keepalived/libipvs/Makefile"
index abe6893..28f4670 100644 (file)
@@ -212,7 +212,7 @@ AC_TYPE_SIGNAL
 AC_CHECK_FUNCS(gettimeofday select socket strerror strtol uname)
 
 dnl ----[ Process output target ]----
-OUTPUT_TARGET="$OUTPUT_TARGET keepalived/Makefile keepalived/healthcheck/Makefile keepalived/vrrp/Makefile"
+OUTPUT_TARGET="$OUTPUT_TARGET keepalived/Makefile keepalived/healthcheck/Makefile keepalived/vrrp/Makefile lib/Makefile"
 if test "$IPVS_SUPPORT" = "_WITH_LVS_"; then
   if test "$KERN" = "_KRNL_2_4_"; then
     OUTPUT_TARGET="$OUTPUT_TARGET keepalived/libipvs/Makefile"
diff --git a/genhash/AUTHOR b/genhash/AUTHOR
new file mode 100644 (file)
index 0000000..0d64916
--- /dev/null
@@ -0,0 +1 @@
+Alexandre Cassen, <Alexandre.Cassen@wanadoo.fr>
diff --git a/genhash/AUTHORS b/genhash/AUTHORS
deleted file mode 100644 (file)
index 9434f73..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Alexandre Cassen <acassen@linux-vs.org>
-Jan Holmberg <jan@artech.se>
index 143a0de..170e465 100644 (file)
@@ -1,3 +1,7 @@
+2002-11-18  Alexandre Cassen  <acassen@linux-vs.org>
+       * Rewrote the whole previous code to use common
+         template libraries.
+
 2002-01-17  Alexandre Cassen  <acassen@linux-vs.org>
        * Patched the dynamic GET request lenght allocation.
 
index 2a2593d..3ed72dd 100644 (file)
@@ -18,13 +18,12 @@ Utilisation
   The global synopsis for the tool is :
 
   [user@lvs]$ genhash --help
-  genhash Version 0.4.9 (30/11, 2001)
+  genhash v1.0.0 (18/11, 2002)
   Usage:
     genhash -s server-address -p port -u url
-    genhash -S -K priv-key-file -P pem-password -s server-address -p port -u url
-    genhash -S -K priv-key-file -P pem-password -C cert-file -s server-address -p port -u url
+    genhash -S -s server-address -p port -u url
     genhash -h
-    genhash -v
+    genhash -r
 
   Commands:
   Either long or short options are allowed.
@@ -32,11 +31,10 @@ Utilisation
     genhash --server          -s       Use the specified remote server address.
     genhash --port            -p       Use the specified remote server port.
     genhash --url             -u       Use the specified remote server url.
-    genhash --use-private-key -K       Use the specified SSL private key.
-    genhash --use-password    -P       Use the specified SSL private key password.
-    genhash --use-certificate -C       Use the specified SSL Certificate file.
+    genhash --use-virtualhost -V       Use the specified virtualhost in GET query.
+    genhash --verbose         -v       Use verbose mode output.
     genhash --help            -h       Display this short inlined help screen.
-    genhash --version         -v       Display the version number
+    genhash --release         -r       Display the release number
 
   Imagine we have a remote HTTP/HTTPS server owning the IP address 192.168.200.10.
   We want to generate a MD5SUM over the server root url (/).
index 62aff91..aba4d9a 100644 (file)
@@ -1,28 +1,31 @@
-# Makefile
+# Makefile.in
 #
-# Keepalived OpenSource project.
-#
-# Copyright (C) 2001, 2002 Alexandre Cassen, <acassen@linux-vs.org>
+# Copyright (C) 2002 Alexandre Cassen, <acassen@linux-vs.org>
+
+EXEC = ../bin/genhash
 
-EXEC = genhash
-BIN  = ../bin
-prefix = @prefix@
+prefix      = @prefix@
 exec_prefix = @exec_prefix@
-bindir = @bindir@
+bindir     = @bindir@
 
-CC = gcc
-CFLAGS = @CFLAGS@ -Wall -Wunused -Wstrict-prototypes
-LDFLAGS = @LIBS@ @LDFLAGS@
+CC = @CC@
+INCLUDES = -I../lib
+CFLAGS = @CFLAGS@ $(INCLUDES) \
+        -Wall -Wunused -Wstrict-prototypes
+LDFLAGS = -lssl -lpopt
 
-OBJS = main.o client.o common.o
+OBJS = main.o sock.o layer4.o http.o ssl.o
+LIB_OBJS = ../lib/timer.o ../lib/scheduler.o \
+          ../lib/memory.o ../lib/list.o ../lib/utils.o \
+          ../lib/html.o
 
 all:   $(EXEC)
-       strip $(BIN)/$(EXEC)
+       strip $(EXEC)
        @echo ""
        @echo "Make complete"
 
-$(EXEC): $(OBJS)
-       $(CC) $(OBJS) -o $(BIN)/$(EXEC) $(LDFLAGS)
+$(EXEC): $(LIB_OBJS) $(OBJS)
+       $(CC) $(LIB_OBJS) $(OBJS) -o $(EXEC) $(LDFLAGS)
 
 clean:
        rm -f core *.o
@@ -35,4 +38,20 @@ uninstall:
 
 install:
        install -d $(bindir)
-       install -m 755 $(BIN)/$(EXEC) $(bindir)/
+       install -m 755 $(EXEC) $(bindir)/
+
+mrproper: clean distclean
+       rm -f config.*
+
+# Code dependencies
+
+main.o: main.c main.h ../lib/utils.h sock.h ../lib/timer.h \
+       http.h ssl.h ../lib/scheduler.h ../lib/memory.h
+sock.o: sock.c sock.h ../lib/utils.h layer4.h ssl.h main.h \
+       ../lib/memory.h
+layer4.o: layer4.c layer4.h ../lib/scheduler.h ../lib/utils.h \
+       main.h ssl.h
+http.o: http.c http.h sock.h ../lib/scheduler.h ../lib/utils.h \
+       layer4.h main.h ../lib/html.h ../lib/timer.h ../lib/scheduler.h \
+       ../lib/memory.h
+ssl.o: ssl.c ssl.h http.h main.h ../lib/utils.h ../lib/html.h
diff --git a/genhash/TODO b/genhash/TODO
deleted file mode 100644 (file)
index bffe175..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-* Create a generic function to handle remote server reply.
-  That way we will remove duplicate code for read reply.
-* beautifull the code.
diff --git a/genhash/VERSION b/genhash/VERSION
new file mode 100644 (file)
index 0000000..3eefcb9
--- /dev/null
@@ -0,0 +1 @@
+1.0.0
diff --git a/genhash/client.c b/genhash/client.c
deleted file mode 100644 (file)
index 8f09497..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Soft:        Genhash compute MD5 digest from a HTTP get result. This
- *              program is use to compute hash value that you will add
- *              into the /etc/keepalived/keepalived.conf for HTTP_GET
- *              & SSL_GET keepalive method.
- *
- * Part:        Layer4 global functions.
- *
- * Version:     $Id: client.c,v 0.4.9 2001/11/28 11:50:23 acassen Exp $
- *
- * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
- *              Jan Holmberg, <jan@artech.se>
- *
- *              This program is distributed in the hope that it will be useful,
- *              but WITHOUT ANY WARRANTY; without even the implied warranty of
- *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *              See the GNU General Public License for more details.
- *
- *              This program is free software; you can redistribute it and/or
- *              modify it under the terms of the GNU General Public License
- *              as published by the Free Software Foundation; either version
- *              2 of the License, or (at your option) any later version.
- */
-
-#include "client.h"
-
-int
-tcp_connect(int fd, char *host, int port)
-{
-       int long_inet = sizeof (struct sockaddr_in);
-       struct sockaddr_in adr_serv;
-       struct hostent *ip_serv;
-       int arglen;
-       struct timeval tv;
-       fd_set wfds;
-       int rc, val;
-
-       /* Proceed remote hostname */
-       memset(&ip_serv, 0, sizeof (struct hostent));
-       if ((ip_serv = gethostbyname(host)) == NULL)
-               return TCP_RESOLV_ERROR;
-
-       /* Fill in connection structure */
-       memset(&adr_serv, 0, long_inet);
-       adr_serv.sin_family = AF_INET;
-       adr_serv.sin_port = htons(port);
-       adr_serv.sin_addr = *(struct in_addr *) ip_serv->h_addr;
-
-       /* Set read/write socket nonblock */
-       val = fcntl(fd, F_GETFL);
-       fcntl(fd, F_SETFL, val | O_NONBLOCK);
-
-       /* Connect the remote host */
-       rc = connect(fd, (struct sockaddr *) &adr_serv, long_inet);
-       if (rc == -1) {
-               if (errno != EINPROGRESS) {
-                       rc = errno;
-                       return TCP_CONNECT_ERROR;
-               }
-       }
-
-       /* Timeout settings */
-       tv.tv_sec = SOCKET_TIMEOUT_READ;
-       tv.tv_usec = 0;
-       FD_ZERO(&wfds);
-       FD_SET(fd, &wfds);
-
-       rc = select(fd + 1, NULL, &wfds, NULL, &tv);
-       if (!FD_ISSET(fd, &wfds))
-               return TCP_WRITE_TIMEOUT;
-
-       if (rc <= 0)
-               return TCP_SELECT_ERROR;
-
-       rc = 0;
-       arglen = sizeof (int);
-       if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &rc, &arglen) < 0)
-               rc = errno;
-       if (rc)
-               return TCP_CONNECT_FAILED;
-
-       /* Restore socket parameters */
-       fcntl(fd, F_SETFL, val);
-
-       return TCP_CONNECT_SUCCESS;
-}
-
-int
-tcp_send(int fd, char *request, int len)
-{
-       if (send(fd, request, len, 0) == -1)
-               return TCP_SEND_ERROR;
-       return 0;
-}
-
-int
-tcp_read_to(int fd)
-{
-       struct timeval tv;
-       fd_set rfds;
-
-       /* Timeout settings */
-       tv.tv_sec = SOCKET_TIMEOUT_READ;
-       tv.tv_usec = 0;
-       FD_ZERO(&rfds);
-       FD_SET(fd, &rfds);
-
-       /* attempt read data */
-       select(fd + 1, &rfds, NULL, NULL, &tv);
-       if (!FD_ISSET(fd, &rfds))
-               return TCP_READ_TIMEOUT;
-       return 0;
-}
-
-int
-tcp_sock(void)
-{
-       int fd;
-       struct sockaddr_in adr_local;
-
-       if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
-               return (-1);
-       memset(&adr_local, 0, sizeof (struct sockaddr_in));
-       adr_local.sin_family = AF_INET;
-       adr_local.sin_port = htons(0);
-       adr_local.sin_addr.s_addr = htonl(INADDR_ANY);
-
-       if (bind
-           (fd, (struct sockaddr *) &adr_local, sizeof (struct sockaddr_in)))
-               return (-1);
-
-       return (fd);
-}
diff --git a/genhash/client.h b/genhash/client.h
deleted file mode 100644 (file)
index 2423cc7..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Soft:        Genhash compute MD5 digest from a HTTP get result. This
- *              program is use to compute hash value that you will add
- *              into the /etc/keepalived/keepalived.conf for HTTP_GET
- *              & SSL_GET keepalive method.
- *
- * Part:        client.c include file.
- *
- * Version:     $Id: client.h,v 0.4.9 2001/11/28 11:50:23 acassen Exp $
- *
- * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
- *              Jan Holmberg, <jan@artech.se>
- *
- *              This program is distributed in the hope that it will be useful,
- *              but WITHOUT ANY WARRANTY; without even the implied warranty of
- *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *              See the GNU General Public License for more details.
- *
- *              This program is free software; you can redistribute it and/or
- *              modify it under the terms of the GNU General Public License
- *              as published by the Free Software Foundation; either version
- *              2 of the License, or (at your option) any later version.
- */
-
-#ifndef _CLIENT_H
-#define _CLIENT_H
-
-/* System includes */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-/* Socket timeout */
-#define SOCKET_TIMEOUT_READ    3
-#define SOCKET_TIMEOUT_WRITE   3
-
-/* Return codes */
-/* systems predefined ret codes */
-#define OUT_OF_MEMORY          (1 << 0)
-
-/* TCP predefined ret codes */
-#define TCP_BIND_ERROR         (1 << 1)
-#define TCP_RESOLV_ERROR       (1 << 2)
-#define TCP_CONNECT_ERROR      (1 << 3)
-#define TCP_CONNECT_SUCCESS    (1 << 4)
-#define TCP_WRITE_TIMEOUT      (1 << 5)
-#define TCP_SELECT_ERROR       (1 << 6)
-#define TCP_CONNECT_FAILED     (1 << 7)
-#define TCP_SEND_ERROR         (1 << 8)
-#define TCP_READ_TIMEOUT       (1 << 9)
-
-/* Upper Layer - HTTP predefined ret codes */
-#define HTTP_GET_SUCCESS       (1 << 10)
-
-/* Upper Layer - SSL predefined ret codes */
-#define SSL_WRITE_ERROR                (1 << 11)
-#define SSL_INCOMPLETE_WRITE   (1 << 12)
-#define SSL_READ_ERROR         (1 << 13)
-#define SSL_SHUTDOWN_FAILED    (1 << 14)
-#define SSL_GET_SUCCESS                (1 << 15)
-
-/* Prototypes */
-extern int tcp_connect(int fd, char *host, int port);
-extern int tcp_send(int fd, char *request, int len);
-extern int tcp_read_to(int fd);
-extern int tcp_sock(void);
-
-#endif
diff --git a/genhash/common.c b/genhash/common.c
deleted file mode 100644 (file)
index 3b0262f..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Soft:        Genhash compute MD5 digest from a HTTP get result. This
- *              program is use to compute hash value that you will add
- *              into the /etc/keepalived/keepalived.conf for HTTP_GET
- *              & SSL_GET keepalive method.
- *
- * Part:        Common SSL functions.
- *
- * Version:     $Id: common.c,v 0.4.9 2001/11/28 11:50:23 acassen Exp $
- *
- * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
- *              Jan Holmberg, <jan@artech.se>
- *
- *              This program is distributed in the hope that it will be useful,
- *              but WITHOUT ANY WARRANTY; without even the implied warranty of
- *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *              See the GNU General Public License for more details.
- *
- *              This program is free software; you can redistribute it and/or
- *              modify it under the terms of the GNU General Public License
- *              as published by the Free Software Foundation; either version
- *              2 of the License, or (at your option) any later version.
- */
-
-#include "common.h"
-
-static BIO *bio_err = 0;
-static char *pass;
-
-/* A simple error and exit routine*/
-int
-err_exit(char *string)
-{
-       fprintf(stderr, "%s\n", string);
-       exit(0);
-}
-
-/* Print SSL errors and exit*/
-int
-berr_exit(char *string)
-{
-       BIO_printf(bio_err, "%s\n", string);
-       ERR_print_errors(bio_err);
-       exit(0);
-}
-
-/*The password code is not thread safe*/
-static int
-password_cb(char *buf, int num, int rwflag, void *userdata)
-{
-       if (num < strlen(pass) + 1)
-               return (0);
-
-       strcpy(buf, pass);
-       return (strlen(pass));
-}
-
-static void
-sigpipe_handle(int x)
-{
-}
-
-/* SSL context initializer */
-SSL_CTX *
-initialize_ctx(char *keyfile, char *password, char *cafile)
-{
-       SSL_METHOD *meth;
-       SSL_CTX *ctx;
-
-       if (!bio_err) {
-               /* Global system initialization */
-               SSL_library_init();
-               SSL_load_error_strings();
-
-               /* An error write context */
-               bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
-       }
-
-       /* Set up a SIGPIPE handler */
-       signal(SIGPIPE, sigpipe_handle);
-
-       /* Create our context */
-       meth = SSLv23_method();
-       ctx = SSL_CTX_new(meth);
-
-       /* Load our keys and certificates */
-       if (keyfile)
-               if (!(SSL_CTX_use_certificate_chain_file(ctx, keyfile)))
-                       berr_exit("Can't read certificate file");
-
-       if (password) {
-               pass = password;
-               SSL_CTX_set_default_passwd_cb(ctx, password_cb);
-       }
-
-       if (keyfile)
-               if (!
-                   (SSL_CTX_use_PrivateKey_file
-                    (ctx, keyfile, SSL_FILETYPE_PEM)))
-                       berr_exit("Can't read key file");
-
-       /* Load the CAs we trust */
-       if (cafile)
-               if (!(SSL_CTX_load_verify_locations(ctx, cafile, 0)))
-                       berr_exit("Can't read CA list");
-#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
-       SSL_CTX_set_verify_depth(ctx, 1);
-#endif
-
-       return ctx;
-}
-
-void
-destroy_ctx(SSL_CTX * ctx)
-{
-       SSL_CTX_free(ctx);
-}
diff --git a/genhash/common.h b/genhash/common.h
deleted file mode 100644 (file)
index 9fe4b43..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Soft:        Genhash compute MD5 digest from a HTTP get result. This
- *              program is use to compute hash value that you will add
- *              into the /etc/keepalived/keepalived.conf for HTTP_GET
- *              & SSL_GET keepalive method.
- *
- * Part:        common.c include file.
- *
- * Version:     $Id: common.h,v 0.4.9 2001/11/28 11:50:23 acassen Exp $
- *
- * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
- *              Jan Holmberg, <jan@artech.se>
- *
- *              This program is distributed in the hope that it will be useful,
- *              but WITHOUT ANY WARRANTY; without even the implied warranty of
- *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *              See the GNU General Public License for more details.
- *
- *              This program is free software; you can redistribute it and/or
- *              modify it under the terms of the GNU General Public License
- *              as published by the Free Software Foundation; either version
- *              2 of the License, or (at your option) any later version.
- */
-
-#ifndef _COMMON_H
-#define _COMMON_H
-
-/* System includes */
-#include <string.h>
-#include <signal.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-/* prototypes */
-extern int berr_exit(char *string);
-extern int err_exit(char *string);
-extern SSL_CTX *initialize_ctx(char *keyfile, char *password, char *cafile);
-extern void destroy_ctx(SSL_CTX * ctx);
-
-#ifndef ALLOW_OLD_VERSIONS
-#if(OPENSSL_VERSION_NUMBER < 0x00905100L)
-#error "Must use OpenSSL 0.9.6 or later"
-#endif
-#endif
-
-#endif
diff --git a/genhash/http.c b/genhash/http.c
new file mode 100644 (file)
index 0000000..479c4e3
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        HTTP asynchronous engine.
+ *
+ * Version:     $Id: http.c,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#include <errno.h>
+#include <openssl/err.h>
+#include "memory.h"
+#include "http.h"
+#include "layer4.h"
+#include "main.h"
+#include "utils.h"
+#include "html.h"
+#include "timer.h"
+
+/* extern variables */
+extern REQ *req;
+
+/* 
+ * The global design of this checker is the following :
+ * 
+ * - All the actions are done asynchronously.
+ * - All the actions handle timeout connection.
+ * - All the actions handle error from low layer to upper
+ *   layers.
+ * 
+ * The global synopsis of the inter-thread-call is :
+ *     
+ *     http_request_thread (send SSL GET request)
+ *            v
+ *     http_response_thread (initialize read stream step)
+ *         /             \
+ *        /               \
+ *       v                 v
+ *  http_read_thread   ssl_read_thread (perform HTTP|SSL stream)
+ *       v              v
+ *  ------------------------------
+ *   finalize    /     epilog
+ */
+
+/* free allocated pieces */
+static void free_all(thread * thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+
+       DBG("Total read size read = %d Bytes, fd:%d\n",
+           sock->total_size, sock->fd);
+
+       if (sock->buffer)
+               FREE(sock->buffer);
+
+       /*
+        * Decrement the current global get number.
+        * => free the reserved thread
+        */
+       req->response_time = timer_tol(timer_now());
+       thread_add_terminate_event(thread->master);
+}
+
+/* Simple epilog functions. */
+int
+epilog(thread * thread)
+{
+       DBG("Timeout on URL : [%s]\n", req->url);
+       free_all(thread);
+       return 0;
+}
+
+/* Simple finalization function */
+int
+finalize(thread *thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+       unsigned char digest[16];
+       int i;
+
+       printf("\n");
+       /* Compute final MD5 digest */
+       MD5_Final(digest, &sock->context);
+       printf(HTML_MD5);
+       print_buffer(16, digest);
+
+       printf(HTML_MD5_FINAL);
+       for (i = 0; i < 16; i++)
+               printf("%02x", digest[i]);
+       printf("\n\n");
+
+       DBG("Finalize : [%s]\n", req->url);
+       free_all(thread);
+       return 0;
+}
+
+/* Process incoming stream */
+int http_process_stream(SOCK *sock, int r)
+{
+       sock->size += r;
+       sock->total_size += r;
+
+       if (!sock->extracted) {
+               printf(HTTP_HEADER_HEXA);
+               if ((sock->extracted =
+                   extract_html(sock->buffer, sock->size))) {
+                       print_buffer(sock->extracted - sock->buffer, sock->buffer);
+                       printf(HTTP_HEADER_ASCII);
+                       for (r = 0; r < sock->extracted - sock->buffer; r++)
+                               printf("%c", sock->buffer[r]);
+                       printf("\n");
+
+                       printf(HTML_HEADER_HEXA);
+                       r = sock->size - (sock->extracted - sock->buffer);
+                       if (r) {
+                               print_buffer(r, sock->extracted);
+                               memcpy(sock->buffer, sock->extracted, r);
+                               MD5_Update(&sock->context, sock->buffer,
+                                          r);
+                               r = 0;
+                       }
+                       sock->size = r;
+               } else {
+                       /* minimize buffer using no 2*CR/LF found yet */
+                       if (sock->size > 3) {
+                               memcpy(sock->buffer,
+                                      sock->buffer + sock->size - 3, 3);
+                               sock->size = 3;
+                       }
+               }
+       } else if (sock->size) {
+               print_buffer(r, sock->buffer);
+               MD5_Update(&sock->context, sock->buffer,
+                          sock->size);
+               sock->size = 0;
+       }
+
+       return 0;
+}
+
+/* Asynchronous HTTP stream reader */
+int
+http_read_thread(thread * thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+       int r = 0;
+
+       /* Handle read timeout */
+       if (thread->type == THREAD_READ_TIMEOUT)
+               return epilog(thread);
+
+       /* read the HTTP stream */
+       memset(sock->buffer, 0, MAX_BUFFER_LENGTH);
+       r = read(thread->u.fd, sock->buffer, MAX_BUFFER_LENGTH);
+
+       DBG(" [l:%d,fd:%d]\n", r, sock->fd);
+
+       if (r == -1 || r == 0) {        /* -1:error , 0:EOF */
+               if (r == -1) {
+                       /* We have encourred a real read error */
+                       DBG("Read error with server [%s:%d]: %s\n",
+                           inet_ntop2(req->addr_ip), ntohs(req->addr_port),
+                           strerror(errno));
+                       return epilog(thread);
+               }
+
+               /* All the HTTP stream has been parsed */
+               finalize(thread);
+       } else {
+               /* Handle the response stream */
+               http_process_stream(sock, r);
+
+               /*
+                * Register next http stream reader.
+                * Register itself to not perturbe global I/O multiplexer.
+                */
+               thread_add_read(thread->master, http_read_thread, sock,
+                               thread->u.fd, HTTP_CNX_TIMEOUT);
+       }
+
+       return 0;
+}
+
+/*
+ * Read get result from the remote web server.
+ * Apply trigger check to this result.
+ */
+int
+http_response_thread(thread * thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+
+       /* Handle read timeout */
+       if (thread->type == THREAD_READ_TIMEOUT)
+               return epilog(thread);
+
+       /* Allocate & clean the get buffer */
+       sock->buffer = (char *) MALLOC(MAX_BUFFER_LENGTH);
+
+       /* Initalize the MD5 context */
+       MD5_Init(&sock->context);
+
+       /* Register asynchronous http/ssl read thread */
+       if (req->ssl)
+               thread_add_read(thread->master, ssl_read_thread, sock,
+                               thread->u.fd, HTTP_CNX_TIMEOUT);
+       else
+               thread_add_read(thread->master, http_read_thread, sock,
+                               thread->u.fd, HTTP_CNX_TIMEOUT);
+       return 0;
+}
+
+/* remote Web server is connected, send it the get url query.  */
+int
+http_request_thread(thread * thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+       char *str_request;
+       int ret = 0;
+
+       /* Handle read timeout */
+       if (thread->type == THREAD_WRITE_TIMEOUT)
+               return epilog(thread);
+
+       /* Allocate & clean the GET string */
+       str_request = (char *) MALLOC(GET_REQUEST_BUFFER_LENGTH);
+       memset(str_request, 0, GET_REQUEST_BUFFER_LENGTH);
+
+       snprintf(str_request, GET_REQUEST_BUFFER_LENGTH, REQUEST_TEMPLATE,
+                req->url,
+                (req->vhost) ? req->vhost : inet_ntop2(req->addr_ip)
+                , ntohs(req->addr_port));
+
+       /* Send the GET request to remote Web server */
+       DBG("Sending GET request [%s] on fd:%d\n",
+           req->url, sock->fd);
+       if (req->ssl)
+               ret =
+                   ssl_send_request(sock->ssl, str_request,
+                                    strlen(str_request));
+       else
+               ret =
+                   (send(sock->fd, str_request, strlen(str_request), 0) !=
+                    -1) ? 1 : 0;
+
+       FREE(str_request);
+
+       if (!ret) {
+               fprintf(stderr, "Cannot send get request to [%s:%d].\n",
+                   inet_ntop2(req->addr_ip)
+                   , ntohs(req->addr_port));
+               return epilog(thread);
+       }
+
+       /* Register read timeouted thread */
+       thread_add_read(thread->master, http_response_thread, sock,
+                       sock->fd, HTTP_CNX_TIMEOUT);
+       return 1;
+}
diff --git a/genhash/http.h b/genhash/http.h
new file mode 100644 (file)
index 0000000..0cfe5a9
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        http.c include file.
+ *
+ * Version:     $Id: http.h,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _HTTP_H
+#define _HTTP_H
+
+/* system includes */
+#include <stdio.h>
+#include <openssl/ssl.h>
+
+/* local includes */
+#include "scheduler.h"
+#include "sock.h"
+
+/* global defs */
+#define GET_REQUEST_BUFFER_LENGTH 1024
+#define GET_BUFFER_LENGTH 2048
+#define MAX_BUFFER_LENGTH 4096
+#define HTTP_CNX_TIMEOUT 5
+#define PROTO_HTTP     0x01
+#define PROTO_SSL      0x02
+
+/* GET processing command */
+#define REQUEST_TEMPLATE "GET %s HTTP/1.0\r\n" \
+                        "User-Agent: GenHash (Linux powered)\r\n" \
+                        "Host: %s:%d\r\n\r\n"
+
+/* Output delimiters */
+#define DELIM_BEGIN "-----------------------["
+#define DELIM_END   "]-----------------------\n"
+#define HTTP_HEADER_HEXA  DELIM_BEGIN"    HTTP Header Buffer    "DELIM_END
+#define HTTP_HEADER_ASCII DELIM_BEGIN" HTTP Header Ascii Buffer "DELIM_END
+#define HTML_HEADER_HEXA  DELIM_BEGIN"       HTML Buffer        "DELIM_END
+#define HTML_MD5          DELIM_BEGIN"    HTML MD5 resulting    "DELIM_END
+#define HTML_MD5_FINAL    DELIM_BEGIN" HTML MD5 final resulting "DELIM_END
+
+/* Define prototypes */
+extern int epilog(thread *thread);
+extern int finalize(thread *thread);
+extern int http_process_stream(SOCK *sock, int r);
+extern int http_request_thread(thread * thread);
+
+#endif
diff --git a/genhash/layer4.c b/genhash/layer4.c
new file mode 100644 (file)
index 0000000..ebe90d0
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        Layer4 asynchronous primitives.
+ *
+ * Version:     $Id: layer4.c,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#include "layer4.h"
+#include "utils.h"
+#include "main.h"
+#include "sock.h"
+#include "http.h"
+#include "ssl.h"
+
+enum connect_result
+tcp_connect(int fd, uint32_t addr_ip, uint16_t addr_port)
+{
+       struct linger li = { 0 };
+       int long_inet;
+       struct sockaddr_in adr_serv;
+       int ret;
+       int val;
+
+       /* free the tcp port after closing the socket descriptor */
+       li.l_onoff = 1;
+       li.l_linger = 0;
+       setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &li,
+                  sizeof (struct linger));
+
+       long_inet = sizeof (struct sockaddr_in);
+       memset(&adr_serv, 0, long_inet);
+       adr_serv.sin_family = AF_INET;
+       adr_serv.sin_port = addr_port;
+       adr_serv.sin_addr.s_addr = addr_ip;
+
+       /* Make socket non-block. */
+       val = fcntl(fd, F_GETFL, 0);
+       fcntl(fd, F_SETFL, val | O_NONBLOCK);
+
+       /* Call connect function. */
+       ret = connect(fd, (struct sockaddr *) &adr_serv, long_inet);
+
+       /* Immediate success */
+       if (ret == 0) {
+               fcntl(fd, F_SETFL, val);
+               return connect_success;
+       }
+
+       /* If connect is in progress then return 1 else it's real error. */
+       if (ret < 0) {
+               if (errno != EINPROGRESS)
+                       return connect_error;
+       }
+
+       /* restore previous fd args */
+       fcntl(fd, F_SETFL, val);
+       return connect_in_progress;
+}
+
+enum connect_result
+tcp_socket_state(int fd, thread * thread, uint32_t addr_ip, uint16_t addr_port,
+                int (*func) (struct _thread *))
+{
+       int status;
+       int slen;
+       int ret = 0;
+       TIMEVAL timer_min;
+
+       /* Handle connection timeout */
+       if (thread->type == THREAD_WRITE_TIMEOUT) {
+               DBG("TCP connection timeout to [%s:%d].\n",
+                   inet_ntop2(addr_ip), ntohs(addr_port));
+               close(thread->u.fd);
+               return connect_timeout;
+       }
+
+       /* Check file descriptor */
+       slen = sizeof (status);
+       if (getsockopt
+           (thread->u.fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen) < 0)
+               ret = errno;
+
+       /* Connection failed !!! */
+       if (ret) {
+               DBG("TCP connection failed to [%s:%d].\n",
+                   inet_ntop2(addr_ip), ntohs(addr_port));
+               close(thread->u.fd);
+               return connect_error;
+       }
+
+       /* If status = 0, TCP connection to remote host is established.
+        * Otherwise register checker thread to handle connection in progress,
+        * and other error code until connection is established.
+        * Recompute the write timeout (or pending connection).
+        */
+       if (status != 0) {
+               DBG("TCP connection to [%s:%d] still IN_PROGRESS.\n",
+                   inet_ntop2(addr_ip), ntohs(addr_port));
+
+               timer_min = timer_sub_now(thread->sands);
+
+               if (TIMER_SEC(timer_min) <= 0)
+                       thread_add_write(thread->master, func,
+                                        THREAD_ARG(thread)
+                                        , thread->u.fd, 0);
+               else
+                       thread_add_write(thread->master, func,
+                                        THREAD_ARG(thread)
+                                        , thread->u.fd, TIMER_SEC(timer_min));
+               return connect_in_progress;
+       }
+
+       return connect_success;
+}
+
+void
+tcp_connection_state(int fd, enum connect_result status, thread * thread,
+                    int (*func) (struct _thread *)
+                    , int timeout)
+{
+       switch (status) {
+       case connect_error:
+               close(fd);
+               break;
+
+       case connect_success:
+               thread_add_write(thread->master, func, THREAD_ARG(thread),
+                                fd, timeout);
+               break;
+
+       /* Checking non-blocking connect, we wait until socket is writable */
+       case connect_in_progress:
+               thread_add_write(thread->master, func, THREAD_ARG(thread),
+                                fd, timeout);
+               break;
+
+       default:
+               break;
+       }
+}
+
+int
+tcp_check_thread(thread * thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+       int ret = 1;
+
+       sock->status = tcp_socket_state(thread->u.fd, thread, req->addr_ip
+                                 , req->addr_port, tcp_check_thread);
+       switch (sock->status) {
+       case connect_error:
+               DBG("Error connecting server [%s:%d].\n",
+                   inet_ntop2(req->addr_ip), ntohs(req->addr_port));
+               thread_add_terminate_event(thread->master);
+               return -1;
+               break;
+
+       case connect_timeout:
+               DBG("Timeout connecting server [%s:%d].\n",
+                   inet_ntop2(req->addr_ip), ntohs(req->addr_port));
+               thread_add_terminate_event(thread->master);
+               return -1;
+               break;
+
+       case connect_success:{
+                       if (req->ssl)
+                               ret = ssl_connect(thread);
+
+                       if (ret) {
+                               /* Remote WEB server is connected.
+                                * Unlock eventual locked socket.
+                                */
+                               sock->lock = 0;
+                               thread_add_event(thread->master,
+                                                http_request_thread,
+                                                sock, 0);
+                       } else {
+                               DBG("Connection trouble to: [%s:%d].\n",
+                                   inet_ntop2(req->addr_ip),
+                                   ntohs(req->addr_port));
+                               if (req->ssl)
+                                       ssl_printerr(SSL_get_error
+                                                    (sock->ssl, ret));
+                               sock->status = connect_error;
+                               return -1;
+                       }
+               }
+               break;
+       }
+
+       return 1;
+}
+
+int
+tcp_connect_thread(thread * thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+
+       if ((sock->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+               DBG("WEB connection fail to create socket.\n");
+               return 0;
+       }
+
+       sock->status = tcp_connect(sock->fd, req->addr_ip, req->addr_port);
+
+       /* handle tcp connection status & register check worker thread */
+       tcp_connection_state(sock->fd, sock->status, thread, tcp_check_thread,
+                            HTTP_CNX_TIMEOUT);
+       return 0;
+}
diff --git a/genhash/layer4.h b/genhash/layer4.h
new file mode 100644 (file)
index 0000000..e5a867b
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        layer4.c include file.
+ *
+ * Version:     $Id: layer4.h,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LAYER4_H
+#define _LAYER4_H
+
+/* system includes */
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* local includes */
+#include "scheduler.h"
+
+enum connect_result {
+       connect_error,
+       connect_in_progress,
+       connect_timeout,
+       connect_success
+};
+
+/* Prototypes defs */
+extern enum connect_result
+tcp_connect(int fd, uint32_t, uint16_t);
+
+extern enum connect_result
+tcp_socket_state(int, thread *, uint32_t, uint16_t,
+                int (*func) (struct _thread *));
+
+extern void
+tcp_connection_state(int, enum connect_result
+                    , thread *, int (*func) (struct _thread *)
+                    , int);
+
+extern int
+tcp_connect_thread(thread *);
+
+#endif
index a8885da..491dd42 100644 (file)
@@ -1,15 +1,13 @@
-/* 
- * Soft:        Genhash compute MD5 digest from a HTTP get result. This
- *              program is use to compute hash value that you will add
- *              into the /etc/keepalived/keepalived.conf for HTTP_GET
- *              & SSL_GET keepalive method.
- * 
- * Part:        Main part performing get request and MD5SUM over content.
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        Main entry point.
  *
- * Version:     $Id: main.c,v 0.4.9 2001/11/28 11:50:23 acassen Exp $
+ * Version:     $Id: main.c,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
- *              Jan Holmberg, <jan@artech.se>
  *
  *              This program is distributed in the hope that it will be useful,
  *              but WITHOUT ANY WARRANTY; without even the implied warranty of
  *              2 of the License, or (at your option) any later version.
  */
 
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
 #include "main.h"
-#include "common.h"
-#include "client.h"
-
-/* Dump a buffer (ASCII or Binary) */
-static void
-print_buffer(int count, char *buff)
-{
-       int i, j, c;
-       int printnext = 1;
-
-       if (count % 16)
-               c = count + (16 - count % 16);
-       else
-               c = count;
+#include "utils.h"
+#include "sock.h"
 
-       for (i = 0; i < c; i++) {
-               if (printnext) {
-                       printnext--;
-                       printf("%.4x ", i & 0xffff);
-               }
-               if (i < count)
-                       printf("%3.2x", buff[i] & 0xff);
-               else
-                       printf("   ");
-               if (!((i + 1) % 8)) {
-                       if ((i + 1) % 16)
-                               printf(" -");
-                       else {
-                               printf("   ");
-                               for (j = i - 15; j <= i; j++)
-                                       if (j < count) {
-                                               if ((buff[j] & 0xff) >= 0x20
-                                                   && (buff[j] & 0xff) <= 0x7e)
-                                                       printf("%c",
-                                                              buff[j] & 0xff);
-                                               else
-                                                       printf(".");
-                                       } else
-                                               printf(" ");
-                               printf("\n");
-                               printnext = 1;
-                       }
-               }
-       }
-}
-
-/* Allocate & clean a buffer */
-static char *
-xmalloc(const int size)
-{
-       char *buffer;
-
-       buffer = (char *) malloc(size);
-       if (!buffer)
-               return NULL;
-       memset(buffer, 0, size);
-
-       return buffer;
-}
+/* global var */
+thread_master *master = NULL;
+SOCK *sock = NULL;
 
-/* Return the html header from a global HTTP buffer */
-static char *
-extract_html(char *buffer, int size_buffer)
+/* Terminate handler */
+void
+sigend(int sig)
 {
-       char *end = buffer + size_buffer;
-
-       while (buffer < end && !(*buffer++ == '\n' &&
-                                (*buffer == '\n'
-                                 || (*buffer++ == '\r' && *buffer == '\n')))) ;
-
-       if (*buffer == '\n')
-               return buffer + 1;
-       return NULL;
+       /* register the terminate thread */
+       thread_add_terminate_event(master);
 }
 
-/* Build the GET request */
-static char *
-build_request(REQ * req)
+/* signal wrapper */
+void *
+signal_set(int signo, void (*func) (int))
 {
-       char *request;
-       char *vhost;
-       int request_len = 0;
-
-       request_len = strlen(REQUEST_TEMPLATE) + strlen(req->host) + strlen(req->url) + 5 +     /* characters for port */
-           1;                  /* null terminator     */
-       request = xmalloc(request_len);
-       if (!request)
-               return NULL;
-
-       vhost = req->host;
-       if (req->virtualhost)
-               vhost = req->virtualhost;
-       snprintf(request, request_len, REQUEST_TEMPLATE, req->url, vhost,
-                req->port);
-       return request;
+       int ret;
+       struct sigaction sig;
+       struct sigaction osig;
+
+       sig.sa_handler = func;
+       sigemptyset(&sig.sa_mask);
+       sig.sa_flags = 0;
+#ifdef SA_RESTART
+       sig.sa_flags |= SA_RESTART;
+#endif /* SA_RESTART */
+
+       ret = sigaction(signo, &sig, &osig);
+
+       if (ret < 0)
+               return (SIG_ERR);
+        else
+               return (osig.sa_handler);
 }
 
-static int
-https_request(SSL * ssl, REQ * req)
-{
-       char *request = NULL;
-       int r, i, e = 0;
-       int request_len;
-       char *extracted;
-       unsigned char digest[16];
-       MD5_CTX context;
-
-       /* Build the SSL request */
-       request = build_request(req);
-       if (!request)
-               return OUT_OF_MEMORY;
-       request_len = strlen(request);
-
-       /* Send the SSL request */
-       r = SSL_write(ssl, request, request_len);
-       if (SSL_ERROR_NONE != SSL_get_error(ssl, r)) {
-               free(request);
-               return SSL_WRITE_ERROR;
-       }
-
-       /* Test for eventual imcomplete SSL write */
-       if (request_len != r) {
-               free(request);
-               return SSL_INCOMPLETE_WRITE;
-       }
-
-       /* Init MD5 context */
-       MD5_Init(&context);
-       extracted = NULL;
-       req->len = 0;
-       e = 0;
-
-       /* 
-        * Now read the server's response, assuming
-        * that it's terminated by a close.
-        *
-        * FIXME: Create a function to read data from remote
-        *        server instead of code duplication.
-        */
-       printf(HTTP_HEADER_HEXA);
-
-       while (!e) {
-               r = SSL_read(ssl, req->buffer + req->len, req->max - req->len);
-               e = SSL_get_error(ssl, r);
-               if (e != SSL_ERROR_NONE)
-                       break;
-               if (r > 0 && e == 0) {
-                       req->len += r;
-                       /* Only header yet ? */
-                       if (!extracted) {
-                               /* Found something more than header ? */
-                               if ((extracted =
-                                    extract_html(req->buffer, req->len))) {
-                                       r = req->len - (extracted -
-                                                       req->buffer);
-                                       if (r) {
-                                               print_buffer(r, req->buffer);
-                                               printf(HTTP_HEADER_ASCII);
-                                               for (i = 0;
-                                                    i <
-                                                    extracted - req->buffer;
-                                                    i++)
-                                                       printf("%c",
-                                                              req->buffer[i]);
-                                               printf("\n");
-                                               printf(HTML_HEADER_HEXA);
-                                               memcpy(req->buffer, extracted,
-                                                      r);
-                                               MD5_Update(&context,
-                                                          req->buffer, r);
-                                               r = 0;
-                                       }
-                                       req->len = r;
-                               } else {
-                                       if (req->len > 3) {
-                                               print_buffer(req->len - 3,
-                                                            req->buffer);
-                                               printf(HTTP_HEADER_ASCII);
-                                               for (i = 0; i < req->len - 3;
-                                                    i++)
-                                                       printf("%c",
-                                                              req->buffer[i]);
-                                               printf("\n");
-                                               printf(HTML_HEADER_HEXA);
-                                               memcpy(req->buffer,
-                                                      req->buffer + req->len -
-                                                      3, 3);
-                                               req->len = 3;
-                                       }
-                               }
-                       } else {
-                               if (req->len) {
-                                       print_buffer(req->len, req->buffer);
-                                       MD5_Update(&context, req->buffer,
-                                                  req->len);
-                                       req->len = 0;
-                               }
-                       }
-               }
-       }
-
-       /* Error handling */
-       if (e != SSL_ERROR_ZERO_RETURN && e != SSL_ERROR_SYSCALL) {
-               free(request);
-               return SSL_READ_ERROR;
-       }
-
-       if (e == SSL_ERROR_ZERO_RETURN)
-               if (SSL_shutdown(ssl) != 1) {
-                       free(request);
-                       return SSL_SHUTDOWN_FAILED;
-               }
-
-       if (e != SSL_ERROR_SYSCALL)
-               SSL_free(ssl);
-
-       MD5_Final(digest, &context);
-       printf(HTML_MD5);
-       print_buffer(16, digest);
-
-       printf(HTML_MD5_FINAL);
-       for (r = 0; r < 16; r++)
-               printf("%02x", digest[r]);
-       printf("\n\n");
-
-       free(request);
-       return SSL_GET_SUCCESS;
-}
-
-/*
- * Connect a remote SSL server and generate a MD5SUM
- * Upon the remote HTML content returned.
- */
-static int
-genhash_ssl(REQ * req)
-{
-       SSL_CTX *ctx;
-       SSL *ssl;
-       BIO *sbio;
-       int retcode = 0;
-
-       /* SSL context initialization */
-       ctx = initialize_ctx(req->keyfile, req->password, req->cafile);
-
-       /* TCP socket creation */
-       req->fd = tcp_sock();
-       if (req->fd == -1) {
-               destroy_ctx(ctx);
-               return TCP_BIND_ERROR;
-       }
-
-       /* TCP connect remote host */
-       retcode = tcp_connect(req->fd, req->host, req->port);
-       if (retcode != TCP_CONNECT_SUCCESS)
-               goto end;
-
-       /* Create the SSL context */
-       ssl = SSL_new(ctx);
-       sbio = BIO_new_socket(req->fd, BIO_NOCLOSE);
-       SSL_set_bio(ssl, sbio, sbio);
-
-       /* Connect remote SSL server */
-       if (SSL_connect(ssl) <= 0)
-               return -2;
-
-       /* Proceed the SSL server reply */
-       retcode = https_request(ssl, req);
-
-      end:
-       /* Shutdown the socket */
-       destroy_ctx(ctx);
-       close(req->fd);
-       return (retcode);
-}
-
-/*
- * Connect a remote HTTP server and generate a MD5SUM
- * Upon the remote HTML content returned.
- */
-static int
-genhash_http(REQ * req)
+/* Initialize signal handler */
+void
+signal_init(void)
 {
-       int request_len = 0;
-       char *request = NULL;
-       char *buffertmp = NULL;
-       int retcode = 0;
-       int r;
-       char *extracted;
-       unsigned char digest[16];
-       MD5_CTX context;
-
-       /* Temporary get buffer allocation */
-       buffertmp = xmalloc(RCV_BUFFER_LENGTH);
-       if (!buffertmp) {
-               free(request);
-               return OUT_OF_MEMORY;
-       }
-
-       /* Build the HTTP request */
-       request = build_request(req);
-       if (!request) {
-               free(buffertmp);
-               return OUT_OF_MEMORY;
-       }
-       request_len = strlen(request);
-
-       /* TCP socket creation */
-       req->fd = tcp_sock();
-       if (req->fd == -1) {
-               free(request);
-               free(buffertmp);
-               return TCP_BIND_ERROR;
-       }
-
-       /* TCP connect remote host */
-       retcode = tcp_connect(req->fd, req->host, req->port);
-       if (retcode != TCP_CONNECT_SUCCESS)
-               goto error;
-
-       /* Send the HTTP request */
-       retcode = tcp_send(req->fd, request, request_len);
-       if (retcode == TCP_SEND_ERROR)
-               goto error;
-
-       /* Proceed the HTTP server reply */
-       retcode = tcp_read_to(req->fd);
-       if (retcode == TCP_READ_TIMEOUT)
-               goto error;
-
-       MD5_Init(&context);
-       extracted = NULL;
-       req->len = 0;
-
-       /* 
-        * Now read the server's response.
-        *
-        * FIXME: Create a function to read data from remote
-        *        server instead of code duplication.
-        */
-       printf(HTTP_HEADER_HEXA);
-       while (1) {
-               r = read(req->fd, buffertmp, RCV_BUFFER_LENGTH);
-               if (r == -1 || r == 0)
-                       break;
-               memcpy(req->buffer + req->len, buffertmp, r);
-               req->len += r;
-               if (!extracted &&
-                   (extracted = extract_html(req->buffer, req->len))) {
-                       print_buffer(extracted - req->buffer, req->buffer);
-                       printf(HTTP_HEADER_ASCII);
-                       for (r = 0; r < extracted - req->buffer; r++)
-                               printf("%c", req->buffer[r]);
-                       printf("\n");
-
-                       printf(HTML_HEADER_HEXA);
-                       r = req->len - (extracted - req->buffer);
-                       if (r)
-                               memcpy(req->buffer, extracted, r);
-                       req->len = r;
-               }
-
-               if (extracted && req->len) {
-                       print_buffer(req->len, req->buffer);
-                       MD5_Update(&context, req->buffer, req->len);
-                       req->len = 0;
-               }
-       }
-
-       MD5_Final(digest, &context);
-       printf(HTML_MD5);
-       print_buffer(16, digest);
-
-       printf(HTML_MD5_FINAL);
-       for (r = 0; r < 16; r++)
-               printf("%02x", digest[r]);
-       printf("\n\n");
-
-       /* All is fine just return a success code */
-       retcode = HTTP_GET_SUCCESS;
-
-      error:
-       close(req->fd);
-       free(request);
-       free(buffertmp);
-       return (retcode);
+       signal_set(SIGHUP, sigend);
+       signal_set(SIGINT, sigend);
+       signal_set(SIGTERM, sigend);
+       signal_set(SIGKILL, sigend);
 }
 
-/* Error return function */
-static void
-print_error(int err)
-{
-       switch (err) {
-               /* System errors */
-       case OUT_OF_MEMORY:
-               err_exit("Out Of Memery");
-               break;
-
-               /* TCP errors */
-       case TCP_BIND_ERROR:
-               err_exit("TCP Bind error");
-               break;
-       case TCP_RESOLV_ERROR:
-               err_exit("TCP Resolv error");
-               break;
-       case TCP_CONNECT_ERROR:
-               err_exit("TCP Connect error");
-               break;
-       case TCP_WRITE_TIMEOUT:
-               err_exit("TCP Write TimeOut");
-               break;
-       case TCP_READ_TIMEOUT:
-               err_exit("TCP Read error");
-               break;
-       case TCP_SELECT_ERROR:
-               err_exit("TCP Select error");
-               break;
-       case TCP_CONNECT_FAILED:
-               err_exit("TCP Connectin failed");
-               break;
-       case TCP_SEND_ERROR:
-               err_exit("TCP Send error");
-               break;
-
-               /* SSL errors */
-       case SSL_WRITE_ERROR:
-               err_exit("SSL Write error");
-               break;
-       case SSL_INCOMPLETE_WRITE:
-               err_exit("SSL Incomplete write");
-               break;
-       case SSL_READ_ERROR:
-               err_exit("SSL Read error");
-               break;
-       case SSL_SHUTDOWN_FAILED:
-               err_exit("SSL Shutdown failed");
-               break;
-       }
-}
 
 /* Usage function */
 static void
 usage(const char *prog)
 {
-       fprintf(stderr, "%s Version %s\n", PROG, VERSION);
+       fprintf(stderr, VERSION_STRING);
        fprintf(stderr,
                "Usage:\n"
                "  %s -s server-address -p port -u url\n"
-               "  %s -S -K priv-key-file -P pem-password -s server-address -p port -u url\n"
-               "  %s -S -K priv-key-file -P pem-password -C cert-file -s server-address -p port -u url\n"
-               "  %s -h\n" "  %s -v\n\n", prog, prog, prog, prog, prog);
+               "  %s -S -s server-address -p port -u url\n"
+               "  %s -h\n" "  %s -r\n\n", prog, prog, prog, prog);
        fprintf(stderr,
                "Commands:\n"
                "Either long or short options are allowed.\n"
@@ -480,13 +90,11 @@ usage(const char *prog)
                "  %s --server          -s       Use the specified remote server address.\n"
                "  %s --port            -p       Use the specified remote server port.\n"
                "  %s --url             -u       Use the specified remote server url.\n"
-               "  %s --use-private-key -K       Use the specified SSL private key.\n"
-               "  %s --use-password    -P       Use the specified SSL private key password.\n"
-               "  %s --use-virtualhost -V       Use the specified VirtualHost GET query.\n"
-               "  %s --use-certificate -C       Use the specified SSL Certificate file.\n"
+               "  %s --use-virtualhost -V       Use the specified virtualhost in GET query.\n"
+               "  %s --verbose         -v       Use verbose mode output.\n"
                "  %s --help            -h       Display this short inlined help screen.\n"
-               "  %s --version         -v       Display the version number\n",
-               prog, prog, prog, prog, prog, prog, prog, prog, prog, prog);
+               "  %s --release         -r       Display the release number\n",
+               prog, prog, prog, prog, prog, prog, prog, prog);
 }
 
 /* Command line parser */
@@ -498,19 +106,18 @@ parse_cmdline(int argc, char **argv, REQ * req)
        int c;
 
        struct poptOption options_table[] = {
-               {"version", 'v', POPT_ARG_NONE, NULL, 'v'},
+               {"release", 'r', POPT_ARG_NONE, NULL, 'r'},
                {"help", 'h', POPT_ARG_NONE, NULL, 'h'},
+               {"verbose", 'v', POPT_ARG_NONE, NULL, 'v'},
                {"use-ssl", 'S', POPT_ARG_NONE, NULL, 'S'},
                {"server", 's', POPT_ARG_STRING, &optarg, 's'},
                {"port", 'p', POPT_ARG_STRING, &optarg, 'p'},
                {"url", 'u', POPT_ARG_STRING, &optarg, 'u'},
-               {"use-private-key", 'K', POPT_ARG_STRING, &optarg, 'K'},
                {"use-virtualhost", 'V', POPT_ARG_STRING, &optarg, 'V'},
-               {"use-password", 'P', POPT_ARG_STRING, &optarg, 'P'},
-               {"use-certificate", 'C', POPT_ARG_STRING, &optarg, 'C'},
                {NULL, 0, 0, NULL, 0}
        };
 
+       /* Parse the command line arguments */
        context =
            poptGetContext(PROG, argc, (const char **) argv, options_table, 0);
        if ((c = poptGetNextOpt(context)) < 0) {
@@ -520,17 +127,23 @@ parse_cmdline(int argc, char **argv, REQ * req)
 
        /* The first option car */
        switch (c) {
-       case 'v':
-               fprintf(stderr, "%s Version %s\n", PROG, VERSION);
+       case 'r':
+               fprintf(stderr, VERSION_STRING);
                break;
        case 'h':
                usage(argv[0]);
                break;
+       case 'v':
+               req->verbose = 1;
+               break;
        case 'S':
                req->ssl = 1;
                break;
        case 's':
-               req->host = optarg;
+               inet_ston(optarg, &req->addr_ip);
+               break;
+       case 'V':
+               req->vhost = optarg;
                break;
        default:
                usage(argv[0]);
@@ -540,27 +153,24 @@ parse_cmdline(int argc, char **argv, REQ * req)
        /* the others */
        while ((c = poptGetNextOpt(context)) >= 0) {
                switch (c) {
+               case 'v':
+                       req->verbose = 1;
+                       break;
+               case 'S':
+                       req->ssl = 1;
+                       break;
                case 's':
-                       req->host = optarg;
+                       inet_ston(optarg, &req->addr_ip);
+                       break;
+               case 'V':
+                       req->vhost = optarg;
                        break;
                case 'p':
-                       req->port = atoi(optarg);
+                       req->addr_port = htons(atoi(optarg));
                        break;
                case 'u':
                        req->url = optarg;
                        break;
-               case 'K':
-                       req->keyfile = optarg;
-                       break;
-               case 'P':
-                       req->password = optarg;
-                       break;
-               case 'V':
-                       req->virtualhost = optarg;
-                       break;
-               case 'C':
-                       req->cafile = optarg;
-                       break;
                default:
                        usage(argv[0]);
                        return CMD_LINE_ERROR;
@@ -582,31 +192,55 @@ parse_cmdline(int argc, char **argv, REQ * req)
 int
 main(int argc, char **argv)
 {
-       REQ *req;
-       char *buffer;
-       int err = 0;
+       thread thread;
 
        /* Allocate the room */
-       req = (REQ *) xmalloc(sizeof (REQ));
-       buffer = (char *) xmalloc(RCV_BUFFER_LENGTH);
+       req = (REQ *) MALLOC(sizeof (REQ));
 
        /* Command line parser */
-       if (!parse_cmdline(argc, argv, req))
+       if (!parse_cmdline(argc, argv, req)) {
+               FREE(req);
                exit(0);
+       }
 
        /* Check minimum configuration need */
-       if (!req->host && !req->port && !req->url) {
+       if (!req->addr_ip && !req->addr_port && !req->url) {
+               FREE(req);
                exit(0);
        }
 
-       /* finalize req initialisation  */
-       req->buffer = buffer;
-       req->max = RCV_BUFFER_LENGTH;
+       /* Init the reference timer */
+       req->ref_time = timer_tol(timer_now());
+       DBG("Reference timer = %lu\n", req->ref_time);
 
-       /* Now make our HTTP/SSL request */
-       err = req->ssl ? genhash_ssl(req) : genhash_http(req);
-       print_error(err);
+       /* Init SSL context */
+       init_ssl();
 
-       free(req);
-       return (1);
+       /* Signal handling initialization  */
+       signal_init();
+       
+       /* Create the master thread */
+       master = thread_make_master();
+
+       /* Register the GET request */
+       init_sock();
+
+       /*
+        * Processing the master thread queues,
+        * return and execute one ready thread.
+        * Run until error, used for debuging only.
+        */
+       while (thread_fetch(master, &thread))
+               thread_call(&thread);
+
+       /* Finalize output informations */
+       if (req->verbose)
+               printf("Global response time for [%s] =%lu\n",
+                      req->url, req->response_time-req->ref_time);
+
+       /* exit cleanly */
+       SSL_CTX_free(req->ctx);
+       free_sock(sock);
+       FREE(req);
+       exit(0);
 }
index ee29905..4ced6e2 100644 (file)
@@ -1,15 +1,13 @@
 /*
- * Soft:        Genhash compute MD5 digest from a HTTP get result. This
- *              program is use to compute hash value that you will add
- *              into the /etc/keepalived/keepalived.conf for HTTP_GET
- *              & SSL_GET keepalive method.
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
  *
  * Part:        main.c include file.
  *
- * Version:     $Id: main.h,v 0.4.9 2001/11/28 11:50:23 acassen Exp $
+ * Version:     $Id: main.h,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
- *              Jan Holmberg, <jan@artech.se>
  *
  *              This program is distributed in the hope that it will be useful,
  *              but WITHOUT ANY WARRANTY; without even the implied warranty of
 #ifndef _MAIN_H
 #define _MAIN_H
 
+/* global includes */
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <errno.h>
-#include <openssl/md5.h>
 #include <popt.h>
+#include <openssl/ssl.h>
+
+/* local includes */
+#include "memory.h"
+#include "timer.h"
+#include "http.h"
+#include "ssl.h"
+#include "list.h"
 
 /* Build version */
 #define PROG    "genhash"
-#define VERSION "0.6.2 (06/14, 2002)"
 
-/* HTTP/HTTPS GET command */
-#define REQUEST_TEMPLATE "GET %s HTTP/1.0\r\n" \
-                         "User-Agent:KeepAliveClient\r\n" \
-                         "Host: %s:%d\r\n\r\n"
+#define VERSION_CODE 0x010000
+#define DATE_CODE    0x120b02
+
+#define GETMETER_VERSION(version)      \
+        (version >> 16) & 0xFF,                \
+        (version >> 8) & 0xFF,         \
+        version & 0xFF
+
+#define VERSION_STRING PROG" v%d.%d.%d (%.2d/%.2d, 20%.2d)\n", \
+                GETMETER_VERSION(VERSION_CODE),                        \
+                GETMETER_VERSION(DATE_CODE)
 
 /* HTTP/HTTPS request structure */
 typedef struct {
-       char *host;
-       char *buffer;
-       int error;
-       int max;
-       int len;
+       uint32_t addr_ip;
+       uint16_t addr_port;
        char *url;
-       unsigned short int port;
-       int fd;
+       char *vhost;
+       int verbose;
        int ssl;
-       char *keyfile;
-       char *password;
-       char *virtualhost;
-       char *cafile;
+       SSL_CTX *ctx;
+       SSL_METHOD *meth;
+       unsigned long ref_time;
+       unsigned long response_time;
 } REQ;
 
-/* Output delimiters */
-#define DELIM_BEGIN "-----------------------["
-#define DELIM_END   "]-----------------------\n"
-#define HTTP_HEADER_HEXA  DELIM_BEGIN"    HTTP Header Buffer    "DELIM_END
-#define HTTP_HEADER_ASCII DELIM_BEGIN" HTTP Header Ascii Buffer "DELIM_END
-#define HTML_HEADER_HEXA  DELIM_BEGIN"       HTML Buffer        "DELIM_END
-#define HTML_MD5          DELIM_BEGIN"    HTML MD5 resulting    "DELIM_END
-#define HTML_MD5_FINAL    DELIM_BEGIN" HTML MD5 final resulting "DELIM_END
+/* Global variables */
+REQ *req;                              /* Cmd line arguments */
 
 /* Data buffer length description */
-#define RCV_BUFFER_LENGTH   512
 #define BUFSIZE             1024
 
 /* Command line error handling */
diff --git a/genhash/sock.c b/genhash/sock.c
new file mode 100644 (file)
index 0000000..02b6fc4
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        Socket pool utility functions.
+ *
+ * Version:     $Id: sock.c,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#include <string.h>
+#include "memory.h"
+#include "utils.h"
+#include "list.h"
+#include "sock.h"
+#include "layer4.h"
+#include "ssl.h"
+#include "main.h"
+
+/* extern var */
+extern thread_master *master;
+extern SOCK *sock;
+
+/* Close the descriptor */
+static void close_sock(SOCK *sock)
+{
+       if (sock->ssl) {
+               SSL_shutdown(sock->ssl);
+               SSL_free(sock->ssl);
+       }
+       close(sock->fd);
+}
+
+/* Destroy the socket handler */
+void free_sock(SOCK *sock)
+{
+       DBG("Freeing fd:%d\n", sock->fd);
+
+       close_sock(sock);
+       FREE(sock);
+}
+
+/* Init socket handler */
+void init_sock(void)
+{
+       sock = (SOCK *)MALLOC(sizeof(SOCK));
+       memset(sock, 0, sizeof(SOCK));
+       thread_add_event(master, tcp_connect_thread,
+                        sock, 0);
+}
diff --git a/genhash/sock.h b/genhash/sock.h
new file mode 100644 (file)
index 0000000..43baa5a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        sock.c include file.
+ *
+ * Version:     $Id: sock.h,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _SOCK_H
+#define _SOCK_H
+
+/* system includes */
+#include <openssl/ssl.h>
+#include <openssl/md5.h>
+
+/* Engine socket pool element structure */
+typedef struct {
+       int fd;
+       SSL *ssl;
+       BIO *bio;
+       MD5_CTX context;
+       int status;
+       int lock;
+       char *buffer;
+       char *extracted;
+       int size;
+       int total_size;
+} SOCK;
+
+/* Prototypes */
+extern void free_sock(SOCK *sock);
+extern void init_sock(void);
+
+#endif
diff --git a/genhash/ssl.c b/genhash/ssl.c
new file mode 100644 (file)
index 0000000..9bf0304
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        SSL engine. 'Semi' asyncrhonous stream handling.
+ *
+ * Version:     $Id: ssl.c,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#include <openssl/err.h>
+#include "main.h"
+#include "sock.h"
+#include "http.h"
+#include "ssl.h"
+#include "utils.h"
+#include "html.h"
+
+/* extern variables */
+extern REQ *req;
+
+/*
+ * Initialize the SSL context, with or without specific
+ * configuration files.
+ */
+static BIO *bio_err = 0;
+void
+init_ssl(void)
+{
+       /* Library initialization */
+       SSL_library_init();
+
+       SSL_load_error_strings();
+       bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+       /* Initialize SSL context for SSL v2/3 */
+       req->meth = SSLv23_method();
+       req->ctx = SSL_CTX_new(req->meth);
+
+#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
+       SSL_CTX_set_verify_depth(req->ctx, 1);
+#endif
+}
+
+/* Display SSL error to readable string */
+int
+ssl_printerr(int err)
+{
+       unsigned long extended_error = 0;
+       char *ssl_strerr;
+
+       switch (err) {
+       case SSL_ERROR_ZERO_RETURN:
+               fprintf(stderr, "  SSL error: (zero return)\n");
+               break;
+       case SSL_ERROR_WANT_READ:
+               fprintf(stderr, "  SSL error: (read error)\n");
+               break;
+       case SSL_ERROR_WANT_WRITE:
+               fprintf(stderr, "  SSL error: (write error)\n");
+               break;
+       case SSL_ERROR_WANT_CONNECT:
+               fprintf(stderr, "  SSL error: (connect error)\n");
+               break;
+       case SSL_ERROR_WANT_X509_LOOKUP:
+               fprintf(stderr, "  SSL error: (X509 lookup error)\n");
+               break;
+       case SSL_ERROR_SYSCALL:
+               fprintf(stderr, "  SSL error: (syscall error)\n");
+               break;
+       case SSL_ERROR_SSL:{
+                       ssl_strerr = (char *) MALLOC(500);
+
+                       extended_error = ERR_get_error();
+                       ERR_error_string(extended_error, ssl_strerr);
+                       fprintf(stderr, "  SSL error: (%s)\n", ssl_strerr);
+                       FREE(ssl_strerr);
+                       break;
+               }
+       }
+       return 0;
+}
+
+int
+ssl_connect(thread * thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+       int ret;
+
+       sock->ssl = SSL_new(req->ctx);
+       sock->bio = BIO_new_socket(sock->fd, BIO_NOCLOSE);
+       BIO_set_nbio(sock->bio, 1);     /* Set the Non-Blocking flag */
+       SSL_set_bio(sock->ssl, sock->bio, sock->bio);
+       ret = SSL_connect(sock->ssl);
+
+       DBG("  SSL_connect return code = %d on fd:%d\n",
+           ret, thread->u.fd);
+       ssl_printerr(SSL_get_error(sock->ssl, ret));
+
+       return (ret > 0) ? 1 : 0;
+}
+
+int
+ssl_send_request(SSL * ssl, char *str_request, int request_len)
+{
+       int err, r = 0;
+
+       while (1) {
+               err = 1;
+               r = SSL_write(ssl, str_request, request_len);
+               if (SSL_ERROR_NONE != SSL_get_error(ssl, r))
+                       break;
+               err++;
+               if (request_len != r)
+                       break;
+               err++;
+               break;
+       }
+
+       return (err == 3) ? 1 : 0;
+}
+
+/* Asynchronous SSL stream reader */
+int
+ssl_read_thread(thread * thread)
+{
+       SOCK *sock = THREAD_ARG(thread);
+       int r = 0;
+       int error;
+
+       /* Handle read timeout */
+       if (thread->type == THREAD_READ_TIMEOUT)
+               return epilog(thread);
+
+       /*
+        * The design implemented here is a workaround for use
+        * with OpenSSL. This goto loop is a 'read until not
+        * end of stream'. But this break a little our global
+        * I/O multiplexer thread framework because it enter
+        * a synchronous read process for each GET reply.
+        * Sound a little nasty !.
+        * 
+        * Why OpenSSL doesn t handle underlying fd. This
+        * break the I/O (select()) approach !...
+        * If you read this and know the answer, please reply
+        * I am probably missing something... :)
+        * My test show that sometime it return from select,
+        * and sometime not...
+        */
+
+read_stream:
+
+       /* read the SSL stream */
+       memset(sock->buffer, 0, MAX_BUFFER_LENGTH);
+       r = SSL_read(sock->ssl, sock->buffer, MAX_BUFFER_LENGTH);
+       error = SSL_get_error(sock->ssl, r);
+
+       DBG(" [l:%d,fd:%d]\n", r, sock->fd);
+
+       if (error) {
+               /* All the SSL streal has been parsed */
+               /* Handle response stream */
+               if (error != SSL_ERROR_NONE)
+                       return finalize(thread);
+       } else if (r > 0 && error == 0) {
+
+               /* Handle the response stream */
+               http_process_stream(sock, r);
+
+               /*
+                * Register next ssl stream reader.
+                * Register itself to not perturbe global I/O multiplexer.
+                */
+               goto read_stream;
+       }
+
+       return 0;
+}
diff --git a/genhash/ssl.crt b/genhash/ssl.crt
deleted file mode 100644 (file)
index a8fc8bd..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICoDCCAgmgAwIBAgIBADANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJBVTET
-MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMB4XDTAxMTEyODE1MzcwMFoXDTAxMTIyODE1MzcwMFowRTELMAkGA1UE
-BhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdp
-ZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqaHao73f
-HpyErd5yhBcY9MS0oN0uHFtSXsz63VXjfEwhl/7bgaw+9qR1a/iY8lW7NL7yON+9
-6o1wToTV/8gDs19rlUY+tpFiIsJzHUO2Xknnyp87dUPOU+bNu+r525DVnTvf4uxV
-6H56CPqqGDYKpG1dyjDtdiTgayIcehQNsiECAwEAAaOBnzCBnDAdBgNVHQ4EFgQU
-E3xmxdjFNxXJLa/NlzpeQtqwNZcwbQYDVR0jBGYwZIAUE3xmxdjFNxXJLa/Nlzpe
-QtqwNZehSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEw
-HwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCAQAwDAYDVR0TBAUwAwEB
-/zANBgkqhkiG9w0BAQQFAAOBgQCMAF/IJrmL7wSdY/YWjbj8+PKzIMzJmz6w6c8V
-LhbLHYreMurG5830Ljnd1udm7o7g+16qLNfq0rEwrWhnxDnC1Id8nHXxhUHO6IEg
-YDPBWMte7zOC7skgDzvJc585HiMNxXEuX1pwnBvHv+qqu36TtVZSXeOKZcOOmkwE
-eY40Bg==
------END CERTIFICATE-----
diff --git a/genhash/ssl.csr b/genhash/ssl.csr
deleted file mode 100644 (file)
index 70c01d3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN CERTIFICATE REQUEST-----
-MIIBhDCB7gIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEh
-MB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEB
-AQUAA4GNADCBiQKBgQCpodqjvd8enISt3nKEFxj0xLSg3S4cW1JezPrdVeN8TCGX
-/tuBrD72pHVr+JjyVbs0vvI4373qjXBOhNX/yAOzX2uVRj62kWIiwnMdQ7ZeSefK
-nzt1Q85T5s276vnbkNWdO9/i7FXofnoI+qoYNgqkbV3KMO12JOBrIhx6FA2yIQID
-AQABoAAwDQYJKoZIhvcNAQEEBQADgYEAJr5QWBjpWL1qsrHaNAP+qP17IAUWuZsz
-Zdy72zGnQcsrk3mn6b1z9OS7WOPKcKkSq2q1+DlQS7vfhPaYRM1g/sqOMbnPv+MJ
-CCvHvBcI+nKBjUS7WofEuZSvVzo8bdwoVyYLdQWKFi6w3Z+O8D3YxRlvXseWWOkI
-lj4W75ypRVU=
------END CERTIFICATE REQUEST-----
diff --git a/genhash/ssl.h b/genhash/ssl.h
new file mode 100644 (file)
index 0000000..9e8b6ec
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        ssl.c include file.
+ *
+ * Version:     $Id: ssl.h,v 1.0.0 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _SSL_H
+#define _SSL_H
+
+#include <openssl/ssl.h>
+
+/* Prototypes */
+extern void init_ssl(void);
+extern int ssl_connect(thread * thread);
+extern int ssl_printerr(int err);
+extern int ssl_send_request(SSL * ssl, char *str_request, int request_len);
+extern int ssl_read_thread(thread * thread);
+
+#endif
diff --git a/genhash/ssl.key b/genhash/ssl.key
deleted file mode 100644 (file)
index 0e250fe..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,45FBDBEBCB52B1ED
-
-q6RONp0/s4kRRhz1n//irIU+QIed+F0Vu7ijixGARCJkkp+ZoXbGqOYwLJXjJXtH
-iC08SodwhFZLdLgCTttTn6IZvKR6Ye0K6or0JvSLQ+3+qdDy7GmgEnctPhE7j4Nk
-ptZejNPjjauh5tpu/rrIIq14ApE0zDuJpx97co4/i7VrGpB/HVVtJ61As3ry4aRL
-T8WvuQEIM5TLKC8tSxPb8rQKM5soY2IHd+GmMgYkiNg+Vcg6I7N34EQkse0CHNxA
-PUl2kPwP9kg981mR/xks22oNNM5AAkTuWXB8R3zDuyaVdYcpbSEiOeOBMPFo43CR
-yFsYRVOer9Dp97KSkYQ3VOwoYil2m6ddrpYBr9qDZ/PF9VBhdrJT37rA73+1V6AO
-YFkQvbWiL/SUsvByXFHes68Y09fCHkbCkbtY3tNvTK8Z37iI6ZuTPdBIYblTRYil
-51RDJkrCuUyLx3dzkPxQqq1nkBRx9QLz2DaY0xRc9PEgM01C/Q5T/7mwosSsE/zZ
-5oJB3upN8/1kmy+gTLLoE5kSyEZup8NsEHEqhU1z2z+t6DKOnFR8eg0YXdItIfHP
-y7QNKmFaSghtkNPQUrXz/s4Bh/9bEAicIOjj6Om2uVKG0vXEa+0b+Qz8sUcHvFB+
-IX2NJUCmFQgjFt6a3IYo6P0ajLy1g/ES+nPWwjYAMVXe0RHrB+Q0pwib9koWGvZN
-4N2xti19DEdKBNMgWRo7SBzTNtkv5Eo6btLw4M9oeqonC1YJfGThFUSssyC5ZCcY
-H+QeYs48mWoQwXwAufOr8CwALLmeAGhgBiIy6dcbvHpO7IQzTRRcIA==
------END RSA PRIVATE KEY-----
diff --git a/genhash/ssl.pem b/genhash/ssl.pem
deleted file mode 100644 (file)
index 71dcd6f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,45FBDBEBCB52B1ED
-
-q6RONp0/s4kRRhz1n//irIU+QIed+F0Vu7ijixGARCJkkp+ZoXbGqOYwLJXjJXtH
-iC08SodwhFZLdLgCTttTn6IZvKR6Ye0K6or0JvSLQ+3+qdDy7GmgEnctPhE7j4Nk
-ptZejNPjjauh5tpu/rrIIq14ApE0zDuJpx97co4/i7VrGpB/HVVtJ61As3ry4aRL
-T8WvuQEIM5TLKC8tSxPb8rQKM5soY2IHd+GmMgYkiNg+Vcg6I7N34EQkse0CHNxA
-PUl2kPwP9kg981mR/xks22oNNM5AAkTuWXB8R3zDuyaVdYcpbSEiOeOBMPFo43CR
-yFsYRVOer9Dp97KSkYQ3VOwoYil2m6ddrpYBr9qDZ/PF9VBhdrJT37rA73+1V6AO
-YFkQvbWiL/SUsvByXFHes68Y09fCHkbCkbtY3tNvTK8Z37iI6ZuTPdBIYblTRYil
-51RDJkrCuUyLx3dzkPxQqq1nkBRx9QLz2DaY0xRc9PEgM01C/Q5T/7mwosSsE/zZ
-5oJB3upN8/1kmy+gTLLoE5kSyEZup8NsEHEqhU1z2z+t6DKOnFR8eg0YXdItIfHP
-y7QNKmFaSghtkNPQUrXz/s4Bh/9bEAicIOjj6Om2uVKG0vXEa+0b+Qz8sUcHvFB+
-IX2NJUCmFQgjFt6a3IYo6P0ajLy1g/ES+nPWwjYAMVXe0RHrB+Q0pwib9koWGvZN
-4N2xti19DEdKBNMgWRo7SBzTNtkv5Eo6btLw4M9oeqonC1YJfGThFUSssyC5ZCcY
-H+QeYs48mWoQwXwAufOr8CwALLmeAGhgBiIy6dcbvHpO7IQzTRRcIA==
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIICoDCCAgmgAwIBAgIBADANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJBVTET
-MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMB4XDTAxMTEyODE1MzcwMFoXDTAxMTIyODE1MzcwMFowRTELMAkGA1UE
-BhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdp
-ZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqaHao73f
-HpyErd5yhBcY9MS0oN0uHFtSXsz63VXjfEwhl/7bgaw+9qR1a/iY8lW7NL7yON+9
-6o1wToTV/8gDs19rlUY+tpFiIsJzHUO2Xknnyp87dUPOU+bNu+r525DVnTvf4uxV
-6H56CPqqGDYKpG1dyjDtdiTgayIcehQNsiECAwEAAaOBnzCBnDAdBgNVHQ4EFgQU
-E3xmxdjFNxXJLa/NlzpeQtqwNZcwbQYDVR0jBGYwZIAUE3xmxdjFNxXJLa/Nlzpe
-QtqwNZehSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEw
-HwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCAQAwDAYDVR0TBAUwAwEB
-/zANBgkqhkiG9w0BAQQFAAOBgQCMAF/IJrmL7wSdY/YWjbj8+PKzIMzJmz6w6c8V
-LhbLHYreMurG5830Ljnd1udm7o7g+16qLNfq0rEwrWhnxDnC1Id8nHXxhUHO6IEg
-YDPBWMte7zOC7skgDzvJc585HiMNxXEuX1pwnBvHv+qqu36TtVZSXeOKZcOOmkwE
-eY40Bg==
------END CERTIFICATE-----
index 76635a3..8348cf2 100644 (file)
@@ -1,9 +1,9 @@
 Summary: Generic HA monitor build upon VRRP and services poller, strongly recommanded for LVS HA.
 Name: keepalived
 Packager: Christophe Varoqui, <christophe.varoqui@free.fr>
-Version: 0.7.1
+Version: 0.7.6
 Release: 1
-Source: http://www.keepalived.org/software/keepalived-0.7.1.tar.gz
+Source: http://www.keepalived.org/software/keepalived-0.7.6.tar.gz
 Copyright: GPL
 Group: Utilities/File
 BuildRoot: /tmp/%{name}-%{version}.build
@@ -14,7 +14,7 @@ The main goal of the keepalived project is to add a strong & robust keepalive fa
 
 %prep
 rm -rf %{buildroot}
-%setup -n keepalived-0.7.1
+%setup -n keepalived-0.7.6
 
 %build
 ./configure --prefix=%{buildroot} --exec-prefix=%{buildroot} --sysconfdir=%{buildroot}/etc
index 0924806..eb0a998 100644 (file)
@@ -42,7 +42,7 @@ all:
        for i in $(SUBDIRS); do \
        $(MAKE) -C $$i || exit 1; done && \
        echo "Building $(BIN)/$(EXEC)" && \
-       $(CC) -o $(BIN)/$(EXEC) $(LDFLAGS) `find $(SUBDIRS) -name '*.[oa]'`
+       $(CC) -o $(BIN)/$(EXEC) $(LDFLAGS) `find $(SUBDIRS) ../lib -name '*.[oa]'`
        strip $(BIN)/$(EXEC)
        @echo ""
        @echo "Make complete"
index ec5c89a..c0c12e6 100644 (file)
@@ -5,15 +5,13 @@
 # Copyright (C) 2001, 2002 Alexandre Cassen, <acassen@linux-vs.org>
 
 CC      = @CC@
-INCLUDES = -I../include
+INCLUDES = -I../include -I../../lib
 CFLAGS  = @CFLAGS@ $(INCLUDES) \
           -Wall -Wunused -Wstrict-prototypes
 DEFS    = -D@KERN@ -D@IPVS_SUPPORT@ -D@VRRP_SUPPORT@ @DFLAGS@
 COMPILE         = $(CC) $(CFLAGS) $(DEFS)
 
-OBJS =         main.o memory.o daemon.o pidfile.o utils.o timer.o \
-       scheduler.o vector.o list.o data.o parser.o layer4.o \
-       smtp.o
+OBJS =         main.o daemon.o pidfile.o data.o parser.o layer4.o smtp.o
 HEADERS = $(OBJS:.o=.h)
 
 .c.o:
@@ -29,20 +27,13 @@ distclean: clean
 
 
 main.o: main.c ../include/main.h
-memory.o: memory.c ../include/memory.h
 daemon.o: daemon.c ../include/daemon.h
 pidfile.o: pidfile.c ../include/pidfile.h
-utils.o: utils.c ../include/utils.h
-timer.o: timer.c ../include/timer.h
-scheduler.o: scheduler.c ../include/scheduler.h ../include/memory.h \
-  ../include/utils.h
-vector.o: vector.c ../include/vector.h ../include/memory.h
-list.o: list.c ../include/list.h ../include/memory.h
-data.o: data.c ../include/data.h ../include/memory.h ../include/utils.h \
+data.o: data.c ../include/data.h ../../lib/memory.h ../../lib/utils.h \
   ../include/check_api.h ../include/vrrp.h ../include/vrrp_sync.h
-parser.o: parser.c ../include/parser.h ../include/memory.h ../include/vrrp.h \
+parser.o: parser.c ../include/parser.h ../../lib/memory.h ../include/vrrp.h \
   ../include/vrrp_if.h ../include/check_api.h
-layer4.o: layer4.c ../include/layer4.h ../include/check_api.h ../include/utils.h
-smtp.o: smtp.c ../include/smtp.h ../include/memory.h ../include/list.h \
-  ../include/utils.h
+layer4.o: layer4.c ../include/layer4.h ../include/check_api.h ../../lib/utils.h
+smtp.o: smtp.c ../include/smtp.h ../../lib/memory.h ../../lib/list.h \
+  ../../lib/utils.h
 
index e068110..f2027b3 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: main.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index fe76851..18e8955 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: data.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: data.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index a6b854f..fa65574 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        Layer4 checkers handling. Register worker threads &
  *              upper layer checkers.
  *
- * Version:     $Id: layer4.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: layer4.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index c4f9929..5fe5d78 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: main.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -356,6 +356,7 @@ int
 main(int argc, char **argv)
 {
        /* Init debugging level */
+       mem_allocated = 0;
        debug = 0;
 
        /*
index d17befc..3721cba 100644 (file)
@@ -7,7 +7,7 @@
  *              data structure representation the conf file representing
  *              the loadbalanced server pool.
  *  
- * Version:     $Id: parser.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: parser.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index a80849a..31a879d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile utility.
  *
- * Version:     $Id: pidfile.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: pidfile.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index bf24d8b..8f8ec49 100644 (file)
@@ -7,7 +7,7 @@
  *              using the smtp protocol according to the RFC 821. A non blocking
  *              timeouted connection is used to handle smtp protocol.
  *
- * Version:     $Id: smtp.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: smtp.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 5c025db..a782daf 100644 (file)
@@ -11,7 +11,7 @@ ifeq ($(CI_LINUX),_WITH_CI_LINUX_)
 CI_LINUX_OBJ = check_ci.o
 CIFLAGS = -D$(CI_LINUX)
 endif
-INCLUDES = -I../include
+INCLUDES = -I../include -I../../lib
 CFLAGS  = @CFLAGS@ $(INCLUDES) \
           -Wall -Wunused -Wstrict-prototypes
 DEFS    = -D$(KERNEL) -D@IPVS_SUPPORT@ -D@IPVS_SYNCD@ -D@VRRP_SUPPORT@ @DFLAGS@ $(CIFLAGS)
@@ -39,20 +39,20 @@ distclean: clean
        rm -f Makefile
 
 check_api.o: check_api.c ../include/check_api.h ../include/parser.h \
-  ../include/memory.h ../include/utils.h ../include/check_misc.h \
+  ../../lib/memory.h ../../lib/utils.h ../include/check_misc.h \
   ../include/check_tcp.h ../include/check_http.h ../include/check_ssl.h
 check_tcp.o: check_tcp.c ../include/check_tcp.h ../include/check_api.h \
-  ../include/memory.h ../include/ipwrapper.h ../include/layer4.h \
-  ../include/smtp.h ../include/utils.h ../include/parser.h
+  ../../lib/memory.h ../include/ipwrapper.h ../include/layer4.h \
+  ../include/smtp.h ../../lib/utils.h ../include/parser.h
 check_http.o: check_http.c ../include/check_http.h ../include/check_ssl.h \
-  ../include/check_api.h ../include/memory.h ../include/parser.h \
-  ../include/utils.h
+  ../include/check_api.h ../../lib/memory.h ../include/parser.h \
+  ../../lib/utils.h
 check_ssl.o: check_ssl.c ../include/check_ssl.h ../include/check_api.h \
-  ../include/memory.h ../include/parser.h ../include/smtp.h \
-  ../include/utils.h
+  ../../lib/memory.h ../include/parser.h ../include/smtp.h \
+  ../../lib/utils.h
 check_misc.o: check_misc.c ../include/check_misc.h ../include/check_api.h \
-  ../include/memory.h ../include/ipwrapper.h ../include/smtp.h \
-  ../include/utils.h ../include/parser.h ../include/daemon.h
-ipwrapper.o: ipwrapper.c ../include/ipwrapper.h ../include/utils.h
-ipvswrapper.o: ipvswrapper.c ../include/ipvswrapper.h ../include/utils.h \
-  ../include/memory.h
+  ../../lib/memory.h ../include/ipwrapper.h ../include/smtp.h \
+  ../../lib/utils.h ../include/parser.h ../include/daemon.h
+ipwrapper.o: ipwrapper.c ../include/ipwrapper.h ../../lib/utils.h
+ipvswrapper.o: ipvswrapper.c ../include/ipvswrapper.h ../../lib/utils.h \
+  ../../lib/memory.h
index a4fccb8..815f2ad 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers registration.
  *
- * Version:     $Id: check_api.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_api.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index dca9b7d..d50bb25 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        CI-LINUX checker. Integration to Compaq Cluster Infrastructure.
  *
- * Version:     $Id: check_ci.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_ci.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Aneesh Kumar K.V, <aneesh.kumar@digital.com>
index f8bef05..7d74ae2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        WEB CHECK. Common HTTP/SSL checker primitives.
  *
- * Version:     $Id: check_http.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_http.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
@@ -28,6 +28,7 @@
 #include "memory.h"
 #include "parser.h"
 #include "utils.h"
+#include "html.h"
 
 int http_connect_thread(thread *);
 
@@ -45,8 +46,13 @@ void
 dump_url(void *data)
 {
        url *url = data;
-       syslog(LOG_INFO, "   Checked url = %s, digest = %s", url->path,
-              url->digest);
+       syslog(LOG_INFO, "   Checked url = %s", url->path);
+       if (url->digest)
+               syslog(LOG_INFO, "           digest = %s",
+                      url->digest);
+       if (url->status_code)
+               syslog(LOG_INFO, "           HTTP Status Code = %d",
+                      url->status_code);
 }
 
 void
@@ -164,6 +170,15 @@ digest_handler(vector strvec)
 }
 
 void
+status_code_handler(vector strvec)
+{
+       http_get_checker *http_get_chk = CHECKER_GET();
+       url *url = LIST_TAIL_DATA(http_get_chk->url);
+
+       url->status_code = CHECKER_VALUE_INT(strvec);
+}
+
+void
 install_http_check_keyword(void)
 {
        install_keyword("HTTP_GET", &http_get_handler);
@@ -176,6 +191,7 @@ install_http_check_keyword(void)
        install_sublevel();
        install_keyword("path", &path_handler);
        install_keyword("digest", &digest_handler);
+       install_keyword("status_code", &status_code_handler);
        install_sublevel_end();
        install_sublevel_end();
 }
@@ -194,6 +210,7 @@ install_ssl_check_keyword(void)
        install_sublevel();
        install_keyword("path", &path_handler);
        install_keyword("digest", &digest_handler);
+       install_keyword("status_code", &status_code_handler);
        install_sublevel_end();
        install_sublevel_end();
 }
@@ -290,6 +307,7 @@ epilog(thread * thread, int method, int t, int c)
                if (req->buffer)
                        FREE(req->buffer);
                FREE(req);
+               http_arg->req = NULL;
                close(thread->u.fd);
        }
 
@@ -338,22 +356,6 @@ timeout_epilog(thread * thread, char *smtp_msg, char *debug_msg)
        return 0;
 }
 
-/* HTML stream parser primitives */
-/* simple function returning a pointer to the html buffer begin */
-char *
-extract_html(char *buffer, int size_buffer)
-{
-       char *end = buffer + size_buffer;
-
-       while (buffer < end &&
-              !(*buffer++ == '\n' &&
-                (*buffer == '\n' || (*buffer++ == '\r' && *buffer == '\n')))) ;
-
-       if (*buffer == '\n')
-               return buffer + 1;
-       return NULL;
-}
-
 /* return the url pointer of the current url iterator  */
 url *
 fetch_next_url(http_get_checker * http_get_check)
@@ -370,60 +372,116 @@ http_handle_response(thread * thread, unsigned char digest[16]
 {
        checker *checker = THREAD_ARG(thread);
        http_get_checker *http_get_check = CHECKER_ARG(checker);
-#ifdef _DEBUG_
-       uint16_t addr_port = get_service_port(checker);
        http_arg *http_arg = HTTP_ARG(http_get_check);
-#endif
+       REQ *req = HTTP_REQ(http_arg);
+       uint16_t addr_port = get_service_port(checker);
        int r, di = 0;
        unsigned char *digest_tmp;
-       url *fetched_url;
+       url *fetched_url = fetch_next_url(http_get_check);
 
-       if (empty_buffer) {
+       /* First check if remote webserver returned data */
+       if (empty_buffer)
                return timeout_epilog(thread, "=> CHECK failed on service"
                                      " : empty buffer received <=\n\n",
                                      "Read, no data received from ");
-       } else {
+
+       /* Next check the HTTP status code */
+       if (fetched_url->status_code) {
+               if (req->status_code != fetched_url->status_code) {
+                       /* check if server is currently alive */
+                       if (ISALIVE(checker->rs)) {
+                               syslog(LOG_INFO,
+                                      "HTTP status code error to [%s:%d] url[%s]"
+                                      ", status_code [%d].",
+                                      inet_ntop2(CHECKER_RIP(checker)),
+                                      ntohs(addr_port), fetched_url->path,
+                                      req->status_code);
+                               smtp_alert(thread->master, checker->rs, NULL,
+                                          "DOWN",
+                                          "=> CHECK failed on service"
+                                          " : HTTP status code mismatch <=\n\n");
+                               perform_svr_state(DOWN, checker->vs, checker->rs);
+                       }
+                       return epilog(thread, 1, 0, 0);
+               }
+       }
+
+       /* Continue with MD5SUM */
+       if (fetched_url->digest) {
                /* Compute MD5SUM */
                digest_tmp = (char *) MALLOC(MD5_BUFFER_LENGTH + 1);
                for (di = 0; di < 16; di++)
                        sprintf(digest_tmp + 2 * di, "%02x", digest[di]);
 
-               fetched_url = fetch_next_url(http_get_check);
-
                DBG("MD5SUM to [%s:%d] url(%d) = [%s].",
                    inet_ntop2(CHECKER_RIP(checker)), ntohs(addr_port),
                    http_arg->url_it + 1, digest_tmp);
 
                r = strcmp(fetched_url->digest, digest_tmp);
-               FREE(digest_tmp);
 
                if (r) {
-                       DBG("MD5 digest error to [%s:%d] url(%d)"
-                           ", expecting MD5SUM [%s].",
-                           inet_ntop2(CHECKER_RIP(checker)),
-                           ntohs(addr_port), http_arg->url_it + 1,
-                           fetched_url->digest);
-
                        /* check if server is currently alive */
                        if (ISALIVE(checker->rs)) {
+                               syslog(LOG_INFO,
+                                      "MD5 digest error to [%s:%d] url[%s]"
+                                      ", MD5SUM [%s].",
+                                      inet_ntop2(CHECKER_RIP(checker)),
+                                      ntohs(addr_port), fetched_url->path,
+                                      digest_tmp);
                                smtp_alert(thread->master, checker->rs, NULL,
                                           "DOWN",
                                           "=> CHECK failed on service"
                                           " : MD5 digest mismatch <=\n\n");
-                               perform_svr_state(DOWN, checker->vs,
-                                                 checker->rs);
+                               perform_svr_state(DOWN, checker->vs, checker->rs);
                        }
+                       FREE(digest_tmp);
                        return epilog(thread, 1, 0, 0);
                } else {
                        DBG("MD5 digest success to [%s:%d] url(%d).",
                            inet_ntop2(CHECKER_RIP(checker)), ntohs(addr_port),
                            http_arg->url_it + 1);
+                       FREE(digest_tmp);
                        return epilog(thread, 1, 1, 0) + 1;
                }
        }
+
        return epilog(thread, 1, 0, 0) + 1;
 }
 
+/* Handle response stream performing MD5 updates */
+int
+http_process_response(REQ *req, int r)
+{
+       req->len += r;
+       if (!req->extracted) {
+               if ((req->extracted =
+                    extract_html(req->buffer, req->len))) {
+                       req->status_code = extract_status_code(req->buffer, req->len);
+                       r = req->len - (req->extracted - req->buffer);
+                       if (r) {
+                               memcpy(req->buffer, req->extracted, r);
+                               MD5_Update(&req->context, req->buffer,
+                                          r);
+                               r = 0;
+                       }
+                       req->len = r;
+               } else {
+                       /* minimize buffer using no 2*CR/LF found yet */
+                       if (req->len > 3) {
+                               memcpy(req->buffer,
+                                      req->buffer + req->len - 3, 3);
+                               req->len = 3;
+                       }
+               }
+       } else if (req->len) {
+               MD5_Update(&req->context, req->buffer,
+                          req->len);
+               req->len = 0;
+       }
+
+       return 0;
+}
+
 /* Asynchronous HTTP stream reader */
 int
 http_read_thread(thread * thread)
@@ -473,33 +531,8 @@ http_read_thread(thread * thread)
 
        } else {
 
-               req->len += r;
-               if (!req->extracted) {
-                       if ((req->extracted =
-                            extract_html(req->buffer, req->len))) {
-                               r = req->len - (req->extracted - req->buffer);
-                               if (r) {
-                                       memcpy(req->buffer, req->extracted, r);
-                                       MD5_Update(&req->context, req->buffer,
-                                                  r);
-                                       r = 0;
-                               }
-                               req->len = r;
-                       } else {
-                               /* minimize buffer using no 2*CR/LF found yet */
-                               if (req->len > 3) {
-                                       memcpy(req->buffer,
-                                              req->buffer + req->len - 3, 3);
-                                       req->len = 3;
-                               }
-                       }
-               } else {
-                       if (req->len) {
-                               MD5_Update(&req->context, req->buffer,
-                                          req->len);
-                               req->len = 0;
-                       }
-               }
+               /* Handle response stream */
+               http_process_response(req, r);
 
                /*
                 * Register next http stream reader.
@@ -618,8 +651,8 @@ http_check_thread(thread * thread)
        checker *checker = THREAD_ARG(thread);
        http_get_checker *http_get_check = CHECKER_ARG(checker);
        uint16_t addr_port = get_service_port(checker);
-#ifdef _DEBUG_
        http_arg *http_arg = HTTP_ARG(http_get_check);
+#ifdef _DEBUG_
        REQ *req = HTTP_REQ(http_arg);
 #endif
        int ret = 1;
@@ -648,6 +681,9 @@ http_check_thread(thread * thread)
                break;
 
        case connect_success:{
+                       /* Allocate & clean request struct */
+                       http_arg->req = (REQ *) MALLOC(sizeof (REQ));
+
                        if (http_get_check->proto == PROTO_SSL)
                                ret = ssl_connect(thread);
 
@@ -721,9 +757,7 @@ http_connect_thread(thread * thread)
                return epilog(thread, 1, 0, 0) + 1;
        }
 
-       /* Allocate & clean request struct */
-       http_arg->req = (REQ *) MALLOC(sizeof (REQ));
-
+       /* Create the socket */
        if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
                DBG("WEB connection fail to create socket.");
                return 0;
index 3b47e6d..64d46c0 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        MISC CHECK. Perform a system call to run an extra
  *              system prog or script.
  *
- * Version:     $Id: check_misc.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_misc.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index ceb7cbb..4ac8fcb 100644 (file)
@@ -7,7 +7,7 @@
  *              url, compute a MD5 over this result and match it to the
  *              expected value.
  *
- * Version:     $Id: check_ssl.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_ssl.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
@@ -30,6 +30,7 @@
 #include "parser.h"
 #include "smtp.h"
 #include "utils.h"
+#include "html.h"
 
 extern data *conf_data;
 
@@ -270,33 +271,8 @@ ssl_read_thread(thread * thread)
 
        } else if (r > 0 && req->error == 0) {
 
-               req->len += r;
-               if (!req->extracted) {
-                       if ((req->extracted =
-                            extract_html(req->buffer, req->len))) {
-                               r = req->len - (req->extracted - req->buffer);
-                               if (r) {
-                                       memcpy(req->buffer, req->extracted, r);
-                                       MD5_Update(&req->context, req->buffer,
-                                                  r);
-                                       r = 0;
-                               }
-                               req->len = r;
-                       } else {
-                               /* minimize buffer using no 2*CR/LF found yet */
-                               if (req->len > 3) {
-                                       memcpy(req->buffer,
-                                              req->buffer + req->len - 3, 3);
-                                       req->len = 3;
-                               }
-                       }
-               } else {
-                       if (req->len) {
-                               MD5_Update(&req->context, req->buffer,
-                                          req->len);
-                               req->len = 0;
-                       }
-               }
+               /* Handle response stream */
+               http_process_response(req, r);
 
                /*
                 * Register next ssl stream reader.
index 61c3386..50bd7d0 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        TCP checker.
  *
- * Version:     $Id: check_tcp.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_tcp.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index e3acec1..7ac1ad7 100644 (file)
@@ -7,7 +7,7 @@
  *              library to add/remove server MASQ rules to the kernel 
  *              firewall framework.
  *
- * Version:     $Id: ipfwwrapper.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: ipfwwrapper.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index cf83264..3ebc93f 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        IPVS Kernel wrapper. Use setsockopt call to add/remove
  *              server to/from the loadbalanced server pool.
  *  
- * Version:     $Id: ipvswrapper.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: ipvswrapper.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 3f3bdce..4e00718 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Manipulation functions for IPVS & IPFW wrappers.
  *
- * Version:     $id: ipwrapper.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $id: ipwrapper.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 44ff6a2..5e0dfdf 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers arguments structures definitions.
  *
- * Version:     $Id: check_api.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_api.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index bd55299..1ed4ecf 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_ci.c include file.
  *
- * Version:     $Id: check_ci.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_ci.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Aneesh Kumar K.V, <aneesh.kumar@digital.com>
index 54d02e4..5c585ad 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_http.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
@@ -42,6 +42,7 @@ typedef struct {
        char *buffer;
        char *extracted;
        int error;
+       int status_code;
        int len;
        SSL *ssl;
        BIO *bio;
@@ -58,6 +59,7 @@ typedef struct _http_arg {
 typedef struct _url {
        char *path;
        char *digest;
+       int status_code;
 } url;
 typedef struct _http_get_checker {
        int proto;
@@ -89,8 +91,8 @@ typedef struct _http_get_checker {
 extern void install_http_check_keyword(void);
 extern int epilog(thread * thread, int metod, int t, int c);
 extern int timeout_epilog(thread * thread, char *smtp_msg, char *debug_msg);
-extern char *extract_html(char *buffer, int size_buffer);
 extern url *fetch_next_url(http_get_checker * http_get_check);
+extern int http_process_response(REQ *req, int r);
 extern int http_handle_response(thread * thread, unsigned char digest[16]
                                , int empty_buffer);
 #endif
index 2fa3786..3144522 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_misc.c include file.
  *
- * Version:     $Id: check_misc.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_misc.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index a490ba7..2e13b63 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_http.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index db1ee59..659649f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_tcp.c include file.
  *
- * Version:     $Id: check_tcp.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: check_tcp.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index ecb2fdd..b033bb0 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Daemon process handling.
  *
- * Version:     $Id: daemon.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: daemon.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 4608cd6..cbc4171 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: data.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: data.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index b9cad61..28b7b37 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipfwwrapper.c include file.
  *
- * Version:     $Id: ipfwwrapper.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: ipfwwrapper.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 48ca112..de64ff3 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipvswrapper.c include file.
  *
- * Version:     $Id: ipvswrapper.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: ipvswrapper.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 491538b..7cc31d2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipwrapper.c include file.
  *
- * Version:     $Id: ipwrapper.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: ipwrapper.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 670c65a..de1e783 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        layer4.c include file.
  *
- * Version:     $Id: layer4.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: layer4.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index e058778..ba1e7c9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program include file.
  *
- * Version:     $Id: main.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: main.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -47,7 +47,6 @@ thread_master *master = NULL;         /* Scheduling master thread */
 char *conf_file = NULL;                        /* Configuration file */
 int reload = 0;                                /* Global reloading flag */
 unsigned int debug;                    /* Debugging flags */
-unsigned long mem_allocated = 0;       /* Total memory used in Bytes */
 data *conf_data;                       /* Global configuration data */
 data *old_data;                                /* Used during reload process */
 
@@ -66,8 +65,8 @@ extern void register_vrrp_thread(void);
 /* Build version */
 #define PROG    "Keepalived"
 
-#define VERSION_CODE 0x000701
-#define DATE_CODE    0x110902
+#define VERSION_CODE 0x000706
+#define DATE_CODE    0x140A02
 
 #define KEEPALIVED_VERSION(version)    \
        (version >> 16) & 0xFF,         \
index 31008cf..45ee731 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        cfreader.c include file.
  *  
- * Version:     $Id: parser.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: parser.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 8702658..4a69b17 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile.c include file.
  *
- * Version:     $Id: pidfile.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: pidfile.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 99a11dd..2598c24 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        smtp.c include file.
  *
- * Version:     $Id: smtp.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: smtp.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 25afa35..af301db 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Part:        vrrp.c program include file.
  *
- * Version:     $Id: vrrp.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 #define _VRRP_H
 
 /* system include */
-#include <net/ethernet.h>
-#include <netinet/ip.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
 #include <unistd.h>
 
 /* local include */
@@ -113,7 +107,6 @@ typedef struct _vrrp_rt {
                                 * VRRP adverts
                                 */
        int adver_int;          /* delay between advertisements(in sec) */
-       char hwaddr[6];         /* VMAC -- rfc2338.7.3 */
        int preempt;            /* true if a higher prio preempt a lower one */
        int state;              /* internal state (init/backup/master) */
        int init_state;         /* the initial state of the instance */
diff --git a/keepalived/include/vrrp_arp.h b/keepalived/include/vrrp_arp.h
new file mode 100644 (file)
index 0000000..b922c8e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Soft:        Keepalived is a failover program for the LVS project
+ *              <www.linuxvirtualserver.org>. It monitor & manipulate
+ *              a loadbalanced server pool using multi-layer checks.
+ *
+ * Part:        vrrp_arp.c include file.
+ *
+ * Version:     $Id: vrrp_arp.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Author:      Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *              
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _VRRP_ARP_H
+#define _VRRP_ARP_H
+
+/* system includes */
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+/* local includes */
+#include "vrrp.h"
+
+/* local definitions */
+#define ETHERNET_HW_LEN                6
+#define IPPROTO_ADDR_LEN       4
+
+/* types definition */
+typedef struct _m_arphdr {
+       unsigned short int ar_hrd;              /* Format of hardware address.  */
+       unsigned short int ar_pro;              /* Format of protocol address.  */
+       unsigned char ar_hln;                   /* Length of hardware address.  */
+       unsigned char ar_pln;                   /* Length of protocol address.  */
+       unsigned short int ar_op;               /* ARP opcode (command).  */
+
+       /* Ethernet looks like this : This bit is variable sized however...  */
+       unsigned char __ar_sha[ETH_ALEN];       /* Sender hardware address.  */
+       unsigned char __ar_sip[4];              /* Sender IP address.  */
+       unsigned char __ar_tha[ETH_ALEN];       /* Target hardware address.  */
+       unsigned char __ar_tip[4];              /* Target IP address.  */
+} m_arphdr;
+
+/* prototypes */
+extern int send_gratuitous_arp(vrrp_rt * vrrp, int addr);
+
+#endif
index f3674d0..b19fa7e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_if.c include file.
  *
- * Version:     $Id: vrrp_if.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_if.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -95,5 +95,10 @@ extern int if_monitor_thread(thread * thread);
 extern void init_interface_queue(void);
 extern void free_interface_queue(void);
 extern void dump_if(void *data);
+extern int if_join_vrrp_group(int sd, interface *ifp, int proto);
+extern void if_leave_vrrp_group(int sd, interface *ifp);
+extern int if_setsockopt_bindtodevice(int sd, interface *ifp);
+extern int if_setsockopt_hdrincl(int sd);
+extern int if_setsockopt_mcast_loop(int sd);
 
 #endif
index 102a01a..8f87fac 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipaddress.c include file.
  *
- * Version:     $Id: vrrp_ipaddress.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index dab536e..1631651 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipsecah.c include file.
  * 
- * Version:     $Id: vrrp_ipsecah.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 267ef90..2061738 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_netlink.c include file.
  *
- * Version:     $Id: vrrp_netlink.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_netlink.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index bbbfb58..186b316 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Part:        vrrp_notify.c include file.
  *
- * Version:     $Id: vrrp_notify.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_notify.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 91056f8..3278840 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_scheduler.c include file.
  * 
- * Version:     $Id: vrrp_scheduler.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 2a61a0a..ab3560d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_sync.c include file.
  * 
- * Version:     $Id: vrrp_sync.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_sync.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 09a2d7f..3f03d03 100644 (file)
@@ -10,13 +10,6 @@ global_defs {
    lvs_id LVS_DEVEL
 }
 
-!SSL {
-!  password password
-!  ca /etc/keepalived/root.pem
-!  certificate /etc/keepalived/dh1024.pem
-!  key /etc/keepalived/client.pem
-!}
-
 vrrp_instance VI_1 {
     state MASTER
     interface eth0
@@ -38,7 +31,6 @@ virtual_server 192.168.200.100 443 {
     delay_loop 6
     lb_algo rr 
     lb_kind NAT
-    nat_mask 255.255.255.0
     persistence_timeout 50
     protocol TCP
 
@@ -64,7 +56,6 @@ virtual_server 192.168.200.100 80 {
     delay_loop 6
     lb_algo rr 
     lb_kind NAT
-    nat_mask 255.255.255.0
     persistence_timeout 50
     protocol TCP
 
diff --git a/keepalived/samples/keepalived.conf.status_code b/keepalived/samples/keepalived.conf.status_code
new file mode 100644 (file)
index 0000000..a0cb03b
--- /dev/null
@@ -0,0 +1,37 @@
+! Configuration File for keepalived
+
+global_defs {
+   notification_email {
+     acassen
+   }
+   notification_email_from Alexandre.Cassen@firewall.loc
+   smtp_server 192.168.200.1
+   smtp_connect_timeout 30
+   lvs_id LVS_DEVEL
+}
+
+virtual_server 192.168.200.100 443 {
+    delay_loop 6
+    lb_algo rr 
+    lb_kind NAT
+    persistence_timeout 50
+    protocol TCP
+
+    real_server 192.168.201.100 443 {
+        weight 1
+        SSL_GET {
+            url { 
+              path /
+              status_code 200  # Can only specify a HTTP status_code
+            }
+            url { 
+              path /mrtg/
+              digest 9b3a0c85a887a256d6939da88aabd8cd
+              status_code 200  # Can mix digest and status_code
+            }
+            connect_timeout 3
+            nb_get_retry 3
+            delay_before_retry 3
+        }
+    }
+}
index 4121a32..de53940 100644 (file)
@@ -5,14 +5,14 @@
 # Copyright (C) 2001, 2002 Alexandre Cassen, <acassen@linux-vs.org>
 
 CC      = @CC@
-INCLUDES = -I../include
+INCLUDES = -I../include -I../../lib
 CFLAGS  = @CFLAGS@ $(INCLUDES) \
           -Wall -Wunused -Wstrict-prototypes
 DEFS    = -D@KERN@ -D@IPVS_SUPPORT@ -D@IPVS_SYNCD@ @DFLAGS@
 COMPILE         = $(CC) $(CFLAGS) $(DEFS)
 
 OBJS =         vrrp.o vrrp_notify.o vrrp_scheduler.o vrrp_sync.o \
-       vrrp_netlink.o vrrp_if.o vrrp_ipaddress.o vrrp_ipsecah.o
+       vrrp_netlink.o vrrp_arp.o vrrp_if.o vrrp_ipaddress.o vrrp_ipsecah.o
 HEADERS = $(OBJS:.o=.h)
 
 .c.o:
@@ -27,21 +27,22 @@ distclean: clean
        rm -f Makefile
 
 vrrp.o: vrrp.c ../include/vrrp.h ../include/vrrp_scheduler.h \
-  ../include/vrrp_notify.h ../include/ipvswrapper.h ../include/memory.h \
-  ../include/list.h ../include/data.h
-vrrp_notify.o: vrrp_notify.c ../include/vrrp_notify.h ../include/memory.h
+  ../include/vrrp_notify.h ../include/ipvswrapper.h ../../lib/memory.h \
+  ../../lib/list.h ../include/data.h ../include/vrrp_arp.h
+vrrp_notify.o: vrrp_notify.c ../include/vrrp_notify.h ../../lib/memory.h
 vrrp_scheduler.o: vrrp_scheduler.c ../include/vrrp_scheduler.h \
   ../include/vrrp_ipsecah.h ../include/vrrp_if.h ../include/vrrp.h \
   ../include/vrrp_sync.h ../include/vrrp_notify.h ../include/ipvswrapper.h \
-  ../include/memory.h ../include/list.h ../include/data.h ../include/smtp.h
+  ../../lib/memory.h ../../lib/list.h ../include/data.h ../include/smtp.h
 vrrp_sync.o: vrrp_sync.c ../include/vrrp_sync.h ../include/vrrp_if.h \
   ../include/vrrp_notify.h ../include/data.h
 vrrp_netlink.o: vrrp_netlink.c ../include/vrrp_netlink.h ../include/check_api.h \
-  ../include/vrrp_if.h ../include/memory.h ../include/scheduler.h \
-  ../include/utils.h
+  ../include/vrrp_if.h ../../lib/memory.h ../../lib/scheduler.h \
+  ../../lib/utils.h
+vrrp_arp.o: vrrp_arp.c ../include/vrrp_arp.h
 vrrp_if.o: vrrp_if.c ../include/vrrp_if.h ../include/vrrp_netlink.h \
-  ../include/scheduler.h ../include/data.h ../include/memory.h \
-  ../include/utils.h
+  ../../lib/scheduler.h ../include/data.h ../../lib/memory.h \
+  ../../lib/utils.h
 vrrp_ipaddress.o: vrrp_ipaddress.c ../include/vrrp_ipaddress.h \
-  ../include/vrrp_netlink.h ../include/utils.h
+  ../include/vrrp_netlink.h ../../lib/utils.h
 vrrp_ipsecah.o: vrrp_ipsecah.c ../include/vrrp_ipsecah.h
index f35850c..b07d12a 100644 (file)
@@ -8,7 +8,7 @@
  *              master fails, a backup server takes over.
  *              The original implementation has been made by jerome etienne.
  *
- * Version:     $Id: vrrp.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -25,6 +25,8 @@
 
 /* local include */
 #include <ctype.h>
+#include <sys/uio.h>
+#include "vrrp_arp.h"
 #include "vrrp_scheduler.h"
 #include "vrrp_notify.h"
 #include "ipvswrapper.h"
@@ -119,13 +121,6 @@ vrrp_handle_ipaddress(vrrp_rt * vrrp, int cmd, int type)
        return err;
 }
 
-/* ARP header length */
-static int
-vrrp_dlt_len(vrrp_rt * rt)
-{
-       return ETHER_HDR_LEN;   /* hardcoded for ethernet */
-}
-
 /* IP header length */
 static int
 vrrp_iphdr_len(vrrp_rt * vrrp)
@@ -171,7 +166,7 @@ vrrp_in_chk_ipsecah(vrrp_rt * vrrp, char *buffer)
 
        /*
         * then proceed with the sequence number to prevent against replay attack.
-        * in inbound processing, we increment seq_number counter to audit 
+        * For inbound processing, we increment seq_number counter to audit 
         * sender counter.
         */
        vrrp->ipsecah_counter->seq_number++;
@@ -179,8 +174,9 @@ vrrp_in_chk_ipsecah(vrrp_rt * vrrp, char *buffer)
                vrrp->ipsecah_counter->seq_number = ah->seq_number;
        } else {
                syslog(LOG_INFO,
-                      "IPSEC AH : sequence number %d already proceeded."
-                      " Packet droped", ah->seq_number);
+                      "VRRP_Instance(%s) IPSEC-AH : sequence number %d"
+                      " already proceeded. Packet dropped", vrrp->iname
+                      , ah->seq_number);
                return 1;
        }
 
@@ -205,8 +201,9 @@ vrrp_in_chk_ipsecah(vrrp_rt * vrrp, char *buffer)
                 , digest);
 
        if (memcmp(backup_auth_data, digest, HMAC_MD5_TRUNC) != 0) {
-               syslog(LOG_INFO, "IPSEC AH : invalid IPSEC HMAC-MD5 value."
-                      " Due to fields mutation or bad password !");
+               syslog(LOG_INFO, "VRRP_Instance(%s) IPSEC-AH : invalid"
+                      " IPSEC HMAC-MD5 value. Due to fields mutation"
+                      " or bad password !", vrrp->iname);
                return 1;
        }
 
@@ -224,7 +221,8 @@ vrrp_in_chk_vips(vrrp_rt * vrrp, uint32_t ipaddr, unsigned char *buffer)
        for (i = 0; i < vrrp->naddr; i++) {
                bcopy(buffer + i * sizeof (uint32_t), &ipbuf,
                      sizeof (uint32_t));
-               if (ipaddr == ntohl(ipbuf))
+//             if (ipaddr == ntohl(ipbuf))
+               if (ipaddr == ipbuf)
                        return 1;
        }
 
@@ -354,28 +352,6 @@ vrrp_in_chk(vrrp_rt * vrrp, char *buffer)
        return VRRP_PACKET_OK;
 }
 
-/* build ARP header */
-static void
-vrrp_build_arp(vrrp_rt * vrrp, char *buffer, int buflen)
-{
-       /* hardcoded for ethernet */
-       struct ether_header *eth = (struct ether_header *) buffer;
-
-       /* destination address --rfc1122.6.4 */
-       eth->ether_dhost[0] = 0x01;
-       eth->ether_dhost[1] = 0x00;
-       eth->ether_dhost[2] = 0x5E;
-       eth->ether_dhost[3] = (INADDR_VRRP_GROUP >> 16) & 0x7F;
-       eth->ether_dhost[4] = (INADDR_VRRP_GROUP >> 8) & 0xFF;
-       eth->ether_dhost[5] = INADDR_VRRP_GROUP & 0xFF;
-
-       /* source address -- rfc2338.7.3 */
-       memcpy(eth->ether_shost, vrrp->hwaddr, sizeof (vrrp->hwaddr));
-
-       /* type */
-       eth->ether_type = htons(ETHERTYPE_IP);
-}
-
 /* build IP header */
 static void
 vrrp_build_ip(vrrp_rt * vrrp, char *buffer, int buflen)
@@ -506,9 +482,9 @@ vrrp_build_vrrp(vrrp_rt * vrrp, int prio, char *buffer, int buflen)
        hd->adver_int = vrrp->adver_int / TIMER_HZ;
 
        /* copy the ip addresses */
-       for (i = 0; i < vrrp->naddr; i++) {
-               iparr[i] = htonl(vrrp->vaddr[i].addr);
-       }
+       for (i = 0; i < vrrp->naddr; i++)
+               iparr[i] = vrrp->vaddr[i].addr;
+//             iparr[i] = htonl(vrrp->vaddr[i].addr);
 
        /* copy the passwd if the authentication is VRRP_AH_PASS */
        if (vrrp->auth_type == VRRP_AUTH_PASS) {
@@ -530,12 +506,7 @@ vrrp_build_pkt(vrrp_rt * vrrp, int prio, char *buffer, int buflen)
 
        bufptr = buffer;
 
-       /* build the ethernet header */
-       vrrp_build_arp(vrrp, buffer, buflen);
-
        /* build the ip header */
-       buffer += vrrp_dlt_len(vrrp);
-       buflen -= vrrp_dlt_len(vrrp);
        vrrp_build_ip(vrrp, buffer, buflen);
 
        /* build the vrrp header */
@@ -551,8 +522,7 @@ vrrp_build_pkt(vrrp_rt * vrrp, int prio, char *buffer, int buflen)
 
        /* build the IPSEC AH header */
        if (vrrp->auth_type == VRRP_AUTH_AH) {
-               bufptr += vrrp_dlt_len(vrrp);
-               buflen += vrrp_ipsecah_len() + vrrp_iphdr_len(vrrp);;
+               buflen += vrrp_iphdr_len(vrrp) + vrrp_ipsecah_len();
                vrrp_build_ipsecah(vrrp, bufptr, buflen);
        }
 }
@@ -561,26 +531,40 @@ vrrp_build_pkt(vrrp_rt * vrrp, int prio, char *buffer, int buflen)
 static int
 vrrp_send_pkt(vrrp_rt * vrrp, char *buffer, int buflen)
 {
-       struct sockaddr from;
-       int len;
-       int fd = socket(PF_PACKET, SOCK_PACKET, 0x300); /* 0x300 is magic */
-
-       if (fd < 0) {
-               syslog(LOG_INFO, "VRRP Error : socket creation");
-               return -1;
-       }
-
-       /* build the address */
-       memset(&from, 0, sizeof (from));
-       strncpy(from.sa_data, IF_NAME(vrrp->ifp), sizeof(from.sa_data));
-
-//print_buffer(buflen, buffer);
+       struct sockaddr_in dst;
+       struct msghdr msg;
+       struct iovec iov;
+       int fd;
+       int ret;
 
-       /* send the data */
-       len = sendto(fd, buffer, buflen, 0, &from, sizeof (from));
+       /* Create and init socket descriptor */
+       fd = socket(AF_INET
+                   , SOCK_RAW
+                   , (vrrp->auth_type == VRRP_AUTH_AH) ? IPPROTO_IPSEC_AH : IPPROTO_VRRP);
+       if_setsockopt_hdrincl(fd);
+       if_setsockopt_bindtodevice(fd, vrrp->ifp);
+       if_setsockopt_mcast_loop(fd);
+
+       /* Sending path */
+       memset(&dst, 0, sizeof(dst));
+       dst.sin_family = AF_INET;
+       dst.sin_addr.s_addr = htonl(INADDR_VRRP_GROUP);
+       dst.sin_port = htons(0);
+
+       /* Build the message data */
+       memset(&msg, 0, sizeof(msg));
+       msg.msg_name = &dst;
+       msg.msg_namelen = sizeof(dst);
+       msg.msg_iov = &iov;
+       msg.msg_iovlen = 1;
+       iov.iov_base = buffer;
+       iov.iov_len = buflen;
+
+       /* Send the packet */
+       ret = sendmsg(fd, &msg, MSG_DONTROUTE);
 
        close(fd);
-       return len;
+       return 0;
 }
 
 /* send VRRP advertissement */
@@ -591,7 +575,7 @@ vrrp_send_adv(vrrp_rt * vrrp, int prio)
        char *buffer;
 
        /* alloc the memory */
-       buflen = vrrp_dlt_len(vrrp) + vrrp_iphdr_len(vrrp) + vrrp_hd_len(vrrp);
+       buflen = vrrp_iphdr_len(vrrp) + vrrp_hd_len(vrrp);
        if (vrrp->auth_type == VRRP_AUTH_AH)
                buflen += vrrp_ipsecah_len();
 
@@ -631,50 +615,6 @@ vrrp_check_packet(vrrp_rt * vrrp, char *buf, int buflen)
        return VRRP_PACKET_NULL;
 }
 
-/* send a gratuitous ARP packet */
-static int
-send_gratuitous_arp(vrrp_rt * vrrp, int addr)
-{
-       struct m_arphdr {
-               unsigned short int ar_hrd;              /* Format of hardware address.  */
-               unsigned short int ar_pro;              /* Format of protocol address.  */
-               unsigned char ar_hln;                   /* Length of hardware address.  */
-               unsigned char ar_pln;                   /* Length of protocol address.  */
-               unsigned short int ar_op;               /* ARP opcode (command).  */
-
-               /* Ethernet looks like this : This bit is variable sized however...  */
-               unsigned char __ar_sha[ETH_ALEN];       /* Sender hardware address.  */
-               unsigned char __ar_sip[4];              /* Sender IP address.  */
-               unsigned char __ar_tha[ETH_ALEN];       /* Target hardware address.  */
-               unsigned char __ar_tip[4];              /* Target IP address.  */
-       };
-
-       char buf[sizeof (struct m_arphdr) + ETHER_HDR_LEN];
-       char buflen = sizeof (struct m_arphdr) + ETHER_HDR_LEN;
-       struct ether_header *eth = (struct ether_header *) buf;
-       struct m_arphdr *arph = (struct m_arphdr *) (buf + vrrp_dlt_len(vrrp));
-       char *hwaddr = IF_HWADDR(vrrp->ifp);
-       int hwlen = ETH_ALEN;
-
-       /* hardcoded for ethernet */
-       memset(eth->ether_dhost, 0xFF, ETH_ALEN);
-       memcpy(eth->ether_shost, hwaddr, hwlen);
-       eth->ether_type = htons(ETHERTYPE_ARP);
-
-       /* build the arp payload */
-       memset(arph, 0, sizeof (*arph));
-       arph->ar_hrd = htons(ARPHRD_ETHER);
-       arph->ar_pro = htons(ETHERTYPE_IP);
-       arph->ar_hln = 6;
-       arph->ar_pln = 4;
-       arph->ar_op = htons(ARPOP_REQUEST);
-       memcpy(arph->__ar_sha, hwaddr, hwlen);
-       memcpy(arph->__ar_sip, &addr, sizeof (addr));
-       memcpy(arph->__ar_tip, &addr, sizeof (addr));
-
-       return vrrp_send_pkt(vrrp, buf, buflen);
-}
-
 /* Gratuitous ARP on each VIP */
 void
 vrrp_send_gratuitous_arp(vrrp_rt * vrrp)
@@ -851,6 +791,7 @@ vrrp_state_master_rx(vrrp_rt * vrrp, char *buf, int buflen)
        int ret = 0;
        struct iphdr *iph = (struct iphdr *) buf;
        vrrp_pkt *hd = NULL;
+       ipsec_ah *ah;
 
        /* return on link failure */
        if (vrrp->wantstate == VRRP_STATE_GOTO_FAULT) {
@@ -885,6 +826,13 @@ vrrp_state_master_rx(vrrp_rt * vrrp, char *buf, int buflen)
                /* We receive a lower prio adv we just refresh remote ARP cache */
                syslog(LOG_INFO, "VRRP_Instance(%s) Received lower prio advert"
                       ", forcing new election", vrrp->iname);
+               if (iph->protocol == IPPROTO_IPSEC_AH) {
+                       ah = (ipsec_ah *) (buf + sizeof(struct iphdr));
+                       syslog(LOG_INFO, "VRRP_Instance(%s) IPSEC-AH : Syncing seq_num"
+                              " with received = %d", vrrp->iname, ah->seq_number);
+                       vrrp->ipsecah_counter->seq_number = ah->seq_number + 1;
+                       vrrp->ipsecah_counter->cycle = 0;
+               }
                vrrp_send_adv(vrrp, vrrp->priority);
                vrrp_send_gratuitous_arp(vrrp);
                return 0;
@@ -970,72 +918,31 @@ chk_min_cfg(vrrp_rt * vrrp)
 int
 open_vrrp_socket(const int proto, const int index)
 {
-       struct ip_mreqn req_add;
        interface *ifp;
-       int fd;
-       int ret;
+       int fd = -1;
 
        /* Retreive interface */
        ifp = if_get_by_ifindex(index);
 
        /* Simply return if interface is shut */
        if (!IF_ISUP(ifp))
-               return -1;
-
-       /* open the socket */
-       fd = socket(AF_INET, SOCK_RAW, proto);
+               return fd;
 
-       if (fd < 0) {
-               int err = errno;
-               syslog(LOG_INFO,
-                      "cant open raw socket. errno=%d. (try to run it as root)",
-                      err);
-               return -1;
-       }
-
-       /* -> inbound processing option
-        * Specify the bound_dev_if.
-        * why IP_ADD_MEMBERSHIP & IP_MULTICAST_IF doesnt set
-        * sk->bound_dev_if themself ??? !!!
-        * Needed for filter multicasted advert per interface.
-        * 
-        * -- If you read this !!! and know the answer to the question
-        *    please feel free to answer me ! :)
-        */
-       ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, IF_NAME(ifp)
-                        , strlen(IF_NAME(ifp)) + 1);
-       if (ret < 0) {
-               int err = errno;
-               syslog(LOG_INFO,
-                      "cant bind to device %s. errno=%d. (try to run it as root)",
-                      IF_NAME(ifp)
-                      , err);
-               close(fd);
-               return -1;
-       }
+        /* open the socket */
+        fd = socket(AF_INET, SOCK_RAW, proto);
+        if (fd < 0) {
+                int err = errno;
+                syslog(LOG_INFO,
+                       "cant open raw socket. errno=%d. (try to run it as root)",
+                       err);
+                return -1;
+        }
 
-       /* -> outbound processing option
-        * join the multicast group.
-        * binding the socket to the interface for outbound multicast
-        * traffic.
-        */
-       memset(&req_add, 0, sizeof (req_add));
-       req_add.imr_multiaddr.s_addr = htonl(INADDR_VRRP_GROUP);
-       req_add.imr_address.s_addr = IF_ADDR(ifp);
-       req_add.imr_ifindex = IF_INDEX(ifp);
+       /* Join the VRRP MCAST group */
+       if_join_vrrp_group(fd, ifp, proto);
 
-       /* -> Need to handle multicast convergance after takeover.
-        * We retry until multicast is available on the interface.
-        */
-       ret =
-           setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &req_add,
-                      sizeof (struct ip_mreqn));
-       if (ret < 0) {
-               syslog(LOG_INFO, "cant do IP_ADD_MEMBERSHIP errno=%s (%d)",
-                      strerror(errno), errno);
-               close(fd);
-               return -1;
-       }
+       /* Bind inbound stream */
+       if_setsockopt_bindtodevice(fd, ifp);
 
        return fd;
 }
@@ -1043,30 +950,7 @@ open_vrrp_socket(const int proto, const int index)
 void
 close_vrrp_socket(vrrp_rt * vrrp)
 {
-       struct ip_mreqn req_add;
-       int ret = 0;
-
-       /* If fd is -1 then we add a membership trouble */
-       if (vrrp->fd < 0)
-               return;
-
-       /* Leaving the VRRP multicast group */
-       memset(&req_add, 0, sizeof (req_add));
-       req_add.imr_multiaddr.s_addr = htonl(INADDR_VRRP_GROUP);
-       req_add.imr_address.s_addr = IF_ADDR(vrrp->ifp);
-       req_add.imr_ifindex = IF_INDEX(vrrp->ifp);
-       ret =
-           setsockopt(vrrp->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
-                      (char *) &req_add, sizeof (struct ip_mreqn));
-       if (ret < 0) {
-               syslog(LOG_INFO, "cant do IP_DROP_MEMBERSHIP errno=%s (%d)",
-                      strerror(errno)
-                      , errno);
-               return;
-       }
-
-       /* Finally close the desc */
-       close(vrrp->fd);
+       if_leave_vrrp_group(vrrp->fd, vrrp->ifp);
 }
 
 int
@@ -1122,14 +1006,6 @@ shutdown_vrrp_instances(void)
 static int
 vrrp_complete_instance(vrrp_rt * vrrp)
 {
-       /* complete the VMAC address */
-       vrrp->hwaddr[0] = 0x00;
-       vrrp->hwaddr[1] = 0x00;
-       vrrp->hwaddr[2] = 0x5E;
-       vrrp->hwaddr[3] = 0x00;
-       vrrp->hwaddr[4] = 0x01;
-       vrrp->hwaddr[5] = vrrp->vrid;
-
        vrrp->state = VRRP_STATE_INIT;
        if (!vrrp->adver_int)
                vrrp->adver_int = VRRP_ADVER_DFL * TIMER_HZ;
diff --git a/keepalived/vrrp/vrrp_arp.c b/keepalived/vrrp/vrrp_arp.c
new file mode 100644 (file)
index 0000000..f0b35fb
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Soft:        Keepalived is a failover program for the LVS project
+ *              <www.linuxvirtualserver.org>. It monitor & manipulate
+ *              a loadbalanced server pool using multi-layer checks.
+ *
+ * Part:        ARP primitives.
+ *
+ * Version:     $Id: vrrp_arp.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Author:      Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+/* system includes */
+#include <linux/if_packet.h>
+
+/* local includes */
+#include "vrrp_arp.h"
+#include "memory.h"
+#include "utils.h"
+
+/* Send the gratuitous ARP message */
+static int send_arp(vrrp_rt *vrrp, char *buffer, int buflen)
+{
+       int fd;
+       int len;
+       struct sockaddr_ll sll;
+
+       /* Create the socket descriptor */
+       fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_RARP));
+
+       /* Build the dst device */
+       memset(&sll, 0, sizeof(sll));
+       sll.sll_family = AF_PACKET;
+       strncpy(sll.sll_addr, IF_HWADDR(vrrp->ifp), sizeof(sll.sll_addr));
+       sll.sll_halen = ETHERNET_HW_LEN;
+       sll.sll_ifindex = IF_INDEX(vrrp->ifp);
+
+       /* Send packet */
+       len = sendto(fd, buffer, buflen, 0,(struct sockaddr *)&sll, sizeof(sll));
+
+       close(fd);
+       return len;
+}
+
+/* Build a gratuitous ARP message over a specific interface */
+int send_gratuitous_arp(vrrp_rt * vrrp, int addr)
+{
+       char buflen                     = sizeof(m_arphdr) + ETHER_HDR_LEN;
+       char *buf                       = (char *)MALLOC(buflen);
+       struct ether_header *eth        = (struct ether_header *) buf;
+       m_arphdr *arph                  = (m_arphdr *) (buf + ETHER_HDR_LEN);
+       char *hwaddr                    = IF_HWADDR(vrrp->ifp);
+       int len;
+
+       /* Ethernet header */
+       memset(eth->ether_dhost, 0xFF, ETH_ALEN);
+       memcpy(eth->ether_shost, hwaddr, ETH_ALEN);
+       eth->ether_type = htons(ETHERTYPE_ARP);
+
+       /* ARP payload */
+       arph->ar_hrd = htons(ARPHRD_ETHER);
+       arph->ar_pro = htons(ETHERTYPE_IP);
+       arph->ar_hln = ETHERNET_HW_LEN;
+       arph->ar_pln = IPPROTO_ADDR_LEN;
+       arph->ar_op = htons(ARPOP_REQUEST);
+       memcpy(arph->__ar_sha, hwaddr, ETH_ALEN);
+       memcpy(arph->__ar_sip, &addr, sizeof (addr));
+       memcpy(arph->__ar_tip, &addr, sizeof (addr));
+
+       /* Send the ARP message */
+       len = send_arp(vrrp, buf, buflen);
+
+       FREE(buf);
+       return len;
+}
index 15c33fd..bfbee33 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Interfaces manipulation.
  *
- * Version:     $Id: vrrp_if.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_if.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -48,6 +48,7 @@ typedef __uint8_t u8;
 /* local include */
 #include "scheduler.h"
 #include "data.h"
+#include "vrrp.h"
 #include "vrrp_if.h"
 #include "vrrp_netlink.h"
 #include "memory.h"
@@ -382,3 +383,128 @@ if_mii_poller_init(void)
        /* Register NIC Heartbeat monitoring thread */
        thread_add_timer(master, if_monitor_thread, NULL, POLLING_DELAY);
 }
+
+int
+if_join_vrrp_group(int sd, interface *ifp, int proto)
+{
+       struct ip_mreqn req_add;
+       int ret;
+
+       /* -> outbound processing option
+        * join the multicast group.
+        * binding the socket to the interface for outbound multicast
+        * traffic.
+        */
+       memset(&req_add, 0, sizeof (req_add));
+       req_add.imr_multiaddr.s_addr = htonl(INADDR_VRRP_GROUP);
+       req_add.imr_address.s_addr = IF_ADDR(ifp);
+       req_add.imr_ifindex = IF_INDEX(ifp);
+
+       /* -> Need to handle multicast convergance after takeover.
+        * We retry until multicast is available on the interface.
+        */
+       ret = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                        (char *) &req_add, sizeof (struct ip_mreqn));
+       if (ret < 0) {
+               syslog(LOG_INFO, "cant do IP_ADD_MEMBERSHIP errno=%s (%d)",
+                      strerror(errno), errno);
+               close(sd);
+               return -1;
+        }
+
+       return sd;
+}
+
+void
+if_leave_vrrp_group(int sd, interface *ifp)
+{
+       struct ip_mreqn req_add;
+       int ret = 0;
+
+       /* If fd is -1 then we add a membership trouble */
+       if (sd < 0)
+               return;
+
+       /* Leaving the VRRP multicast group */
+       memset(&req_add, 0, sizeof (req_add));
+       req_add.imr_multiaddr.s_addr = htonl(INADDR_VRRP_GROUP);
+       req_add.imr_address.s_addr = IF_ADDR(ifp);
+       req_add.imr_ifindex = IF_INDEX(ifp);
+       ret = setsockopt(sd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+                        (char *) &req_add, sizeof (struct ip_mreqn));
+       if (ret < 0) {
+               syslog(LOG_INFO, "cant do IP_DROP_MEMBERSHIP errno=%s (%d)",
+                      strerror(errno), errno);
+               return;
+       }
+
+       /* Finally close the desc */
+       close(sd);
+}
+
+int
+if_setsockopt_bindtodevice(int sd, interface *ifp)
+{
+       int ret;
+
+       if (sd < 0)
+               return sd;
+
+       /* -> inbound processing option
+        * Specify the bound_dev_if.
+        * why IP_ADD_MEMBERSHIP & IP_MULTICAST_IF doesnt set
+        * sk->bound_dev_if themself ??? !!!
+        * Needed for filter multicasted advert per interface.
+        *
+        * -- If you read this !!! and know the answer to the question
+        *    please feel free to answer me ! :)
+        */
+       ret = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, IF_NAME(ifp)
+                        , strlen(IF_NAME(ifp)) + 1);
+       if (ret < 0) {
+               int err = errno;
+               syslog(LOG_INFO,
+                      "cant bind to device %s. errno=%d. (try to run it as root)",
+                      IF_NAME(ifp), err);
+               close(sd);
+               sd = -1;
+       }
+
+       return sd;
+}
+
+int
+if_setsockopt_hdrincl(int sd)
+{
+       int ret;
+       int on = 1;
+
+       /* Include IP header into RAW protocol packet */
+       ret = setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
+       if (ret < 0) {
+               int err = errno;
+               syslog(LOG_INFO, "cant set HDRINCL IP option. errno=%d.", err);
+               close(sd);
+               return -1;
+       }
+
+       return sd;
+}
+
+int
+if_setsockopt_mcast_loop(int sd)
+{
+       int ret;
+       unsigned char loop = 0;
+
+       /* Include IP header into RAW protocol packet */
+       ret = setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
+       if (ret < 0) {
+               int err = errno;
+               syslog(LOG_INFO, "cant set MULTICAST_LOOP IP option. errno=%d.", err);
+               close(sd);
+               return -1;
+       }
+
+       return sd;
+}
index 970b2cf..60c0735 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK IPv4 address manipulation.
  *
- * Version:     $Id: vrrp_ipaddress.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index e5c86a5..f717474 100644 (file)
@@ -7,7 +7,7 @@
  *              authentication data encryption using HMAC MD5 according to
  *              RFCs 2085 & 2104.
  *
- * Version:     $Id: vrrp_ipsecah.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 885603a..ca4a522 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK kernel command channel.
  *
- * Version:     $Id: vrrp_netlink.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_netlink.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 698b243..20f53db 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        VRRP state transition notification scripts handling.
  *
- * Version:     $Id: vrrp_notify.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_notify.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 769126c..29bf940 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Sheduling framework for vrrp code.
  *
- * Version:     $Id: vrrp_scheduler.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -126,7 +126,7 @@ struct {
   { {NULL}, {NULL},                      {NULL},             {NULL}            },
   { {NULL}, {vrrp_sync_master_election}, {vrrp_sync_master}, {vrrp_sync_fault} },
   { {NULL}, {vrrp_sync_backup},          {NULL},             {vrrp_sync_fault} },
-  { {NULL}, {NULL},                      {NULL},             {vrrp_sync_fault} }
+  { {NULL}, {vrrp_sync_backup},          {vrrp_sync_master}, {vrrp_sync_fault} }
 };
 
 
@@ -457,7 +457,7 @@ vrrp_backup(vrrp_rt * vrrp, char *vrrp_buffer, int len)
        if (iph->protocol == IPPROTO_IPSEC_AH) {
                ah = (ipsec_ah *) (vrrp_buffer + sizeof (struct iphdr));
                if (ah->seq_number >= vrrp->ipsecah_counter->seq_number) {
-                       vrrp->ipsecah_counter->seq_number = ah->seq_number + 10;
+//                     vrrp->ipsecah_counter->seq_number = ah->seq_number + 10;
                        vrrp->ipsecah_counter->cycle = 0;
                }
        }
@@ -476,10 +476,10 @@ vrrp_become_master(vrrp_rt * vrrp, char *vrrp_buffer, int len)
         * with the remote IPSEC AH VRRP instance counter.
         */
        if (iph->protocol == IPPROTO_IPSEC_AH) {
-               syslog(LOG_INFO, "VRRP_Instance(%s) AH seq_num sync",
+               syslog(LOG_INFO, "VRRP_Instance(%s) IPSEC-AH : seq_num sync",
                       vrrp->iname);
                ah = (ipsec_ah *) (vrrp_buffer + sizeof (struct iphdr));
-               vrrp->ipsecah_counter->seq_number = ah->seq_number + 5;
+               vrrp->ipsecah_counter->seq_number = ah->seq_number + 1;
                vrrp->ipsecah_counter->cycle = 0;
        }
 
index a16e954..2cc004c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        VRRP synchronization framework.
  *
- * Version:     $Id: vrrp_sync.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vrrp_sync.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -101,7 +101,13 @@ vrrp_sync_group_up(vrrp_sgroup * vgroup)
                if (IF_ISUP(isync->ifp))
                        is_up++;
        }
-       return (is_up == VECTOR_SIZE(vgroup->iname)) ? 1 : 0;
+
+       if (is_up == VECTOR_SIZE(vgroup->iname)) {
+               syslog(LOG_INFO, "Kernel is reporting: Group(%s) UP"
+                              , GROUP_NAME(vgroup));
+               return 1;
+       }
+       return 0;
 }
 
 /* Leaving fault state */
@@ -160,9 +166,6 @@ vrrp_sync_backup(vrrp_rt * vrrp)
        vrrp_rt *isync;
        vrrp_sgroup *vgroup = vrrp->sync;
 
-       if (GROUP_STATE(vrrp->sync) != VRRP_STATE_MAST)
-               return;
-
        syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to BACKUP state",
               GROUP_NAME(vrrp->sync));
 
@@ -187,9 +190,6 @@ vrrp_sync_master(vrrp_rt * vrrp)
        vrrp_rt *isync;
        vrrp_sgroup *vgroup = vrrp->sync;
 
-       if (GROUP_STATE(vrrp->sync) != VRRP_STATE_BACK)
-               return;
-
        syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to MASTER state",
               GROUP_NAME(vrrp->sync));
 
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644 (file)
index 0000000..4df501a
--- /dev/null
@@ -0,0 +1,35 @@
+# Makefile
+#
+# Keepalived OpenSource project.
+#
+# Copyright (C) 2001, 2002 Alexandre Cassen, <acassen@linux-vs.org>
+
+CC      = @CC@
+INCLUDES = -I.
+CFLAGS  = @CFLAGS@ $(INCLUDES) \
+          -Wall -Wunused -Wstrict-prototypes
+DEFS    = @DFLAGS@
+COMPILE         = $(CC) $(CFLAGS) $(DEFS)
+
+OBJS =         memory.o utils.o timer.o scheduler.o vector.o list.o html.o
+HEADERS = $(OBJS:.o=.h)
+
+.c.o:
+       $(COMPILE) -c $<
+
+all:   $(OBJS)
+
+clean:
+       rm -f *.a *.o *~
+
+distclean: clean
+       rm -f Makefile
+
+
+memory.o: memory.c memory.h
+utils.o: utils.c utils.h
+timer.o: timer.c timer.h
+scheduler.o: scheduler.c scheduler.h memory.h utils.h
+vector.o: vector.c vector.h memory.h
+list.o: list.c list.h memory.h
+html.o: html.h memory.h
diff --git a/lib/html.c b/lib/html.c
new file mode 100644 (file)
index 0000000..3cbd322
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        HTML stream parser utility functions.
+ *
+ * Version:     $Id: html.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include "html.h"
+#include "memory.h"
+
+/* Return the http header content length */
+int extract_content_length(char *buffer, int size)
+{
+       char *clen = strstr(buffer, CONTENT_LENGTH);
+       char *content_buffer = NULL;
+       char *buf_len;
+       int inc = 0;
+       int i;
+
+       /* Allocate the room */
+       buf_len = (char *)MALLOC(40);
+
+       /* Pattern not found */
+       if (!clen)
+               return 0;
+
+       /* Content-Length extraction */
+       while (*(clen++) != ':');
+       content_buffer = clen;
+       while (*(clen++) != '\r' && *clen != '\n')
+               inc++;
+       for (i = 0; i < inc; i++)
+               strncat(buf_len, content_buffer+i, 1);
+       i = atoi(buf_len);
+       FREE(buf_len);
+       return i;
+}
+
+/*
+ * Return the http header error code. According
+ * to rfc2616.6.1 status code is between HTTP_Version
+ * and Reason_Phrase, separated by space caracter.
+ */
+int extract_status_code(char *buffer, int size)
+{
+       char *buf_code;
+       char *begin;
+       char *end = buffer + size;
+       int inc = 0;
+
+       /* Allocate the room */
+       buf_code = (char *)MALLOC(10);
+
+       /* Status-Code extraction */
+       while (buffer < end && *buffer++ != ' ') ;
+       begin = buffer;
+       while (buffer < end && *buffer++ != ' ')
+               inc++;
+       strncat(buf_code, begin, inc);
+       inc = atoi(buf_code);
+       FREE(buf_code);
+       return inc;
+}
+
+/* simple function returning a pointer to the html buffer begin */
+char *extract_html(char *buffer, int size_buffer)
+{
+       char *end = buffer + size_buffer;
+
+       while (buffer < end &&
+              !(*buffer++ == '\n' &&
+               (*buffer == '\n' || (*buffer++ == '\r' && *buffer == '\n')))) ;
+
+       if (*buffer == '\n')
+               return buffer + 1;
+       return NULL;
+}
diff --git a/lib/html.h b/lib/html.h
new file mode 100644 (file)
index 0000000..01a880b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Soft:        Perform a GET query to a remote HTTP/HTTPS server.
+ *              Set a timer to compute global remote server response
+ *              time.
+ *
+ * Part:        parser.c include file.
+ *
+ * Version:     $Id: html.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ *
+ * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _HTML_H
+#define _HTML_H
+
+/* HTTP header tag */
+#define CONTENT_LENGTH "Content-Length:"
+
+/* Prototypes */
+extern int extract_content_length(char *buffer, int size);
+extern int extract_status_code(char *buffer, int size);
+extern char *extract_html(char *buffer, int size_buffer);
+
+#endif
similarity index 96%
rename from keepalived/core/list.c
rename to lib/list.c
index e497110..9c52964 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        List structure manipulation.
  *  
- * Version:     $Id: list.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: list.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
similarity index 96%
rename from keepalived/include/list.h
rename to lib/list.h
index 31f4a9b..1d2ce45 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        list.c include file.
  *  
- * Version:     $Id: list.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: list.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
similarity index 99%
rename from keepalived/core/memory.c
rename to lib/memory.c
index 193b368..0f2e77e 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        Memory management framework. This framework is used to
  *              find any memory leak.
  *
- * Version:     $Id: memory.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: memory.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
similarity index 93%
rename from keepalived/include/memory.h
rename to lib/memory.h
index ae1bc66..8ed8fa2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        memory.c include file.
  *
- * Version:     $Id: memory.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: memory.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
@@ -30,6 +30,9 @@
 #include <stdlib.h>
 #include <string.h>
 
+/* Global var */
+unsigned long mem_allocated;   /* Total memory used in Bytes */
+
 /* extern types */
 extern unsigned int debug;
 extern unsigned long mem_allocated;
similarity index 99%
rename from keepalived/core/scheduler.c
rename to lib/scheduler.c
index a19a9c1..c97e59a 100644 (file)
@@ -7,7 +7,7 @@
  *              the thread management routine (thread.c) present in the 
  *              very nice zebra project (http://www.zebra.org).
  *
- * Version:     $Id: scheduler.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: scheduler.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
similarity index 98%
rename from keepalived/include/scheduler.h
rename to lib/scheduler.h
index 94d95ae..80989cf 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        scheduler.c include file.
  *
- * Version:     $Id: scheduler.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: scheduler.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
similarity index 84%
rename from keepalived/core/timer.c
rename to lib/timer.c
index 372d78a..bb51393 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        Timer manipulations.
  *  
- * Version:     $Id: timer.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: timer.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -20,6 +20,7 @@
  *              2 of the License, or (at your option) any later version.
  */
 
+#include <stdio.h>
 #include <string.h>
 #include "timer.h"
 
@@ -87,3 +88,21 @@ timer_sub_now(TIMEVAL a)
 {
        return timer_sub(timer_now(), a);
 }
+
+/* print timer value */
+void
+timer_dump(TIMEVAL a)
+{
+       unsigned long timer;
+       timer = a.tv_sec * TIMER_HZ + a.tv_usec;
+       printf("=> %lu (usecs)\n", timer);
+}
+
+unsigned long
+timer_tol(TIMEVAL a)
+{
+       unsigned long timer;
+       timer = a.tv_sec * TIMER_HZ + a.tv_usec;
+       return timer;
+}
+
similarity index 91%
rename from keepalived/include/timer.h
rename to lib/timer.h
index 80023c0..0cffce7 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        timer.c include file.
  *  
- * Version:     $Id: timer.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: timer.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -41,5 +41,7 @@ extern TIMEVAL timer_dup(TIMEVAL b);
 extern int timer_cmp(TIMEVAL a, TIMEVAL b);
 extern TIMEVAL timer_sub(TIMEVAL a, TIMEVAL b);
 extern TIMEVAL timer_sub_now(TIMEVAL a);
+extern void timer_dump(TIMEVAL a);
+extern unsigned long timer_tol(TIMEVAL a);
 
 #endif
similarity index 98%
rename from keepalived/core/utils.c
rename to lib/utils.c
index bc172eb..d794b78 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        General program utils.
  *
- * Version:     $Id: utils.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: utils.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
similarity index 96%
rename from keepalived/include/utils.h
rename to lib/utils.h
index af24674..2e0346d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        utils.h include file.
  *
- * Version:     $Id: utils.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: utils.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
similarity index 97%
rename from keepalived/core/vector.c
rename to lib/vector.c
index 1ea9f27..5bd67ed 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        Vector structure manipulation.
  *  
- * Version:     $Id: vector.c,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vector.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
similarity index 95%
rename from keepalived/include/vector.h
rename to lib/vector.h
index 1c8022b..02bccc8 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        vector.c include file.
  *  
- * Version:     $Id: vector.h,v 0.7.1 2002/09/17 22:03:31 acassen Exp $
+ * Version:     $Id: vector.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *