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/src/backend.c b/src/backend.c
index 82a88be..f4b90ce 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -38,6 +38,7 @@
 #include <proto/lb_fwlc.h>
 #include <proto/lb_fwrr.h>
 #include <proto/lb_map.h>
+#include <proto/obj_type.h>
 #include <proto/protocol.h>
 #include <proto/proto_http.h>
 #include <proto/proto_tcp.h>
@@ -489,7 +490,7 @@
 	if (unlikely(s->pend_pos || s->flags & SN_ASSIGNED))
 		goto out_err;
 
-	prev_srv  = target_srv(&s->target);
+	prev_srv  = objt_server(s->target);
 	conn_slot = s->srv_conn;
 
 	/* We have to release any connection slot before applying any LB algo,
@@ -498,13 +499,13 @@
 	if (conn_slot)
 		sess_change_server(s, NULL);
 
-	/* We will now try to find the good server and store it into <target_srv(&s->target)>.
-	 * Note that <target_srv(&s->target)> may be NULL in case of dispatch or proxy mode,
+	/* We will now try to find the good server and store it into <objt_server(s->target)>.
+	 * Note that <objt_server(s->target)> may be NULL in case of dispatch or proxy mode,
 	 * as well as if no server is available (check error code).
 	 */
 
 	srv = NULL;
-	clear_target(&s->target);
+	s->target = NULL;
 
 	if (s->be->lbprm.algo & BE_LB_KIND) {
 		/* we must check if we have at least one server available */
@@ -631,15 +632,15 @@
 			s->be->be_counters.cum_lbconn++;
 			srv->counters.cum_lbconn++;
 		}
-		set_target_server(&s->target, srv);
+		s->target = &srv->obj_type;
 	}
 	else if (s->be->options & (PR_O_DISPATCH | PR_O_TRANSP)) {
-		set_target_proxy(&s->target, s->be);
+		s->target = &s->be->obj_type;
 	}
 	else if ((s->be->options & PR_O_HTTP_PROXY) &&
 		 is_addr(&s->req->cons->conn->addr.to)) {
 		/* in proxy mode, we need a valid destination address */
-		set_target_proxy(&s->target, s->be);
+		s->target = &s->be->obj_type;
 	}
 	else {
 		err = SRV_STATUS_NOSRV;
@@ -691,7 +692,7 @@
 		if (!(s->flags & SN_ASSIGNED))
 			return SRV_STATUS_INTERNAL;
 
-		s->req->cons->conn->addr.to = target_srv(&s->target)->addr;
+		s->req->cons->conn->addr.to = objt_server(s->target)->addr;
 
 		if (!is_addr(&s->req->cons->conn->addr.to)) {
 			/* if the server has no address, we use the same address
@@ -710,7 +711,7 @@
 
 		/* if this server remaps proxied ports, we'll use
 		 * the port the client connected to with an offset. */
-		if (target_srv(&s->target)->state & SRV_MAPPORTS) {
+		if (objt_server(s->target)->state & SRV_MAPPORTS) {
 			int base_port;
 
 			if (!(s->be->options & PR_O_TRANSP))
@@ -764,7 +765,7 @@
  * Returns :
  *
  *   SRV_STATUS_OK       if everything is OK.
- *   SRV_STATUS_NOSRV    if no server is available. target_srv(&s->target) = NULL.
+ *   SRV_STATUS_NOSRV    if no server is available. objt_server(s->target) = NULL.
  *   SRV_STATUS_QUEUED   if the connection has been queued.
  *   SRV_STATUS_FULL     if the server(s) is/are saturated and the
  *                       connection could not be queued at the server's,
@@ -783,7 +784,7 @@
 
 	err = SRV_STATUS_OK;
 	if (!(s->flags & SN_ASSIGNED)) {
-		struct server *prev_srv = target_srv(&s->target);
+		struct server *prev_srv = objt_server(s->target);
 
 		err = assign_server(s);
 		if (prev_srv) {
@@ -796,7 +797,7 @@
 			 *  - if the server remained the same : update retries.
 			 */
 
-			if (prev_srv != target_srv(&s->target)) {
+			if (prev_srv != objt_server(s->target)) {
 				if ((s->txn.flags & TX_CK_MASK) == TX_CK_VALID) {
 					s->txn.flags &= ~TX_CK_MASK;
 					s->txn.flags |= TX_CK_DOWN;
@@ -814,7 +815,7 @@
 	switch (err) {
 	case SRV_STATUS_OK:
 		/* we have SN_ASSIGNED set */
-		srv = target_srv(&s->target);
+		srv = objt_server(s->target);
 		if (!srv)
 			return SRV_STATUS_OK;   /* dispatch or proxy mode */
 
@@ -882,7 +883,7 @@
 static void assign_tproxy_address(struct session *s)
 {
 #if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
-	struct server *srv = target_srv(&s->target);
+	struct server *srv = objt_server(s->target);
 
 	if (srv && srv->state & SRV_BIND_SRC) {
 		switch (srv->state & SRV_TPROXY_MASK) {
@@ -981,13 +982,13 @@
 	}
 
 	/* the target was only on the session, assign it to the SI now */
-	copy_target(&s->req->cons->conn->target, &s->target);
+	s->req->cons->conn->target = s->target;
 
 	/* set the correct protocol on the output stream interface */
-	if (s->target.type == TARG_TYPE_SERVER) {
-		si_prepare_conn(s->req->cons, target_srv(&s->target)->proto, target_srv(&s->target)->xprt);
+	if (objt_server(s->target)) {
+		si_prepare_conn(s->req->cons, objt_server(s->target)->proto, objt_server(s->target)->xprt);
 	}
-	else if (s->target.type == TARG_TYPE_PROXY) {
+	else if (obj_type(s->target) == OBJ_TYPE_PROXY) {
 		/* proxies exclusively run on raw_sock right now */
 		si_prepare_conn(s->req->cons, protocol_by_family(s->req->cons->conn->addr.to.ss_family), &raw_sock);
 		if (!si_ctrl(s->req->cons))
@@ -998,7 +999,7 @@
 
 	/* process the case where the server requires the PROXY protocol to be sent */
 	s->req->cons->send_proxy_ofs = 0;
-	if (s->target.type == TARG_TYPE_SERVER && (s->target.ptr.s->state & SRV_SEND_PROXY)) {
+	if (objt_server(s->target) && (objt_server(s->target)->state & SRV_SEND_PROXY)) {
 		s->req->cons->send_proxy_ofs = 1; /* must compute size */
 		conn_get_to_addr(s->req->prod->conn);
 	}
@@ -1021,7 +1022,7 @@
 	/* set connect timeout */
 	s->req->cons->exp = tick_add_ifset(now_ms, s->be->timeout.connect);
 
-	srv = target_srv(&s->target);
+	srv = objt_server(s->target);
 	if (srv) {
 		s->flags |= SN_CURR_SESS;
 		srv->cur_sess++;
@@ -1053,7 +1054,7 @@
 	 */
  redispatch:
 	conn_err = assign_server_and_queue(t);
-	srv = target_srv(&t->target);
+	srv = objt_server(t->target);
 
 	switch (conn_err) {
 	case SRV_STATUS_OK:
@@ -1173,13 +1174,13 @@
 	if (*p != '.')
 		goto no_cookie;
 
-	clear_target(&s->target);
+	s->target = NULL;
 	while (srv) {
 		if (memcmp(&addr, &(srv->addr), sizeof(addr)) == 0) {
 			if ((srv->state & SRV_RUNNING) || (px->options & PR_O_PERSIST)) {
 				/* we found the server and it is usable */
 				s->flags |= SN_DIRECT | SN_ASSIGNED;
-				set_target_server(&s->target, srv);
+				s->target = &srv->obj_type;
 				break;
 			}
 		}
@@ -1488,11 +1489,11 @@
 acl_fetch_srv_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                  const struct arg *args, struct sample *smp)
 {
-	if (!target_srv(&l4->target))
+	if (!objt_server(l4->target))
 		return 0;
 
 	smp->type = SMP_T_UINT;
-	smp->data.uint = target_srv(&l4->target)->puid;
+	smp->data.uint = objt_server(l4->target)->puid;
 
 	return 1;
 }
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 6c58e43..d3b6300 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -35,6 +35,7 @@
 #include <types/capture.h>
 #include <types/compression.h>
 #include <types/global.h>
+#include <types/obj_type.h>
 #include <types/peers.h>
 
 #include <proto/acl.h>
@@ -265,6 +266,7 @@
 
 		for (; port <= end; port++) {
 			l = (struct listener *)calloc(1, sizeof(struct listener));
+			l->obj_type = OBJ_TYPE_LISTENER;
 			LIST_ADDQ(&curproxy->conf.listeners, &l->by_fe);
 			LIST_ADDQ(&bind_conf->listeners, &l->by_bind);
 			l->frontend = curproxy;
@@ -4034,6 +4036,7 @@
 			newsrv->conf.file = strdup(file);
 			newsrv->conf.line = linenum;
 
+			newsrv->obj_type = OBJ_TYPE_SERVER;
 			LIST_INIT(&newsrv->actconns);
 			LIST_INIT(&newsrv->pendconns);
 			do_check = 0;
diff --git a/src/checks.c b/src/checks.c
index e3c8620..f13273e 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -349,7 +349,7 @@
 		p = pendconn_from_px(s->proxy);
 		if (!p)
 			break;
-		set_target_server(&p->sess->target, s);
+		p->sess->target = &s->obj_type;
 		sess = p->sess;
 		pendconn_free(p);
 		task_wakeup(sess->task, TASK_WOKEN_RES);
@@ -1299,7 +1299,7 @@
 		}
 
 		/* prepare a new connection */
-		set_target_server(&conn->target, s);
+		conn->target = &s->obj_type;
 		conn_prepare(conn, &check_conn_cb, s->check.proto, s->check.xprt, s);
 
 		/* no client address */
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 306fc61..5f59dde 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -125,7 +125,7 @@
 {
 	/* we have a dedicated I/O handler for the stats */
 	stream_int_register_handler(&s->si[1], &cli_applet);
-	copy_target(&s->target, &s->si[1].conn->target); // for logging only
+	s->target = s->si[1].conn->target; // for logging only
 	s->si[1].conn->xprt_ctx = s;
 	s->si[1].applet.st1 = 0;
 	s->si[1].applet.st0 = STAT_CLI_INIT;
@@ -3419,8 +3419,8 @@
 		if (sess->be->cap & PR_CAP_BE)
 			chunk_appendf(&trash,
 				     "  server=%s (id=%u)",
-				     target_srv(&sess->target) ? target_srv(&sess->target)->id : "<none>",
-				     target_srv(&sess->target) ? target_srv(&sess->target)->puid : 0);
+				     objt_server(sess->target) ? objt_server(sess->target)->id : "<none>",
+				     objt_server(sess->target) ? objt_server(sess->target)->puid : 0);
 		else
 			chunk_appendf(&trash, "  server=<NONE> (id=-1)");
 
@@ -3638,7 +3638,7 @@
 					     get_host_port(&curr_sess->si[0].conn->addr.from),
 					     curr_sess->fe->id,
 					     (curr_sess->be->cap & PR_CAP_BE) ? curr_sess->be->id : "<NONE>",
-					     target_srv(&curr_sess->target) ? target_srv(&curr_sess->target)->id : "<none>"
+					     objt_server(curr_sess->target) ? objt_server(curr_sess->target)->id : "<none>"
 					     );
 				break;
 			case AF_UNIX:
@@ -3647,7 +3647,7 @@
 					     curr_sess->listener->luid,
 					     curr_sess->fe->id,
 					     (curr_sess->be->cap & PR_CAP_BE) ? curr_sess->be->id : "<NONE>",
-					     target_srv(&curr_sess->target) ? target_srv(&curr_sess->target)->id : "<none>"
+					     objt_server(curr_sess->target) ? objt_server(curr_sess->target)->id : "<none>"
 					     );
 				break;
 			}
@@ -4161,12 +4161,14 @@
 }
 
 struct si_applet http_stats_applet = {
+	.obj_type = OBJ_TYPE_APPLET,
 	.name = "<STATS>", /* used for logging */
 	.fct = http_stats_io_handler,
 	.release = NULL,
 };
 
 static struct si_applet cli_applet = {
+	.obj_type = OBJ_TYPE_APPLET,
 	.name = "<CLI>", /* used for logging */
 	.fct = cli_io_handler,
 	.release = NULL,
diff --git a/src/log.c b/src/log.c
index 79158e0..06a2a57 100644
--- a/src/log.c
+++ b/src/log.c
@@ -800,12 +800,12 @@
 
 	if (!(tolog & LW_SVID))
 		svid = "-";
-	else switch (s->target.type) {
-	case TARG_TYPE_SERVER:
-		svid = s->target.ptr.s->id;
+	else switch (obj_type(s->target)) {
+	case OBJ_TYPE_SERVER:
+		svid = objt_server(s->target)->id;
 		break;
-	case TARG_TYPE_APPLET:
-		svid = s->target.ptr.a->name;
+	case OBJ_TYPE_APPLET:
+		svid = objt_applet(s->target)->name;
 		break;
 	default:
 		svid = "<NOSRV>";
@@ -1175,8 +1175,8 @@
 				break;
 
 			case LOG_FMT_SRVCONN:  // %sc
-				ret = ultoa_o(target_srv(&s->target) ?
-				                 target_srv(&s->target)->cur_sess :
+				ret = ultoa_o(obj_type(s->target) ?
+				                 objt_server(s->target)->cur_sess :
 				                 0, tmplog, dst + maxsize - tmplog);
 				if (ret == NULL)
 					goto out;
diff --git a/src/peers.c b/src/peers.c
index 263cc8a..6870f8f 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -25,7 +25,8 @@
 #include <common/time.h>
 
 #include <types/global.h>
-#include <proto/listener.h>
+#include <types/listener.h>
+#include <types/obj_type.h>
 #include <types/peers.h>
 
 #include <proto/acl.h>
@@ -1040,6 +1041,7 @@
 }
 
 static struct si_applet peer_applet = {
+	.obj_type = OBJ_TYPE_APPLET,
 	.name = "<PEER>", /* used for logging */
 	.fct = peer_io_handler,
 	.release = peer_session_release,
@@ -1052,8 +1054,7 @@
 {
 	struct stream_interface *oldsi;
 
-	if (session->si[0].conn->target.type == TARG_TYPE_APPLET &&
-	    session->si[0].conn->target.ptr.a == &peer_applet) {
+	if (objt_applet(session->si[0].conn->target) == &peer_applet) {
 		oldsi = &session->si[0];
 	}
 	else {
@@ -1077,7 +1078,7 @@
 {
 	 /* we have a dedicated I/O handler for the stats */
 	stream_int_register_handler(&s->si[1], &peer_applet);
-	copy_target(&s->target, &s->si[1].conn->target); // for logging only
+	s->target = s->si[1].conn->target; // for logging only
 	s->si[1].conn->xprt_ctx = s;
 	s->si[1].applet.st0 = PEER_SESSION_ACCEPT;
 
@@ -1161,7 +1162,7 @@
 	s->si[0].err_loc = NULL;
 	s->si[0].release = NULL;
 	s->si[0].send_proxy_ofs = 0;
-	set_target_client(&s->si[0].conn->target, l);
+	s->si[0].conn->target = &l->obj_type;
 	s->si[0].exp = TICK_ETERNITY;
 	s->si[0].flags = SI_FL_NONE;
 	if (s->fe->options2 & PR_O2_INDEPSTR)
@@ -1180,7 +1181,7 @@
 	s->si[1].err_loc = NULL;
 	s->si[1].release = NULL;
 	s->si[1].send_proxy_ofs = 0;
-	set_target_proxy(&s->si[1].conn->target, s->be);
+	s->si[1].conn->target = &s->be->obj_type;
 	si_prepare_conn(&s->si[1], peer->proto, peer->xprt);
 	s->si[1].exp = TICK_ETERNITY;
 	s->si[1].flags = SI_FL_NONE;
@@ -1188,7 +1189,7 @@
 		s->si[1].flags |= SI_FL_INDEP_STR;
 
 	session_init_srv_conn(s);
-	set_target_proxy(&s->target, s->be);
+	s->target = &s->be->obj_type;
 	s->pend_pos = NULL;
 
 	/* init store persistence */
diff --git a/src/proto_http.c b/src/proto_http.c
index c1fd6a7..f86dcc3 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -767,7 +767,7 @@
 	trash.len = strlen(HTTP_302);
 	memcpy(trash.str, HTTP_302, trash.len);
 
-	srv = target_srv(&s->target);
+	srv = objt_server(s->target);
 
 	/* 2: add the server's prefix */
 	if (trash.len + srv->rdr_len > trash.size)
@@ -3202,7 +3202,7 @@
 		s->logs.tv_request = now;
 		s->task->nice = -32; /* small boost for HTTP statistics */
 		stream_int_register_handler(s->rep->prod, &http_stats_applet);
-		copy_target(&s->target, &s->rep->prod->conn->target); // for logging only
+		s->target = s->rep->prod->conn->target; // for logging only
 		s->rep->prod->conn->xprt_ctx = s;
 		s->rep->prod->applet.st0 = s->rep->prod->applet.st1 = 0;
 		req->analysers = 0;
@@ -4056,16 +4056,16 @@
 	if (s->pend_pos)
 		pendconn_free(s->pend_pos);
 
-	if (target_srv(&s->target)) {
+	if (objt_server(s->target)) {
 		if (s->flags & SN_CURR_SESS) {
 			s->flags &= ~SN_CURR_SESS;
-			target_srv(&s->target)->cur_sess--;
+			objt_server(s->target)->cur_sess--;
 		}
-		if (may_dequeue_tasks(target_srv(&s->target), s->be))
-			process_srv_queue(target_srv(&s->target));
+		if (may_dequeue_tasks(objt_server(s->target), s->be))
+			process_srv_queue(objt_server(s->target));
 	}
 
-	clear_target(&s->target);
+	s->target = NULL;
 
 	s->req->cons->state     = s->req->cons->prev_state = SI_ST_INI;
 	s->req->cons->conn->t.sock.fd = -1; /* just to help with debugging */
@@ -4349,8 +4349,8 @@
 		else if (chn->flags & CF_SHUTW) {
 			txn->rsp.msg_state = HTTP_MSG_ERROR;
 			s->be->be_counters.cli_aborts++;
-			if (target_srv(&s->target))
-				target_srv(&s->target)->counters.cli_aborts++;
+			if (objt_server(s->target))
+				objt_server(s->target)->counters.cli_aborts++;
 			goto wait_other_side;
 		}
 	}
@@ -4628,8 +4628,8 @@
 
 		s->fe->fe_counters.cli_aborts++;
 		s->be->be_counters.cli_aborts++;
-		if (target_srv(&s->target))
-			target_srv(&s->target)->counters.cli_aborts++;
+		if (objt_server(s->target))
+			objt_server(s->target)->counters.cli_aborts++;
 
 		goto return_bad_req_stats_ok;
 	}
@@ -4698,8 +4698,8 @@
 
 	s->fe->fe_counters.srv_aborts++;
 	s->be->be_counters.srv_aborts++;
-	if (target_srv(&s->target))
-		target_srv(&s->target)->counters.srv_aborts++;
+	if (objt_server(s->target))
+		objt_server(s->target)->counters.srv_aborts++;
 
 	if (!(s->flags & SN_ERR_MASK))
 		s->flags |= SN_ERR_SRVCL;
@@ -4823,9 +4823,9 @@
 				http_capture_bad_message(&s->be->invalid_rep, s, msg, msg->msg_state, s->fe);
 
 			s->be->be_counters.failed_resp++;
-			if (target_srv(&s->target)) {
-				target_srv(&s->target)->counters.failed_resp++;
-				health_adjust(target_srv(&s->target), HANA_STATUS_HTTP_HDRRSP);
+			if (objt_server(s->target)) {
+				objt_server(s->target)->counters.failed_resp++;
+				health_adjust(objt_server(s->target), HANA_STATUS_HTTP_HDRRSP);
 			}
 		abort_response:
 			channel_auto_close(rep);
@@ -4856,9 +4856,9 @@
 				http_capture_bad_message(&s->be->invalid_rep, s, msg, msg->msg_state, s->fe);
 
 			s->be->be_counters.failed_resp++;
-			if (target_srv(&s->target)) {
-				target_srv(&s->target)->counters.failed_resp++;
-				health_adjust(target_srv(&s->target), HANA_STATUS_HTTP_READ_ERROR);
+			if (objt_server(s->target)) {
+				objt_server(s->target)->counters.failed_resp++;
+				health_adjust(objt_server(s->target), HANA_STATUS_HTTP_READ_ERROR);
 			}
 
 			channel_auto_close(rep);
@@ -4881,9 +4881,9 @@
 				http_capture_bad_message(&s->be->invalid_rep, s, msg, msg->msg_state, s->fe);
 
 			s->be->be_counters.failed_resp++;
-			if (target_srv(&s->target)) {
-				target_srv(&s->target)->counters.failed_resp++;
-				health_adjust(target_srv(&s->target), HANA_STATUS_HTTP_READ_TIMEOUT);
+			if (objt_server(s->target)) {
+				objt_server(s->target)->counters.failed_resp++;
+				health_adjust(objt_server(s->target), HANA_STATUS_HTTP_READ_TIMEOUT);
 			}
 
 			channel_auto_close(rep);
@@ -4906,9 +4906,9 @@
 				http_capture_bad_message(&s->be->invalid_rep, s, msg, msg->msg_state, s->fe);
 
 			s->be->be_counters.failed_resp++;
-			if (target_srv(&s->target)) {
-				target_srv(&s->target)->counters.failed_resp++;
-				health_adjust(target_srv(&s->target), HANA_STATUS_HTTP_BROKEN_PIPE);
+			if (objt_server(s->target)) {
+				objt_server(s->target)->counters.failed_resp++;
+				health_adjust(objt_server(s->target), HANA_STATUS_HTTP_BROKEN_PIPE);
 			}
 
 			channel_auto_close(rep);
@@ -4969,8 +4969,8 @@
 	if (n == 4)
 		session_inc_http_err_ctr(s);
 
-	if (target_srv(&s->target))
-		target_srv(&s->target)->counters.p.http.rsp[n]++;
+	if (objt_server(s->target))
+		objt_server(s->target)->counters.p.http.rsp[n]++;
 
 	/* check if the response is HTTP/1.1 or above */
 	if ((msg->sl.st.v_l == 8) &&
@@ -4990,11 +4990,11 @@
 	 * and 505 are triggered on demand by client request, so we must not
 	 * count them as server failures.
 	 */
-	if (target_srv(&s->target)) {
+	if (objt_server(s->target)) {
 		if (txn->status >= 100 && (txn->status < 500 || txn->status == 501 || txn->status == 505))
-			health_adjust(target_srv(&s->target), HANA_STATUS_HTTP_OK);
+			health_adjust(objt_server(s->target), HANA_STATUS_HTTP_OK);
 		else
-			health_adjust(target_srv(&s->target), HANA_STATUS_HTTP_STS);
+			health_adjust(objt_server(s->target), HANA_STATUS_HTTP_STS);
 	}
 
 	/*
@@ -5258,9 +5258,9 @@
 			if (rule_set->rsp_exp != NULL) {
 				if (apply_filters_to_response(t, rep, rule_set) < 0) {
 				return_bad_resp:
-					if (target_srv(&t->target)) {
-						target_srv(&t->target)->counters.failed_resp++;
-						health_adjust(target_srv(&t->target), HANA_STATUS_HTTP_RSP);
+					if (objt_server(t->target)) {
+						objt_server(t->target)->counters.failed_resp++;
+						health_adjust(objt_server(t->target), HANA_STATUS_HTTP_RSP);
 					}
 					t->be->be_counters.failed_resp++;
 				return_srv_prx_502:
@@ -5279,8 +5279,8 @@
 
 			/* has the response been denied ? */
 			if (txn->flags & TX_SVDENY) {
-				if (target_srv(&t->target))
-					target_srv(&t->target)->counters.failed_secu++;
+				if (objt_server(t->target))
+					objt_server(t->target)->counters.failed_secu++;
 
 				t->be->be_counters.denied_resp++;
 				t->fe->fe_counters.denied_resp++;
@@ -5348,7 +5348,7 @@
 		/*
 		 * 6: add server cookie in the response if needed
 		 */
-		if (target_srv(&t->target) && (t->be->ck_opts & PR_CK_INS) &&
+		if (objt_server(t->target) && (t->be->ck_opts & PR_CK_INS) &&
 		    !((txn->flags & TX_SCK_FOUND) && (t->be->ck_opts & PR_CK_PSV)) &&
 		    (!(t->flags & SN_DIRECT) ||
 		     ((t->be->cookie_maxidle || txn->cookie_last_date) &&
@@ -5363,13 +5363,13 @@
 			 * requests and this one isn't. Note that servers which don't have cookies
 			 * (eg: some backup servers) will return a full cookie removal request.
 			 */
-			if (!target_srv(&t->target)->cookie) {
+			if (!objt_server(t->target)->cookie) {
 				chunk_printf(&trash,
 					      "Set-Cookie: %s=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/",
 					      t->be->cookie_name);
 			}
 			else {
-				chunk_printf(&trash, "Set-Cookie: %s=%s", t->be->cookie_name, target_srv(&t->target)->cookie);
+				chunk_printf(&trash, "Set-Cookie: %s=%s", t->be->cookie_name, objt_server(t->target)->cookie);
 
 				if (t->be->cookie_maxidle || t->be->cookie_maxlife) {
 					/* emit last_date, which is mandatory */
@@ -5404,7 +5404,7 @@
 				goto return_bad_resp;
 
 			txn->flags &= ~TX_SCK_MASK;
-			if (target_srv(&t->target)->cookie && (t->flags & SN_DIRECT))
+			if (objt_server(t->target)->cookie && (t->flags & SN_DIRECT))
 				/* the server did not change, only the date was updated */
 				txn->flags |= TX_SCK_UPDATED;
 			else
@@ -5438,8 +5438,8 @@
 			 * a set-cookie header. We'll block it as requested by
 			 * the 'checkcache' option, and send an alert.
 			 */
-			if (target_srv(&t->target))
-				target_srv(&t->target)->counters.failed_secu++;
+			if (objt_server(t->target))
+				objt_server(t->target)->counters.failed_secu++;
 
 			t->be->be_counters.denied_resp++;
 			t->fe->fe_counters.denied_resp++;
@@ -5447,10 +5447,10 @@
 				t->listener->counters->denied_resp++;
 
 			Alert("Blocking cacheable cookie in response from instance %s, server %s.\n",
-			      t->be->id, target_srv(&t->target) ? target_srv(&t->target)->id : "<dispatch>");
+			      t->be->id, objt_server(t->target) ? objt_server(t->target)->id : "<dispatch>");
 			send_log(t->be, LOG_ALERT,
 				 "Blocking cacheable cookie in response from instance %s, server %s.\n",
-				 t->be->id, target_srv(&t->target) ? target_srv(&t->target)->id : "<dispatch>");
+				 t->be->id, objt_server(t->target) ? objt_server(t->target)->id : "<dispatch>");
 			goto return_srv_prx_502;
 		}
 
@@ -5712,8 +5712,8 @@
 		if (!(s->flags & SN_ERR_MASK))
 			s->flags |= SN_ERR_SRVCL;
 		s->be->be_counters.srv_aborts++;
-		if (target_srv(&s->target))
-			target_srv(&s->target)->counters.srv_aborts++;
+		if (objt_server(s->target))
+			objt_server(s->target)->counters.srv_aborts++;
 		goto return_bad_res_stats_ok;
 	}
 
@@ -5762,8 +5762,8 @@
 
  return_bad_res: /* let's centralize all bad responses */
 	s->be->be_counters.failed_resp++;
-	if (target_srv(&s->target))
-		target_srv(&s->target)->counters.failed_resp++;
+	if (objt_server(s->target))
+		objt_server(s->target)->counters.failed_resp++;
 
  return_bad_res_stats_ok:
 	txn->rsp.msg_state = HTTP_MSG_ERROR;
@@ -5771,8 +5771,8 @@
 	stream_int_retnclose(res->cons, NULL);
 	res->analysers = 0;
 	s->req->analysers = 0; /* we're in data phase, we want to abort both directions */
-	if (target_srv(&s->target))
-		health_adjust(target_srv(&s->target), HANA_STATUS_HTTP_HDRRSP);
+	if (objt_server(s->target))
+		health_adjust(objt_server(s->target), HANA_STATUS_HTTP_HDRRSP);
 
 	if (!(s->flags & SN_ERR_MASK))
 		s->flags |= SN_ERR_PRXCOND;
@@ -5789,8 +5789,8 @@
 
 	s->fe->fe_counters.cli_aborts++;
 	s->be->be_counters.cli_aborts++;
-	if (target_srv(&s->target))
-		target_srv(&s->target)->counters.cli_aborts++;
+	if (objt_server(s->target))
+		objt_server(s->target)->counters.cli_aborts++;
 
 	if (!(s->flags & SN_ERR_MASK))
 		s->flags |= SN_ERR_CLICL;
@@ -6166,7 +6166,7 @@
 						txn->flags &= ~TX_CK_MASK;
 						txn->flags |= (srv->state & SRV_RUNNING) ? TX_CK_VALID : TX_CK_DOWN;
 						t->flags |= SN_DIRECT | SN_ASSIGNED;
-						set_target_server(&t->target, srv);
+						t->target = &srv->obj_type;
 
 						break;
 					} else {
@@ -6576,7 +6576,7 @@
 							txn->flags &= ~TX_CK_MASK;
 							txn->flags |= (srv->state & SRV_RUNNING) ? TX_CK_VALID : TX_CK_DOWN;
 							t->flags |= SN_DIRECT | SN_ASSIGNED;
-							set_target_server(&t->target, srv);
+							t->target = &srv->obj_type;
 							break;
 						} else {
 							/* we found a server, but it's down,
@@ -7152,7 +7152,7 @@
 				}
 			}
 
-			srv = target_srv(&t->target);
+			srv = objt_server(t->target);
 			/* now check if we need to process it for persistence */
 			if (!(t->flags & SN_IGNORE_PRST) &&
 			    (att_end - att_beg == t->be->cookie_len) && (t->be->cookie_name != NULL) &&
@@ -7289,7 +7289,7 @@
 			memcpy(asession->sessid, txn->sessid, t->be->appsession_len);
 			asession->sessid[t->be->appsession_len] = 0;
 
-			server_id_len = strlen(target_srv(&t->target)->id) + 1;
+			server_id_len = strlen(objt_server(t->target)->id) + 1;
 			if ((asession->serverid = pool_alloc2(apools.serverid)) == NULL) {
 				Alert("Not enough Memory process_srv():asession->serverid:malloc().\n");
 				send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
@@ -7297,7 +7297,7 @@
 				return;
 			}
 			asession->serverid[0] = '\0';
-			memcpy(asession->serverid, target_srv(&t->target)->id, server_id_len);
+			memcpy(asession->serverid, objt_server(t->target)->id, server_id_len);
 
 			asession->request_count = 0;
 			appsession_hash_insert(&(t->be->htbl_proxy), asession);
@@ -7582,7 +7582,7 @@
 
 	es->when = date; // user-visible date
 	es->sid  = s->uniq_id;
-	es->srv  = target_srv(&s->target);
+	es->srv  = objt_server(s->target);
 	es->oe   = other_end;
 	es->src  = s->req->prod->conn->addr.from;
 	es->state = state;
@@ -7775,7 +7775,7 @@
 	s->be = s->fe;
 	s->logs.logwait = s->fe->to_log;
 	session_del_srv_conn(s);
-	clear_target(&s->target);
+	s->target = NULL;
 	/* re-init store persistence */
 	s->store_count = 0;
 
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 28df64b..e744c76 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -220,7 +220,7 @@
  * pointed to by conn->addr.from in case of transparent proxying. Normal source
  * bind addresses are still determined locally (due to the possible need of a
  * source port). conn->target may point either to a valid server or to a backend,
- * depending on conn->target.type. Only TARG_TYPE_PROXY and TARG_TYPE_SERVER are
+ * depending on conn->target. Only OBJ_TYPE_PROXY and OBJ_TYPE_SERVER are
  * supported. The <data> parameter is a boolean indicating whether there are data
  * waiting for being sent or not, in order to adjust data write polling and on
  * some platforms, the ability to avoid an empty initial ACK.
@@ -241,13 +241,13 @@
 	struct server *srv;
 	struct proxy *be;
 
-	switch (conn->target.type) {
-	case TARG_TYPE_PROXY:
-		be = conn->target.ptr.p;
+	switch (obj_type(conn->target)) {
+	case OBJ_TYPE_PROXY:
+		be = objt_proxy(conn->target);
 		srv = NULL;
 		break;
-	case TARG_TYPE_SERVER:
-		srv = conn->target.ptr.s;
+	case OBJ_TYPE_SERVER:
+		srv = objt_server(conn->target);
 		be = srv->proxy;
 		break;
 	default:
diff --git a/src/proxy.c b/src/proxy.c
index 2c710bb..914d979 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -26,6 +26,7 @@
 #include <common/time.h>
 
 #include <types/global.h>
+#include <types/obj_type.h>
 #include <types/peers.h>
 
 #include <proto/backend.h>
@@ -425,6 +426,7 @@
 void init_new_proxy(struct proxy *p)
 {
 	memset(p, 0, sizeof(struct proxy));
+	p->obj_type = OBJ_TYPE_PROXY;
 	LIST_INIT(&p->pendconns);
 	LIST_INIT(&p->acl);
 	LIST_INIT(&p->http_req_rules);
diff --git a/src/queue.c b/src/queue.c
index dd6e962..abc0f8c 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -122,7 +122,7 @@
 
 	/* we want to note that the session has now been assigned a server */
 	sess->flags |= SN_ASSIGNED;
-	set_target_server(&sess->target, srv);
+	sess->target = &srv->obj_type;
 	session_add_srv_conn(sess, srv);
 	srv->served++;
 	if (px->lbprm.server_take_conn)
@@ -148,7 +148,7 @@
 
 	sess->pend_pos = p;
 	p->sess = sess;
-	p->srv = srv = target_srv(&sess->target);
+	p->srv = srv = objt_server(sess->target);
 
 	if (sess->flags & SN_ASSIGNED && srv) {
 		LIST_ADDQ(&srv->pendconns, &p->list);
diff --git a/src/session.c b/src/session.c
index 3d28677..0b0a4ec 100644
--- a/src/session.c
+++ b/src/session.c
@@ -110,7 +110,7 @@
 	s->si[0].conn->ctrl = l->proto;
 	s->si[0].conn->flags = CO_FL_NONE;
 	s->si[0].conn->addr.from = *addr;
-	set_target_client(&s->si[0].conn->target, l);
+	s->si[0].conn->target = &l->obj_type;
 
 	s->logs.accept_date = date; /* user-visible date for logging */
 	s->logs.tv_accept = now;  /* corrected date for internal use */
@@ -415,7 +415,7 @@
 	s->si[1].err_loc   = NULL;
 	s->si[1].release   = NULL;
 	s->si[1].send_proxy_ofs = 0;
-	clear_target(&s->si[1].conn->target);
+	s->si[1].conn->target = NULL;
 	si_prepare_embedded(&s->si[1]);
 	s->si[1].exp       = TICK_ETERNITY;
 	s->si[1].flags     = SI_FL_NONE;
@@ -424,7 +424,7 @@
 		s->si[1].flags |= SI_FL_INDEP_STR;
 
 	session_init_srv_conn(s);
-	clear_target(&s->target);
+	s->target = NULL;
 	s->pend_pos = NULL;
 
 	/* init store persistence */
@@ -548,13 +548,13 @@
 	if (s->pend_pos)
 		pendconn_free(s->pend_pos);
 
-	if (target_srv(&s->target)) { /* there may be requests left pending in queue */
+	if (objt_server(s->target)) { /* there may be requests left pending in queue */
 		if (s->flags & SN_CURR_SESS) {
 			s->flags &= ~SN_CURR_SESS;
-			target_srv(&s->target)->cur_sess--;
+			objt_server(s->target)->cur_sess--;
 		}
-		if (may_dequeue_tasks(target_srv(&s->target), s->be))
-			process_srv_queue(target_srv(&s->target));
+		if (may_dequeue_tasks(objt_server(s->target), s->be))
+			process_srv_queue(objt_server(s->target));
 	}
 
 	if (unlikely(s->srv_conn)) {
@@ -653,8 +653,8 @@
 
 			s->be->be_counters.bytes_in			+= bytes;
 
-			if (target_srv(&s->target))
-				target_srv(&s->target)->counters.bytes_in		+= bytes;
+			if (objt_server(s->target))
+				objt_server(s->target)->counters.bytes_in		+= bytes;
 
 			if (s->listener->counters)
 				s->listener->counters->bytes_in		+= bytes;
@@ -703,8 +703,8 @@
 
 			s->be->be_counters.bytes_out			+= bytes;
 
-			if (target_srv(&s->target))
-				target_srv(&s->target)->counters.bytes_out		+= bytes;
+			if (objt_server(s->target))
+				objt_server(s->target)->counters.bytes_out		+= bytes;
 
 			if (s->listener->counters)
 				s->listener->counters->bytes_out	+= bytes;
@@ -773,7 +773,7 @@
 			si->state    = SI_ST_EST;
 			si->err_type = SI_ET_DATA_ERR;
 			si->ib->flags |= CF_READ_ERROR | CF_WRITE_ERROR;
-			si->err_loc = target_srv(&s->target);
+			si->err_loc = objt_server(s->target);
 			return 1;
 		}
 		si->exp   = TICK_ETERNITY;
@@ -787,7 +787,7 @@
 		if (si->err_type)
 			return 0;
 
-		si->err_loc = target_srv(&s->target);
+		si->err_loc = objt_server(s->target);
 		if (si->flags & SI_FL_ERR)
 			si->err_type = SI_ET_CONN_ERR;
 		else
@@ -803,7 +803,7 @@
 		/* give up */
 		si_shutw(si);
 		si->err_type |= SI_ET_CONN_ABRT;
-		si->err_loc  = target_srv(&s->target);
+		si->err_loc  = objt_server(s->target);
 		if (s->srv_error)
 			s->srv_error(s, si);
 		return 1;
@@ -836,12 +836,12 @@
 static int sess_update_st_cer(struct session *s, struct stream_interface *si)
 {
 	/* we probably have to release last session from the server */
-	if (target_srv(&s->target)) {
-		health_adjust(target_srv(&s->target), HANA_STATUS_L4_ERR);
+	if (objt_server(s->target)) {
+		health_adjust(objt_server(s->target), HANA_STATUS_L4_ERR);
 
 		if (s->flags & SN_CURR_SESS) {
 			s->flags &= ~SN_CURR_SESS;
-			target_srv(&s->target)->cur_sess--;
+			objt_server(s->target)->cur_sess--;
 		}
 	}
 
@@ -850,15 +850,15 @@
 	if (si->conn_retries < 0) {
 		if (!si->err_type) {
 			si->err_type = SI_ET_CONN_ERR;
-			si->err_loc = target_srv(&s->target);
+			si->err_loc = objt_server(s->target);
 		}
 
-		if (target_srv(&s->target))
-			target_srv(&s->target)->counters.failed_conns++;
+		if (objt_server(s->target))
+			objt_server(s->target)->counters.failed_conns++;
 		s->be->be_counters.failed_conns++;
 		sess_change_server(s, NULL);
-		if (may_dequeue_tasks(target_srv(&s->target), s->be))
-			process_srv_queue(target_srv(&s->target));
+		if (may_dequeue_tasks(objt_server(s->target), s->be))
+			process_srv_queue(objt_server(s->target));
 
 		/* shutw is enough so stop a connecting socket */
 		si_shutw(si);
@@ -877,17 +877,17 @@
 	 * bit to ignore any persistence cookie. We won't count a retry nor a
 	 * redispatch yet, because this will depend on what server is selected.
 	 */
-	if (target_srv(&s->target) && si->conn_retries == 0 &&
+	if (objt_server(s->target) && si->conn_retries == 0 &&
 	    s->be->options & PR_O_REDISP && !(s->flags & SN_FORCE_PRST)) {
 		sess_change_server(s, NULL);
-		if (may_dequeue_tasks(target_srv(&s->target), s->be))
-			process_srv_queue(target_srv(&s->target));
+		if (may_dequeue_tasks(objt_server(s->target), s->be))
+			process_srv_queue(objt_server(s->target));
 
 		s->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
 		si->state = SI_ST_REQ;
 	} else {
-		if (target_srv(&s->target))
-			target_srv(&s->target)->counters.retries++;
+		if (objt_server(s->target))
+			objt_server(s->target)->counters.retries++;
 		s->be->be_counters.retries++;
 		si->state = SI_ST_ASS;
 	}
@@ -919,8 +919,8 @@
 	struct channel *req = si->ob;
 	struct channel *rep = si->ib;
 
-	if (target_srv(&s->target))
-		health_adjust(target_srv(&s->target), HANA_STATUS_L4_OK);
+	if (objt_server(s->target))
+		health_adjust(objt_server(s->target), HANA_STATUS_L4_OK);
 
 	if (s->be->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */
 		/* if the user wants to log as soon as possible, without counting
@@ -955,7 +955,7 @@
  */
 static void sess_update_stream_int(struct session *s, struct stream_interface *si)
 {
-	struct server *srv = target_srv(&s->target);
+	struct server *srv = objt_server(s->target);
 
 	DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rqh=%d rqt=%d rph=%d rpt=%d cs=%d ss=%d\n",
 		now_ms, __FUNCTION__,
@@ -970,7 +970,7 @@
 		int conn_err;
 
 		conn_err = connect_server(s);
-		srv = target_srv(&s->target);
+		srv = objt_server(s->target);
 
 		if (conn_err == SN_ERR_NONE) {
 			/* state = SI_ST_CON now */
@@ -1314,7 +1314,7 @@
 				    (px->options & PR_O_PERSIST) ||
 				    (s->flags & SN_FORCE_PRST)) {
 					s->flags |= SN_DIRECT | SN_ASSIGNED;
-					set_target_server(&s->target, srv);
+					s->target = &srv->obj_type;
 					break;
 				}
 				/* if the server is not UP, let's go on with next rules
@@ -1392,7 +1392,7 @@
 							    (px->options & PR_O_PERSIST) ||
 							    (s->flags & SN_FORCE_PRST)) {
 								s->flags |= SN_DIRECT | SN_ASSIGNED;
-								set_target_server(&s->target, srv);
+								s->target = &srv->obj_type;
 							}
 						}
 					}
@@ -1488,7 +1488,7 @@
 		struct stksess *ts;
 		void *ptr;
 
-		if (target_srv(&s->target) && target_srv(&s->target)->state & SRV_NON_STICK) {
+		if (objt_server(s->target) && objt_server(s->target)->state & SRV_NON_STICK) {
 			stksess_free(s->store[i].table, s->store[i].ts);
 			s->store[i].ts = NULL;
 			continue;
@@ -1505,7 +1505,7 @@
 
 		s->store[i].ts = NULL;
 		ptr = stktable_data_ptr(s->store[i].table, ts, STKTABLE_DT_SERVER_ID);
-		stktable_data_cast(ptr, server_id) = target_srv(&s->target)->puid;
+		stktable_data_cast(ptr, server_id) = objt_server(s->target)->puid;
 	}
 	s->store_count = 0; /* everything is stored */
 
@@ -1621,7 +1621,7 @@
 	 * the client cannot have connect (hence retryable) errors. Also, the
 	 * connection setup code must be able to deal with any type of abort.
 	 */
-	srv = target_srv(&s->target);
+	srv = objt_server(s->target);
 	if (unlikely(s->si[0].flags & SI_FL_ERR)) {
 		if (s->si[0].state == SI_ST_EST || s->si[0].state == SI_ST_DIS) {
 			si_shutr(&s->si[0]);
@@ -1706,7 +1706,7 @@
 	 */
 	if (unlikely(s->req->cons->state == SI_ST_DIS)) {
 		s->req->cons->state = SI_ST_CLO;
-		srv = target_srv(&s->target);
+		srv = objt_server(s->target);
 		if (srv) {
 			if (s->flags & SN_CURR_SESS) {
 				s->flags &= ~SN_CURR_SESS;
@@ -1988,7 +1988,7 @@
 	 * we're just in a data phase here since it means we have not
 	 * seen any analyser who could set an error status.
 	 */
-	srv = target_srv(&s->target);
+	srv = objt_server(s->target);
 	if (unlikely(!(s->flags & SN_ERR_MASK))) {
 		if (s->req->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
 			/* Report it if the client got an error or a read timeout expired */
@@ -2148,7 +2148,7 @@
 				 */
 				s->req->cons->state = SI_ST_REQ; /* new connection requested */
 				s->req->cons->conn_retries = s->be->conn_retries;
-				if (unlikely(s->req->cons->conn->target.type == TARG_TYPE_APPLET &&
+				if (unlikely(obj_type(s->req->cons->conn->target) == OBJ_TYPE_APPLET &&
 					     !(si_ctrl(s->req->cons) && si_ctrl(s->req->cons)->connect))) {
 					s->req->cons->state = SI_ST_EST; /* connection established */
 					s->rep->flags |= CF_READ_ATTACHED; /* producer is now attached */
@@ -2177,7 +2177,7 @@
 			if (s->si[1].state == SI_ST_REQ)
 				sess_prepare_conn_req(s, &s->si[1]);
 
-			srv = target_srv(&s->target);
+			srv = objt_server(s->target);
 			if (s->si[1].state == SI_ST_ASS && srv && srv->rdr_len && (s->flags & SN_REDIRECTABLE))
 				perform_http_redirect(s, &s->si[1]);
 		} while (s->si[1].state == SI_ST_ASS);
@@ -2187,7 +2187,7 @@
 		if ((s->flags & SN_BE_ASSIGNED) &&
 		    (s->be->mode == PR_MODE_HTTP) &&
 		    (s->be->server_id_hdr_name != NULL)) {
-			http_send_name_header(&s->txn, s->be, target_srv(&s->target)->id);
+			http_send_name_header(&s->txn, s->be, objt_server(s->target)->id);
 		}
 	}
 
@@ -2327,10 +2327,10 @@
 		if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED))
 			session_process_counters(s);
 
-		if (s->rep->cons->state == SI_ST_EST && s->rep->cons->conn->target.type != TARG_TYPE_APPLET)
+		if (s->rep->cons->state == SI_ST_EST && obj_type(s->rep->cons->conn->target) != OBJ_TYPE_APPLET)
 			si_update(s->rep->cons);
 
-		if (s->req->cons->state == SI_ST_EST && s->req->cons->conn->target.type != TARG_TYPE_APPLET)
+		if (s->req->cons->state == SI_ST_EST && obj_type(s->req->cons->conn->target) != OBJ_TYPE_APPLET)
 			si_update(s->req->cons);
 
 		s->req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_WRITE_NULL|CF_WRITE_PARTIAL|CF_READ_ATTACHED);
@@ -2357,12 +2357,12 @@
 		/* Call the stream interfaces' I/O handlers when embedded.
 		 * Note that this one may wake the task up again.
 		 */
-		if (s->req->cons->conn->target.type == TARG_TYPE_APPLET ||
-		    s->rep->cons->conn->target.type == TARG_TYPE_APPLET) {
-			if (s->req->cons->conn->target.type == TARG_TYPE_APPLET)
-				s->req->cons->conn->target.ptr.a->fct(s->req->cons);
-			if (s->rep->cons->conn->target.type == TARG_TYPE_APPLET)
-				s->rep->cons->conn->target.ptr.a->fct(s->rep->cons);
+		if (obj_type(s->req->cons->conn->target) == OBJ_TYPE_APPLET ||
+		    obj_type(s->rep->cons->conn->target) == OBJ_TYPE_APPLET) {
+			if (objt_applet(s->req->cons->conn->target))
+				objt_applet(s->req->cons->conn->target)->fct(s->req->cons);
+			if (objt_applet(s->rep->cons->conn->target))
+				objt_applet(s->rep->cons->conn->target)->fct(s->rep->cons);
 			if (task_in_rq(t)) {
 				/* If we woke up, we don't want to requeue the
 				 * task to the wait queue, but rather requeue
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index bc4afc6..f19e0a7 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -125,7 +125,7 @@
 			conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
 		}
 
-		if (target_client(&conn->target)->bind_conf->ca_ignerr & (1ULL << err))
+		if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err))
 			return 1;
 
 		return 0;
@@ -135,7 +135,7 @@
 		conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
 
 	/* check if certificate error needs to be ignored */
-	if (target_client(&conn->target)->bind_conf->crt_ignerr & (1ULL << err))
+	if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err))
 		return 1;
 
 	return 0;
@@ -798,15 +798,15 @@
 
 	/* If it is in client mode initiate SSL session
 	   in connect state otherwise accept state */
-	if (target_srv(&conn->target)) {
+	if (objt_server(conn->target)) {
 		/* Alloc a new SSL session ctx */
-		conn->xprt_ctx = SSL_new(target_srv(&conn->target)->ssl_ctx.ctx);
+		conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
 		if (!conn->xprt_ctx)
 			return -1;
 
 		SSL_set_connect_state(conn->xprt_ctx);
-		if (target_srv(&conn->target)->ssl_ctx.reused_sess)
-			SSL_set_session(conn->xprt_ctx, target_srv(&conn->target)->ssl_ctx.reused_sess);
+		if (objt_server(conn->target)->ssl_ctx.reused_sess)
+			SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
 
 		/* set fd on SSL session context */
 		SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
@@ -817,9 +817,9 @@
 		sslconns++;
 		return 0;
 	}
-	else if (target_client(&conn->target)) {
+	else if (objt_listener(conn->target)) {
 		/* Alloc a new SSL session ctx */
-		conn->xprt_ctx = SSL_new(target_client(&conn->target)->bind_conf->default_ctx);
+		conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
 		if (!conn->xprt_ctx)
 			return -1;
 
@@ -893,13 +893,13 @@
 	}
 
 	/* Handshake succeeded */
-	if (target_srv(&conn->target)) {
+	if (objt_server(conn->target)) {
 		if (!SSL_session_reused(conn->xprt_ctx)) {
 			/* check if session was reused, if not store current session on server for reuse */
-			if (target_srv(&conn->target)->ssl_ctx.reused_sess)
-				SSL_SESSION_free(target_srv(&conn->target)->ssl_ctx.reused_sess);
+			if (objt_server(conn->target)->ssl_ctx.reused_sess)
+				SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
 
-			target_srv(&conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
+			objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
 		}
 	}
 
@@ -909,9 +909,9 @@
 
  out_error:
 	/* free resumed session if exists */
-	if (target_srv(&conn->target) && target_srv(&conn->target)->ssl_ctx.reused_sess) {
-		SSL_SESSION_free(target_srv(&conn->target)->ssl_ctx.reused_sess);
-		target_srv(&conn->target)->ssl_ctx.reused_sess = NULL;
+	if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
+		SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
+		objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
 	}
 
 	/* Fail on all other handshake errors */
diff --git a/src/stream_interface.c b/src/stream_interface.c
index bcedcb0..c847632 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -406,7 +406,7 @@
 	DPRINTF(stderr, "registering handler %p for si %p (was %p)\n", app, si, si->owner);
 
 	si_prepare_embedded(si);
-	set_target_applet(&si->conn->target, app);
+	si->conn->target = &app->obj_type;
 	si->release = app->release;
 	si->flags |= SI_FL_WAIT_DATA;
 	return si->owner;
@@ -419,7 +419,7 @@
 {
 	si->release = NULL;
 	si->owner = NULL;
-	clear_target(&si->conn->target);
+	si->conn->target = NULL;
 }
 
 /* This callback is used to send a valid PROXY protocol line to a socket being