REORG: connection: centralize the conn_set_{tos,mark,quickack} functions

There were a number of ugly setsockopt() calls spread all over
proto_http.c, proto_htx.c and hlua.c just to manipulate the front
connection's TOS, mark or TCP quick-ack. These ones entirely relied
on the connection, its existence, its control layer's presence, and
its addresses. Worse, inet_set_tos() was placed in proto_http.c,
exported and used from the two other ones, surrounded in #ifdefs.

This patch moves this code to connection.h and makes the other ones
rely on it without ifdefs.
diff --git a/include/proto/connection.h b/include/proto/connection.h
index e2fae5f..f84b75a 100644
--- a/include/proto/connection.h
+++ b/include/proto/connection.h
@@ -738,6 +738,56 @@
 	conn->flags |= CO_FL_ADDR_TO_SET;
 }
 
+/* Sets the TOS header in IPv4 and the traffic class header in IPv6 packets
+ * (as per RFC3260 #4 and BCP37 #4.2 and #5.2). The connection is tested and if
+ * it is null, nothing is done.
+ */
+static inline void conn_set_tos(const struct connection *conn, int tos)
+{
+	if (!conn || !conn_ctrl_ready(conn))
+		return;
+
+#ifdef IP_TOS
+	if (conn->addr.from.ss_family == AF_INET)
+		setsockopt(conn->handle.fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
+#endif
+#ifdef IPV6_TCLASS
+	if (conn->addr.from.ss_family == AF_INET6) {
+		if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&conn->addr.from)->sin6_addr))
+			/* v4-mapped addresses need IP_TOS */
+			setsockopt(conn->handle.fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
+		else
+			setsockopt(conn->handle.fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos));
+	}
+#endif
+}
+
+/* Sets the netfilter mark on the connection's socket. The connection is tested
+ * and if it is null, nothing is done.
+ */
+static inline void conn_set_mark(const struct connection *conn, int mark)
+{
+	if (!conn || !conn_ctrl_ready(conn))
+		return;
+
+#ifdef SO_MARK
+	setsockopt(conn->handle.fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
+#endif
+}
+
+/* Sets adjust the TCP quick-ack feature on the connection's socket. The
+ * connection is tested and if it is null, nothing is done.
+ */
+static inline void conn_set_quickack(const struct connection *conn, int value)
+{
+	if (!conn || !conn_ctrl_ready(conn))
+		return;
+
+#ifdef TCP_QUICKACK
+	setsockopt(conn->handle.fd, IPPROTO_TCP, TCP_QUICKACK, &value, sizeof(value));
+#endif
+}
+
 /* Attaches a conn_stream to a data layer and sets the relevant callbacks */
 static inline void cs_attach(struct conn_stream *cs, void *data, const struct data_cb *data_cb)
 {
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index 7394619..3e7701c 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -105,7 +105,6 @@
 int http_transform_header_str(struct stream* s, struct http_msg *msg, const char* name,
                               unsigned int name_len, const char *str, struct my_regex *re,
                               int action);
-void inet_set_tos(int fd, const struct sockaddr_storage *from, int tos);
 int http_handle_stats(struct stream *s, struct channel *req);
 enum rule_result http_req_get_intercept_rule(struct proxy *px, struct list *rules,
 					     struct stream *s, int *deny_status);
diff --git a/src/hlua.c b/src/hlua.c
index 189bf47..5dd88f2 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -5373,33 +5373,26 @@
 __LJMP static int hlua_txn_set_tos(lua_State *L)
 {
 	struct hlua_txn *htxn;
-	struct connection *cli_conn;
 	int tos;
 
 	MAY_LJMP(check_args(L, 2, "set_tos"));
 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
 	tos = MAY_LJMP(luaL_checkinteger(L, 2));
 
-	if ((cli_conn = objt_conn(htxn->s->sess->origin)) && conn_ctrl_ready(cli_conn))
-		inet_set_tos(cli_conn->handle.fd, &cli_conn->addr.from, tos);
-
+	conn_set_tos(objt_conn(htxn->s->sess->origin), tos);
 	return 0;
 }
 
 __LJMP static int hlua_txn_set_mark(lua_State *L)
 {
-#ifdef SO_MARK
 	struct hlua_txn *htxn;
-	struct connection *cli_conn;
 	int mark;
 
 	MAY_LJMP(check_args(L, 2, "set_mark"));
 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
 	mark = MAY_LJMP(luaL_checkinteger(L, 2));
 
-	if ((cli_conn = objt_conn(htxn->s->sess->origin)) && conn_ctrl_ready(cli_conn))
-		setsockopt(cli_conn->handle.fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
-#endif
+	conn_set_tos(objt_conn(htxn->s->sess->origin), mark);
 	return 0;
 }
 
diff --git a/src/proto_http.c b/src/proto_http.c
index e2f3009..6c7cfcb 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -23,8 +23,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include <netinet/tcp.h>
-
 #include <common/base64.h>
 #include <common/cfgparse.h>
 #include <common/chunk.h>
@@ -1088,16 +1086,14 @@
 		channel_dont_connect(req);
 		req->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
 		s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
-#ifdef TCP_QUICKACK
-		if (sess->listener->options & LI_O_NOQUICKACK && ci_data(req) &&
-		    objt_conn(sess->origin) && conn_ctrl_ready(__objt_conn(sess->origin))) {
+
+		if (sess->listener->options & LI_O_NOQUICKACK && ci_data(req)) {
 			/* We need more data, we have to re-enable quick-ack in case we
 			 * previously disabled it, otherwise we might cause the client
 			 * to delay next data.
 			 */
-			setsockopt(__objt_conn(sess->origin)->handle.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
+			conn_set_quickack(objt_conn(sess->origin), 1);
 		}
-#endif
 
 		if ((msg->msg_state != HTTP_MSG_RQBEFORE) && (txn->flags & TX_WAIT_NEXT_RQ)) {
 			/* If the client starts to talk, let's fall back to
@@ -1638,26 +1634,6 @@
 	return 1;
 }
 
-/* Sets the TOS header in IPv4 and the traffic class header in IPv6 packets
- * (as per RFC3260 #4 and BCP37 #4.2 and #5.2).
- */
-void inet_set_tos(int fd, const struct sockaddr_storage *from, int tos)
-{
-#ifdef IP_TOS
-	if (from->ss_family == AF_INET)
-		setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
-#endif
-#ifdef IPV6_TCLASS
-	if (from->ss_family == AF_INET6) {
-		if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)from)->sin6_addr))
-			/* v4-mapped addresses need IP_TOS */
-			setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
-		else
-			setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos));
-	}
-#endif
-}
-
 int http_transform_header_str(struct stream* s, struct http_msg *msg,
                               const char* name, unsigned int name_len,
                               const char *str, struct my_regex *re,
@@ -1802,7 +1778,6 @@
 {
 	struct session *sess = strm_sess(s);
 	struct http_txn *txn = s->txn;
-	struct connection *cli_conn;
 	struct act_rule *rule;
 	struct hdr_ctx ctx;
 	const char *auth_realm;
@@ -1903,15 +1878,11 @@
 			break;
 
 		case ACT_HTTP_SET_TOS:
-			if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
-				inet_set_tos(cli_conn->handle.fd, &cli_conn->addr.from, rule->arg.tos);
+			conn_set_tos(objt_conn(sess->origin), rule->arg.tos);
 			break;
 
 		case ACT_HTTP_SET_MARK:
-#ifdef SO_MARK
-			if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
-				setsockopt(cli_conn->handle.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
-#endif
+			conn_set_mark(objt_conn(sess->origin), rule->arg.mark);
 			break;
 
 		case ACT_HTTP_SET_LOGL:
@@ -2213,7 +2184,6 @@
 {
 	struct session *sess = strm_sess(s);
 	struct http_txn *txn = s->txn;
-	struct connection *cli_conn;
 	struct act_rule *rule;
 	struct hdr_ctx ctx;
 	enum rule_result rule_ret = HTTP_RULE_RES_CONT;
@@ -2265,15 +2235,11 @@
 			break;
 
 		case ACT_HTTP_SET_TOS:
-			if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
-				inet_set_tos(cli_conn->handle.fd, &cli_conn->addr.from, rule->arg.tos);
+			conn_set_tos(objt_conn(sess->origin), rule->arg.tos);
 			break;
 
 		case ACT_HTTP_SET_MARK:
-#ifdef SO_MARK
-			if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
-				setsockopt(cli_conn->handle.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
-#endif
+			conn_set_mark(objt_conn(sess->origin), rule->arg.mark);
 			break;
 
 		case ACT_HTTP_SET_LOGL:
@@ -3414,18 +3380,16 @@
 
 	req->analysers &= ~AN_REQ_FLT_XFER_DATA;
 	req->analysers |= AN_REQ_HTTP_XFER_BODY;
-#ifdef TCP_QUICKACK
+
 	/* We expect some data from the client. Unless we know for sure
 	 * we already have a full request, we have to re-enable quick-ack
 	 * in case we previously disabled it, otherwise we might cause
 	 * the client to delay further data.
 	 */
 	if ((sess->listener->options & LI_O_NOQUICKACK) &&
-	    cli_conn && conn_ctrl_ready(cli_conn) &&
 	    ((msg->flags & HTTP_MSGF_TE_CHNK) ||
 	     (msg->body_len > ci_data(req) - txn->req.eoh - 2)))
-		setsockopt(cli_conn->handle.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
-#endif
+		conn_set_quickack(cli_conn, 1);
 
 	/*************************************************************
 	 * OK, that's finished for the headers. We have done what we *
diff --git a/src/proto_htx.c b/src/proto_htx.c
index c22908a..9088ecb 100644
--- a/src/proto_htx.c
+++ b/src/proto_htx.c
@@ -225,16 +225,16 @@
 		channel_dont_connect(req);
 		req->flags |= CF_READ_DONTWAIT; /* try to get back here ASAP */
 		s->res.flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
-#ifdef TCP_QUICKACK
+
 		if (sess->listener->options & LI_O_NOQUICKACK && htx_is_not_empty(htx) &&
 		    objt_conn(sess->origin) && conn_ctrl_ready(__objt_conn(sess->origin))) {
 			/* We need more data, we have to re-enable quick-ack in case we
 			 * previously disabled it, otherwise we might cause the client
 			 * to delay next data.
 			 */
-			setsockopt(__objt_conn(sess->origin)->handle.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
+			conn_set_quickack(objt_conn(sess->origin), 1);
 		}
-#endif
+
 		if ((req->flags & CF_READ_PARTIAL) && (txn->flags & TX_WAIT_NEXT_RQ)) {
 			/* If the client starts to talk, let's fall back to
 			 * request timeout processing.
@@ -951,17 +951,15 @@
 
 	req->analysers &= ~AN_REQ_FLT_XFER_DATA;
 	req->analysers |= AN_REQ_HTTP_XFER_BODY;
-#ifdef TCP_QUICKACK
+
 	/* We expect some data from the client. Unless we know for sure
 	 * we already have a full request, we have to re-enable quick-ack
 	 * in case we previously disabled it, otherwise we might cause
 	 * the client to delay further data.
 	 */
 	if ((sess->listener->options & LI_O_NOQUICKACK) &&
-	    cli_conn && conn_ctrl_ready(cli_conn) &&
 	    (htx_get_tail_type(htx) != HTX_BLK_EOM))
-		setsockopt(cli_conn->handle.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
-#endif
+		conn_set_quickack(cli_conn, 1);
 
 	/*************************************************************
 	 * OK, that's finished for the headers. We have done what we *
@@ -2754,7 +2752,6 @@
 	struct session *sess = strm_sess(s);
 	struct http_txn *txn = s->txn;
 	struct htx *htx;
-	struct connection *cli_conn;
 	struct act_rule *rule;
 	struct http_hdr_ctx ctx;
 	const char *auth_realm;
@@ -2850,15 +2847,11 @@
 				break;
 
 			case ACT_HTTP_SET_TOS:
-				if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
-					inet_set_tos(cli_conn->handle.fd, &cli_conn->addr.from, rule->arg.tos);
+				conn_set_tos(objt_conn(sess->origin), rule->arg.tos);
 				break;
 
 			case ACT_HTTP_SET_MARK:
-#ifdef SO_MARK
-				if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
-					setsockopt(cli_conn->handle.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
-#endif
+				conn_set_mark(objt_conn(sess->origin), rule->arg.mark);
 				break;
 
 			case ACT_HTTP_SET_LOGL:
@@ -3144,7 +3137,6 @@
 	struct session *sess = strm_sess(s);
 	struct http_txn *txn = s->txn;
 	struct htx *htx;
-	struct connection *cli_conn;
 	struct act_rule *rule;
 	struct http_hdr_ctx ctx;
 	enum rule_result rule_ret = HTTP_RULE_RES_CONT;
@@ -3197,15 +3189,11 @@
 				break;
 
 			case ACT_HTTP_SET_TOS:
-				if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
-					inet_set_tos(cli_conn->handle.fd, &cli_conn->addr.from, rule->arg.tos);
+				conn_set_tos(objt_conn(sess->origin), rule->arg.tos);
 				break;
 
 			case ACT_HTTP_SET_MARK:
-#ifdef SO_MARK
-				if ((cli_conn = objt_conn(sess->origin)) && conn_ctrl_ready(cli_conn))
-					setsockopt(cli_conn->handle.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
-#endif
+				conn_set_mark(objt_conn(sess->origin), rule->arg.mark);
 				break;
 
 			case ACT_HTTP_SET_LOGL: