[CLEANUP] tcp: move some non tcp-specific layer6 processing out of proto_tcp

Some functions which act on generic buffer contents without being
tcp-specific were historically in proto_tcp.c. This concerns ACLs
and RDP cookies. Those have been moved away to more appropriate
locations. Ideally we should create some new files for each layer6
protocol parser. Let's do that later.
diff --git a/src/backend.c b/src/backend.c
index 6f1eefe..b51c276 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1,7 +1,7 @@
 /*
  * Backend variables and functions.
  *
- * Copyright 2000-2009 Willy Tarreau <w@1wt.eu>
+ * Copyright 2000-2010 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
@@ -35,7 +35,6 @@
 #include <proto/lb_fwrr.h>
 #include <proto/lb_map.h>
 #include <proto/proto_http.h>
-#include <proto/proto_tcp.h>
 #include <proto/queue.h>
 #include <proto/server.h>
 #include <proto/session.h>
@@ -1013,6 +1012,74 @@
 	return 0;
 }
 
+/* Apply RDP cookie persistence to the current session. For this, the function
+ * tries to extract an RDP cookie from the request buffer, and look for the
+ * matching server in the list. If the server is found, it is assigned to the
+ * session. This always returns 1, and the analyser removes itself from the
+ * list. Nothing is performed if a server was already assigned.
+ */
+int tcp_persist_rdp_cookie(struct session *s, struct buffer *req, int an_bit)
+{
+	struct proxy    *px   = s->be;
+	int              ret;
+	struct acl_expr  expr;
+	struct acl_test  test;
+	struct server *srv = px->srv;
+	struct sockaddr_in addr;
+	char *p;
+
+	DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
+		now_ms, __FUNCTION__,
+		s,
+		req,
+		req->rex, req->wex,
+		req->flags,
+		req->l,
+		req->analysers);
+
+	if (s->flags & SN_ASSIGNED)
+		goto no_cookie;
+
+	memset(&expr, 0, sizeof(expr));
+	memset(&test, 0, sizeof(test));
+
+	expr.arg.str = s->be->rdp_cookie_name;
+	expr.arg_len = s->be->rdp_cookie_len;
+
+	ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test);
+	if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || test.len == 0)
+		goto no_cookie;
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sin_family = AF_INET;
+
+	/* Considering an rdp cookie detected using acl, test.ptr ended with <cr><lf> and should return */
+	addr.sin_addr.s_addr = strtoul(test.ptr, &p, 10);
+	if (*p != '.')
+		goto no_cookie;
+	p++;
+	addr.sin_port = (unsigned short)strtoul(p, &p, 10);
+	if (*p != '.')
+		goto no_cookie;
+
+	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;
+				s->srv = srv;
+				break;
+			}
+		}
+		srv = srv->next;
+	}
+
+no_cookie:
+	req->analysers &= ~an_bit;
+	req->analyse_exp = TICK_ETERNITY;
+	return 1;
+}
+
 int be_downtime(struct proxy *px) {
 	if (px->lbprm.tot_weight && px->last_change < now.tv_sec)  // ignore negative time
 		return px->down_time;