From: <ja...@us...> - 2003-12-15 11:03:09
|
Update of /cvsroot/iptables-p2p/iptables-p2p/kernel In directory sc8-pr-cvs1:/tmp/cvs-serv32319/kernel Modified Files: match_http.c Log Message: match_http() now returns the protocol that matched; major efficiency improvements (untested) Index: match_http.c =================================================================== RCS file: /cvsroot/iptables-p2p/iptables-p2p/kernel/match_http.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- match_http.c 15 Dec 2003 09:41:06 -0000 1.5 +++ match_http.c 15 Dec 2003 11:03:01 -0000 1.6 @@ -24,48 +24,73 @@ #include <linux/file.h> #include <net/sock.h> +#include "ipt_p2p.h" + #define SIZE_MIN 30 #define SIZE_MAX 1000 -static const unsigned char *methods_list[] = { - "GET /get/", - "GET /uri-res/", - "GET /.hash=", - "GET /PoisonedDownloads/", - "GET /", - "HTTP/1.1", - NULL +/*****************************************************************************/ + +/* Ugly short-hand to avoid costly initialization */ +#define STRING_MATCH(strobj) (strobj), (sizeof (strobj) - 1) + +struct string_match +{ + const char *name; + size_t len; }; +static struct string_match methods[] = +{ #define MM_GET_GET 0 + { STRING_MATCH("GET /get/") }, + #define MM_GET_URIRES 1 + { STRING_MATCH("GET /uri-res/") }, + #define NM_GET_HASH 2 + { STRING_MATCH("GET /.hash=") }, + #define MM_GET_POISONED 3 + { STRING_MATCH("GET /PoisonedDownloads/") }, + #define MM_GET 4 + { STRING_MATCH("GET /") }, + #define MM_HTTP11 5 + { STRING_MATCH("HTTP/1.1") }, -static const unsigned char *headers_list[] = { - "X-Kazaa-", - "X-Gnutella-", - "X-OpenftAlias:", - "Content-URN:", - "X-Queue:", - "X-TigerTree", - NULL + { NULL, 0 } }; -#define HM_X_KAZZA 0 +#define METHODS_LEN (((sizeof(methods))/(sizeof(methods[0]))) - 1) + +struct string_match headers[] = +{ +#define HM_X_KAZAA 0 + { STRING_MATCH("X-Kazaa-") }, + #define HM_X_GNUTELLA 1 + { STRING_MATCH("X-Gnutella-") }, + #define HM_X_OPENFTALIAS 2 + { STRING_MATCH("X-OpenftAlias:") }, + #define HM_CONTENT_URN 3 + { STRING_MATCH("Content-URN:") }, + #define HM_X_QUEUE 4 + { STRING_MATCH("X-Queue:") }, + #define HM_X_TIGER_THREE 5 + { STRING_MATCH("X-TigerTree") }, -/* - * <liquidk> Not pretty: Is there a better way? - * <jasta> No. - */ -#define HEADERS_COUNT (sizeof(methods_list)/sizeof(methods_list[0])) + { NULL, 0 } +}; + +#define HEADERS_LEN (((sizeof(headers))/(sizeof(headers[0]))) - 1) + +/*****************************************************************************/ static inline const unsigned char * next_line(const unsigned char *data, @@ -81,25 +106,20 @@ } static inline int -string_match(const unsigned char *data, - const unsigned char *end, - const unsigned char **strings) +string_matchlist(const unsigned char *data, + const unsigned char *end, + const struct string_match *strings) { int i; - size_t stringlen; - for (i = 0; strings[i] != NULL; i++) + for (i = 0; strings[i].name != NULL; i++) { - /* TODO: We absolutely need to precalculate the size of the above - * strings and store them somewhere */ - stringlen = strlen (strings[i]); - /* avoid overflow */ - if (data + stringlen > end) + if (data + strings[i].len > end) continue; - if (memcmp(data, strings[i], stringlen) == 0) - return 1; + if (memcmp(data, strings[i].name, strings[i].len) == 0) + return i; } return -1; @@ -112,39 +132,45 @@ match_http(const unsigned char *data, const unsigned char *end) { - unsigned int method_matched; /* Methods matched */ - unsigned int headers_matched[HEADERS_COUNT]; /* Headers matched */ + unsigned int method_matched; /* Methods matched */ + unsigned int headers_matched[HEADERS_LEN]; /* Headers matched */ if (end - data < SIZE_MIN || end - data > SIZE_MAX) return 0; - /* <jasta> Why is this outside the loop below? */ - method_matched = string_match(data, end, methods_list); + /* Match method */ + method_matched = string_matchlist(data, end, methods); if (method_matched == -1) return 0; memset(headers_matched, 0, sizeof(headers_matched)); + /* Match in headers */ while ((data = next_line(data, end))) { int header; - header = string_match(data, end, headers_list); + header = string_matchlist(data, end, headers); if (header != -1) headers_matched[header] = 1; } /* Kazaa */ - if ((MM(NM_GET_HASH) || MM(MM_HTTP11)) && HM(HM_X_KAZZA)) - return 1; + if ((MM(NM_GET_HASH) || MM(MM_HTTP11)) && HM(HM_X_KAZAA)) + return IPT_P2P_PROTO_KAZAA; /* Gnutella */ if ((MM(MM_GET_GET) || MM(MM_GET_URIRES) || MM(MM_HTTP11)) && (HM(HM_X_GNUTELLA))) - return 1; + return IPT_P2P_PROTO_GNUTELLA; + /* + * These are not supported or undrestood by the common ipt_p2p.h, and + * so not used yet. + */ +#if 0 /* OpenFT */ if ((MM(MM_GET) || MM(MM_HTTP11)) && (HM(HM_X_OPENFTALIAS))) return 1; @@ -158,6 +184,7 @@ if (MM(MM_HTTP11) && HM(HM_X_TIGER_THREE)) return 1; +#endif return 0; } |