MAJOR: connection: replace struct target with a pointer to an enum

Instead of storing a couple of (int, ptr) in the struct connection
and the struct session, we use a different method : we only store a
pointer to an integer which is stored inside the target object and
which contains a unique type identifier. That way, the pointer allows
us to retrieve the object type (by dereferencing it) and the object's
address (by computing the displacement in the target structure). The
NULL pointer always corresponds to OBJ_TYPE_NONE.

This reduces the size of the connection and session structs. It also
simplifies target assignment and compare.

In order to improve the generated code, we try to put the obj_type
element at the beginning of all the structs (listener, server, proxy,
si_applet), so that the original and target pointers are always equal.

A lot of code was touched by massive replaces, but the changes are not
that important.
diff --git a/include/types/connection.h b/include/types/connection.h
index 57e9fea..6149dd5 100644
--- a/include/types/connection.h
+++ b/include/types/connection.h
@@ -28,6 +28,7 @@
 #include <common/config.h>
 
 #include <types/listener.h>
+#include <types/obj_type.h>
 #include <types/protocol.h>
 
 /* referenced below */
@@ -141,16 +142,6 @@
 	CO_FL_XPRT_TRACKED  = 0x80000000,
 };
 
-/* target types */
-enum {
-	TARG_TYPE_NONE = 0,         /* no target set, pointer is NULL by definition */
-	TARG_TYPE_CLIENT,           /* target is a client, pointer is NULL by definition */
-	TARG_TYPE_PROXY,            /* target is a proxy   ; use address with the proxy's settings */
-	TARG_TYPE_SERVER,           /* target is a server  ; use address with server's and its proxy's settings */
-	TARG_TYPE_APPLET,           /* target is an applet ; use only the applet */
-};
-
-
 /* xprt_ops describes transport-layer operations for a connection. They
  * generally run over a socket-based control layer, but not always. Some
  * of them are used for data transfer with the upper layer (rcv_*, snd_*)
@@ -184,18 +175,6 @@
 	int  (*init)(struct connection *conn);  /* data-layer initialization */
 };
 
-/* a target describes what is on the remote side of the connection. */
-struct target {
-	int type;
-	union {
-		void *v;              /* pointer value, for any type */
-		struct proxy *p;      /* when type is TARG_TYPE_PROXY  */
-		struct server *s;     /* when type is TARG_TYPE_SERVER */
-		struct si_applet *a;  /* when type is TARG_TYPE_APPLET */
-		struct listener *l;   /* when type is TARG_TYPE_CLIENT */
-	} ptr;
-} __attribute__((packed));
-
 /* This structure describes a connection with its methods and data.
  * A connection may be performed to proxy or server via a local or remote
  * socket, and can also be made to an internal applet. It can support
@@ -216,7 +195,7 @@
 			int fd;       /* file descriptor for a stream driver when known */
 		} sock;
 	} t;
-	struct target target;         /* the target to connect to (server, proxy, applet, ...) */
+	enum obj_type *target;        /* the target to connect to (server, proxy, applet, ...) */
 	struct {
 		struct sockaddr_storage from;	/* client address, or address to spoof when connecting to the server */
 		struct sockaddr_storage to;	/* address reached by the client, or address to connect to */
diff --git a/include/types/listener.h b/include/types/listener.h
index 918ba0a..323c996 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -31,6 +31,7 @@
 
 #include <common/config.h>
 #include <common/mini-clist.h>
+#include <types/obj_type.h>
 #include <eb32tree.h>
 
 /* Some pointer types reference below */
@@ -146,6 +147,7 @@
  * the fdtab.
  */
 struct listener {
+	enum obj_type obj_type;         /* object type = OBJ_TYPE_LISTENER */
 	int fd;				/* the listen socket */
 	char *name;			/* */
 	int luid;			/* listener universally unique ID, used for SNMP */
diff --git a/include/types/obj_type.h b/include/types/obj_type.h
new file mode 100644
index 0000000..cfb3e34
--- /dev/null
+++ b/include/types/obj_type.h
@@ -0,0 +1,49 @@
+/*
+ * include/types/obj_type.h
+ * This file declares some object types for use in various structures.
+ *
+ * Copyright (C) 2000-2012 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 _TYPES_OBJ_TYPE_H
+#define _TYPES_OBJ_TYPE_H
+
+/* The principle is to be able to change the type of a pointer by pointing
+ * it directly to an object type. The object type indicates the format of the
+ * structure holing the type, and this is used to retrieve the pointer to the
+ * beginning of the structure. Doing so saves us from having to maintain both
+ * a pointer and a type for elements such as connections which can point to
+ * various types of objects.
+ */
+
+/* object types */
+enum obj_type {
+	OBJ_TYPE_NONE = 0,     /* pointer is NULL by definition */
+	OBJ_TYPE_LISTENER,     /* object is a struct listener */
+	OBJ_TYPE_PROXY,        /* object is a struct proxy */
+	OBJ_TYPE_SERVER,       /* object is a struct server */
+	OBJ_TYPE_APPLET,       /* object is a struct si_applet */
+};
+
+#endif /* _TYPES_OBJ_TYPE_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 343d4ad..5d99423 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -42,6 +42,7 @@
 #include <types/freq_ctr.h>
 #include <types/listener.h>
 #include <types/log.h>
+#include <types/obj_type.h>
 #include <types/proto_http.h>
 #include <types/sample.h>
 #include <types/session.h>
@@ -200,10 +201,11 @@
 };
 
 struct proxy {
-	struct in_addr mon_net, mon_mask;	/* don't forward connections from this net (network order) FIXME: should support IPv6 */
+	enum obj_type obj_type;                 /* object type == OBJ_TYPE_PROXY */
 	int state;				/* proxy state */
 	int options;				/* PR_O_REDISP, PR_O_TRANSP, ... */
 	int options2;				/* PR_O2_* */
+	struct in_addr mon_net, mon_mask;	/* don't forward connections from this net (network order) FIXME: should support IPv6 */
 	unsigned int ck_opts;			/* PR_CK_* (cookie options) */
 	unsigned int fe_req_ana, be_req_ana;	/* bitmap of common request protocol analysers for the frontend and backend */
 	unsigned int fe_rsp_ana, be_rsp_ana;	/* bitmap of common response protocol analysers for the frontend and backend */
diff --git a/include/types/server.h b/include/types/server.h
index e65c2c0..4806ffa 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -36,6 +36,7 @@
 #include <types/connection.h>
 #include <types/counters.h>
 #include <types/freq_ctr.h>
+#include <types/obj_type.h>
 #include <types/port_range.h>
 #include <types/proxy.h>
 #include <types/queue.h>
@@ -107,6 +108,7 @@
 };
 
 struct server {
+	enum obj_type obj_type;                 /* object type == OBJ_TYPE_SERVER */
 	struct server *next;
 	int state;				/* server state (SRV_*) */
 	int prev_state;				/* server state before last change (SRV_*) */
diff --git a/include/types/session.h b/include/types/session.h
index ae11f81..f0a5be6 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -34,6 +34,7 @@
 #include <types/channel.h>
 #include <types/compression.h>
 
+#include <types/obj_type.h>
 #include <types/proto_http.h>
 #include <types/proxy.h>
 #include <types/queue.h>
@@ -99,15 +100,14 @@
  *    immediately assigned when SN_DIRECT is determined. Both must be cleared
  *    when clearing SN_DIRECT (eg: redispatch).
  *  - ->srv has no meaning without SN_ASSIGNED and must not be checked without
- *    it. ->target and ->target_type may be used to check previous ->srv after
- *    a failed connection attempt.
+ *    it. ->target may be used to check previous ->srv after a failed connection attempt.
  *  - a session being processed has srv_conn set.
  *  - srv_conn might remain after SN_DIRECT has been reset, but the assigned
  *    server should eventually be released.
  */
 struct session {
 	int flags;				/* some flags describing the session */
-	struct target target;			/* target to use for this session */
+	enum obj_type *target;			/* target to use for this session */
 
 	struct channel *req;			/* request buffer */
 	struct channel *rep;			/* response buffer */
diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h
index 04c0dca..a808491 100644
--- a/include/types/stream_interface.h
+++ b/include/types/stream_interface.h
@@ -27,6 +27,7 @@
 
 #include <types/channel.h>
 #include <types/connection.h>
+#include <types/obj_type.h>
 #include <common/config.h>
 
 /* A stream interface must have its own errors independently of the buffer's,
@@ -160,8 +161,9 @@
 
 /* An applet designed to run in a stream interface */
 struct si_applet {
-	char *name; /* applet's name to report in logs */
-	void (*fct)(struct stream_interface *);  /* internal I/O handler, may never be NULL */
+	enum obj_type obj_type;                      /* object type = OBJ_TYPE_APPLET */
+	char *name;                                  /* applet's name to report in logs */
+	void (*fct)(struct stream_interface *);      /* internal I/O handler, may never be NULL */
 	void (*release)(struct stream_interface *);  /* callback to release resources, may be NULL */
 };