[MEDIUM] check for cttproxy support when required

Previously, use of the "usesrc" keyword could silently fail if
either the module was not loaded, or the user did not have enough
permissions. Now the errors are better diagnosed and more appropriate
advices are given.
diff --git a/Makefile b/Makefile
index d9b12f9..a08f010 100644
--- a/Makefile
+++ b/Makefile
@@ -94,7 +94,6 @@
 # set some defines when needed.
 # Known ones are -DENABLE_POLL, -DENABLE_EPOLL, and -DUSE_MY_EPOLL
 # - use -DTPROXY to compile with transparent proxy support.
-# - use -DCONFIG_HAP_CTTPROXY to enable full transparent proxy support
 DEFINE = -DTPROXY
 
 # Now let's determine the version, sub-version and release date.
@@ -119,13 +118,16 @@
 
 # do not change this one, enable USE_* variables instead.
 OPTIONS =
+OPT_OBJS =
 
 ifneq ($(USE_TCPSPLICE),)
 OPTIONS += -DCONFIG_HAP_TCPSPLICE
 endif
 
+# - set USE_CTTPROXY to enable full transparent proxy support
 ifneq ($(USE_CTTPROXY),)
 OPTIONS += -DCONFIG_HAP_CTTPROXY
+OPT_OBJS += src/cttproxy.o
 endif
 
 ifneq ($(USE_TPROXY),)
@@ -199,7 +201,7 @@
        src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
        src/session.o src/hdr_idx.o src/rbtree.o
 
-haproxy: $(OBJS)
+haproxy: $(OBJS) $(OPT_OBJS)
 	$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
 
 objsize: haproxy
diff --git a/include/proto/cttproxy.h b/include/proto/cttproxy.h
new file mode 100644
index 0000000..f343037
--- /dev/null
+++ b/include/proto/cttproxy.h
@@ -0,0 +1,47 @@
+/*
+  include/proto/cttproxy.h
+  This file contains prototypes for Linux's cttproxy interface.
+  This file should be included only if CTTPROXY is enabled.
+
+  Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation, version 2.1
+  exclusively.
+
+  This library 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
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _PROTO_CTTPROXY_H
+#define _PROTO_CTTPROXY_H
+
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <common/config.h>
+#include <import/ip_tproxy.h>
+
+/*
+ * Checks that CTTPROXY is available and in the right version.
+ * Returns 0 if OK, -1 if wrong version, -2 if not available or other error.
+ */
+int check_cttproxy_version();
+
+
+#endif /* _PROTO_CTTPROXY_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/src/cttproxy.c b/src/cttproxy.c
new file mode 100644
index 0000000..04c3df2
--- /dev/null
+++ b/src/cttproxy.c
@@ -0,0 +1,64 @@
+/*
+ * Functions for managing transparent proxying with CTTPROXY.
+ * This file should be compiled only if CTTPROXY is enabled.
+ *
+ * Copyright 2000-2007 Willy Tarreau <w@1wt.eu>
+ *
+ * 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 <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <common/compat.h>
+#include <common/config.h>
+#include <common/time.h>
+
+#include <types/global.h>
+
+#include <import/ip_tproxy.h>
+
+/*
+ * Checks that CTTPROXY is available and in the right version.
+ * Returns 0 if OK, -1 if wrong version, -2 if not available or other error.
+ */
+int check_cttproxy_version() {
+	struct in_tproxy itp1;
+	int fd;
+
+	memset(&itp1, 0, sizeof(itp1));
+		
+	fd = socket(AF_INET, SOCK_STREAM, 0);
+	if (fd == -1)
+		return -2;
+
+	itp1.op = TPROXY_VERSION;
+	itp1.v.version = 0x02000000; /* CTTPROXY version 2.0 expected */
+	
+	if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp1, sizeof(itp1)) == -1) {
+		if (errno == -EINVAL)
+			return -1; /* wrong version */
+		else
+			return -2; /* not supported or other error */
+	}
+	return 0;
+}
+
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/src/haproxy.c b/src/haproxy.c
index 3fe500b..a4afca3 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -94,6 +94,10 @@
 #include <libtcpsplice.h>
 #endif
 
+#ifdef CONFIG_HAP_CTTPROXY
+#include <proto/cttproxy.h>
+#endif
+
 /*********************************************************************/
 
 /*********************************************************************/
@@ -768,6 +772,27 @@
 	}
 #endif
 
+#ifdef CONFIG_HAP_CTTPROXY
+	if (global.last_checks & LSTCHK_CTTPROXY) {
+		int ret;
+
+		ret = check_cttproxy_version();
+		if (ret < 0) {
+			Alert("[%s.main()] Cannot enable cttproxy.\n%s",
+			      argv[0],
+			      (ret == -1) ? "  Incorrect module version.\n"
+			      : "  Make sure you have enough permissions and that the module is loaded.\n");
+			exit(1);
+		}
+	}
+#endif
+
+	if ((global.last_checks & LSTCHK_NETADM) && global.uid) {
+		Alert("[%s.main()] Some configuration options require full privileges, so global.uid cannot be changed.\n"
+		      "", argv[0], global.gid);
+		exit(1);
+	}
+
 	if (nb_oldpids)
 		tell_old_pids(oldpids_sig);