]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] session: move counter ACL fetches from proto_tcp
authorWilly Tarreau <w@1wt.eu>
Fri, 18 Jun 2010 15:46:06 +0000 (17:46 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 10 Aug 2010 16:04:12 +0000 (18:04 +0200)
It was not normal to have counter fetches in proto_tcp.c. The only
reason was that the key based on the source address was fetched there,
but now we have split the key extraction and data processing, we must
move that to a more appropriate place. Session seems OK since the
counters are all manipulated from here.

Also, since we're precisely counting number of connections with these
ACLs, we rename them src_conn_cnt and src_updt_conn_cnt. This is not
a problem right now since no version was emitted with these keywords.

src/proto_tcp.c
src/session.c

index 7adb0f99905b88c217c8352a91a7bf94f534b895..20fcd6aa7c229972363c66895182c232f97e7f60 100644 (file)
@@ -1034,84 +1034,6 @@ pattern_fetch_dport(struct proxy *px, struct session *l4, void *l7, int dir,
        return 1;
 }
 
-/* set test->i to the number of connections from the session's source address
- * in the table pointed to by expr.
- */
-static int
-acl_fetch_src_count(struct proxy *px, struct session *l4, void *l7, int dir,
-                   struct acl_expr *expr, struct acl_test *test)
-{
-       struct stksess *ts;
-
-       /* right now we only support IPv4 */
-       if (l4->cli_addr.ss_family != AF_INET)
-               return 0;
-
-       if (expr->arg_len) {
-               /* another table was designated, we must look for it */
-               for (px = proxy; px; px = px->next)
-                       if (strcmp(px->id, expr->arg.str) == 0)
-                               break;
-       }
-       if (!px)
-               return 0; /* table not found */
-
-       static_table_key.key = (void *)&((struct sockaddr_in *)&l4->frt_addr)->sin_addr;
-       test->flags = ACL_TEST_F_VOL_TEST;
-       test->i = 0;
-       if ((ts = stktable_lookup_key(&px->table, &static_table_key)) != NULL) {
-               void *ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CUM);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               test->i = stktable_data_cast(ptr, conn_cum);
-       }
-
-       return 1;
-}
-
-/* set test->i to the number of connections from the session's source address
- * in the table pointed to by expr, after updating it.
- */
-static int
-acl_fetch_src_update_count(struct proxy *px, struct session *l4, void *l7, int dir,
-                          struct acl_expr *expr, struct acl_test *test)
-{
-       struct stksess *ts;
-       void *ptr;
-
-       /* right now we only support IPv4 */
-       if (l4->cli_addr.ss_family != AF_INET)
-               return 0;
-
-       if (expr->arg_len) {
-               /* another table was designated, we must look for it */
-               for (px = proxy; px; px = px->next)
-                       if (strcmp(px->id, expr->arg.str) == 0)
-                               break;
-       }
-       if (!px)
-               return 0;
-
-       static_table_key.key = (void *)&((struct sockaddr_in *)&l4->frt_addr)->sin_addr;
-       if ((ts = stktable_lookup_key(&px->table, &static_table_key)) == NULL) {
-               /* entry does not exist, initialize a new one */
-               ts = stksess_new(&px->table, &static_table_key);
-               if (!ts)
-                       return 0;
-               stktable_store(&px->table, ts);
-       }
-       else
-               stktable_touch(&px->table, ts);
-
-       ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CUM);
-       if (!ptr)
-               return 0; /* parameter not stored in this table */
-
-       test->i = ++stktable_data_cast(ptr, conn_cum);
-       test->flags = ACL_TEST_F_VOL_TEST;
-       return 1;
-}
-
 static struct cfg_kw_list cfg_kws = {{ },{
        { CFG_LISTEN, "tcp-request", tcp_parse_tcp_req },
        { 0, NULL, NULL },
@@ -1123,8 +1045,6 @@ static struct acl_kw_list acl_kws = {{ },{
        { "src",        acl_parse_ip,    acl_fetch_src,      acl_match_ip,  ACL_USE_TCP4_PERMANENT|ACL_MAY_LOOKUP },
        { "dst",        acl_parse_ip,    acl_fetch_dst,      acl_match_ip,  ACL_USE_TCP4_PERMANENT|ACL_MAY_LOOKUP },
        { "dst_port",   acl_parse_int,   acl_fetch_dport,    acl_match_int, ACL_USE_TCP_PERMANENT  },
-       { "src_count",  acl_parse_int,   acl_fetch_src_count,acl_match_int, ACL_USE_TCP4_VOLATILE },
-       { "src_update_count",  acl_parse_int,   acl_fetch_src_update_count, acl_match_int, ACL_USE_TCP4_VOLATILE },
        { NULL, NULL, NULL, NULL },
 }};
 
index 4e2bedd6525789a3b6273ee07ff547cdcd989ddc..9d583b5f05f101f70db88648b0905f9bc43e08af 100644 (file)
@@ -2051,6 +2051,91 @@ void default_srv_error(struct session *s, struct stream_interface *si)
 }
 
 
+/************************************************************************/
+/*           All supported ACL keywords must be declared here.          */
+/************************************************************************/
+
+/* set test->i to the number of connections from the session's source address
+ * in the table pointed to by expr.
+ */
+static int
+acl_fetch_src_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
+                      struct acl_expr *expr, struct acl_test *test)
+{
+       struct stksess *ts;
+       struct stktable_key *key;
+
+       key = tcpv4_src_to_stktable_key(l4);
+       if (!key)
+               return 0; /* only TCPv4 is supported right now */
+
+       if (expr->arg_len)
+               px = find_stktable(expr->arg.str);
+
+       if (!px)
+               return 0; /* table not found */
+
+       test->flags = ACL_TEST_F_VOL_TEST;
+       test->i = 0;
+       if ((ts = stktable_lookup_key(&px->table, key)) != NULL) {
+               void *ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CNT);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               test->i = stktable_data_cast(ptr, conn_cnt);
+       }
+
+       return 1;
+}
+
+/* set test->i to the number of connections from the session's source address
+ * in the table pointed to by expr, after updating it.
+ */
+static int
+acl_fetch_src_updt_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
+                           struct acl_expr *expr, struct acl_test *test)
+{
+       struct stksess *ts;
+       struct stktable_key *key;
+       void *ptr;
+
+       key = tcpv4_src_to_stktable_key(l4);
+       if (!key)
+               return 0; /* only TCPv4 is supported right now */
+
+       if (expr->arg_len)
+               px = find_stktable(expr->arg.str);
+
+       if (!px)
+               return 0; /* table not found */
+
+       if ((ts = stktable_lookup_key(&px->table, key)) == NULL) {
+               /* entry does not exist, initialize a new one */
+               ts = stksess_new(&px->table, key);
+               if (!ts)
+                       return 0;
+               stktable_store(&px->table, ts);
+       }
+       else
+               stktable_touch(&px->table, ts);
+
+       ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CNT);
+       if (!ptr)
+               return 0; /* parameter not stored in this table */
+
+       test->i = ++stktable_data_cast(ptr, conn_cnt);
+       test->flags = ACL_TEST_F_VOL_TEST;
+       return 1;
+}
+
+
+/* Note: must not be declared <const> as its list will be overwritten */
+static struct acl_kw_list acl_kws = {{ },{
+       { "src_conn_cnt",       acl_parse_int,   acl_fetch_src_conn_cnt,      acl_match_int, ACL_USE_TCP4_VOLATILE },
+       { "src_updt_conn_cnt",  acl_parse_int,   acl_fetch_src_updt_conn_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE },
+       { NULL, NULL, NULL, NULL },
+}};
+
+
 /* Parse a "track-counters" line starting with "track-counters" in args[arg-1].
  * Returns the number of warnings emitted, or -1 in case of fatal errors. The
  * <prm> struct is fed with the table name if any. If unspecified, the caller
@@ -2100,6 +2185,12 @@ int parse_track_counters(char **args, int *arg,
        return 0;
 }
 
+__attribute__((constructor))
+static void __session_init(void)
+{
+       acl_register_keywords(&acl_kws);
+}
+
 /*
  * Local variables:
  *  c-indent-level: 8