From: Thomas Holmes Date: Fri, 29 May 2015 11:54:25 +0000 (+0100) Subject: MEDIUM: sample: add trie support to 51Degrees X-Git-Tag: v1.6-dev2~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4d441a759cbad023eafc838e1e713321fa288df9;p=thirdparty%2Fhaproxy.git MEDIUM: sample: add trie support to 51Degrees Trie or pattern algorithm is used depending on what 51Degrees source files are provided to MAKE. --- diff --git a/include/types/global.h b/include/types/global.h index 2203a1f389..b3b96720c5 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -186,10 +186,13 @@ struct global { #endif #ifdef USE_51DEGREES - fiftyoneDegreesDataSet _51d_data_set; - char * _51d_data_file_path; /* the path of the data file. this is taken from 51degrees-data-file in config. */ char _51d_property_seperator; /* the seperator to use in the response for the values. this is taken from 51degrees-property-seperator from config. */ struct list _51d_property_names; /* list of properties to load into the data set. this is taken from 51degrees-property-name-list from config. */ + char * _51d_data_file_path; +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + fiftyoneDegreesDataSet _51d_data_set; /* data set used with the pattern detection method. */ +#endif + #endif }; diff --git a/src/cfgparse.c b/src/cfgparse.c index 44b1c2ca33..30d51c7823 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -1752,7 +1752,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) #ifdef USE_51DEGREES else if (strcmp(args[0], "51degrees-data-file") == 0) { if(!*(args[1])) { - Alert("parsing [%s:%d]: '%s' expects a filepath to a 51Degrees data file.\n", file, linenum, args[0]); + Alert("parsing [%s:%d]: '%s' expects a filepath to a 51Degrees trie or pattern data file.\n", file, linenum, args[0]); err_code |= ERR_ALERT | ERR_FATAL; goto out; } @@ -1760,12 +1760,12 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) } else if (strcmp(args[0], "51degrees-property-seperator") == 0) { if(!*(args[1])) { - Alert("parsing [%s:%d]: '%s' expects a ingle character.\n", file, linenum, args[0]); + Alert("parsing [%s:%d]: '%s' expects a single character.\n", file, linenum, args[0]); err_code |= ERR_ALERT | ERR_FATAL; goto out; } if (strlen(args[1]) > 1) { - Alert("parsing [%s:%d]: '%s' expects a ingle character, got '%s'.\n", file, linenum, args[0], args[1]); + Alert("parsing [%s:%d]: '%s' expects a single character, got '%s'.\n", file, linenum, args[0], args[1]); err_code |= ERR_ALERT | ERR_FATAL; goto out; } diff --git a/src/haproxy.c b/src/haproxy.c index daf68d0b65..e04aa3f6a9 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -548,8 +548,8 @@ void init(int argc, char **argv) #ifdef USE_51DEGREES int i = 0; struct _51d_property_names *name; - fiftyoneDegreesDataSetInitStatus _51d_dataset_status; char **_51d_property_list; + fiftyoneDegreesDataSetInitStatus _51d_dataset_status = DATA_SET_INIT_STATUS_NOT_SET; #endif chunk_init(&trash, malloc(global.tune.bufsize), global.tune.bufsize); @@ -1108,9 +1108,14 @@ void init(int argc, char **argv) list_for_each_entry(name, &global._51d_property_names, list) _51d_property_list[i++] = name->name; +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + _51d_dataset_status = fiftyoneDegreesInitWithPropertyArray(global._51d_data_file_path, _51d_property_list, i); +#endif +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED _51d_dataset_status = fiftyoneDegreesInitWithPropertyArray(global._51d_data_file_path, &global._51d_data_set, _51d_property_list, i); - free(_51d_property_list); +#endif chunk_reset(&trash); + switch (_51d_dataset_status) { case DATA_SET_INIT_STATUS_SUCCESS: break; @@ -1118,23 +1123,37 @@ void init(int argc, char **argv) chunk_printf(&trash, "Insufficient memory."); break; case DATA_SET_INIT_STATUS_CORRUPT_DATA: - chunk_printf(&trash, "Corrupt data."); +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + chunk_printf(&trash, "Corrupt data file. Check that the data file provided is uncompressed and Trie data format."); +#endif +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + chunk_printf(&trash, "Corrupt data file. Check that the data file provided is uncompressed and Pattern data format."); +#endif break; case DATA_SET_INIT_STATUS_INCORRECT_VERSION: - chunk_printf(&trash, "Incorrect version."); +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + chunk_printf(&trash, "Incorrect version. Check that the data file provided is uncompressed and Trie data format."); +#endif +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED + chunk_printf(&trash, "Incorrect version. Check that the data file provided is uncompressed and Pattern data format."); +#endif break; case DATA_SET_INIT_STATUS_FILE_NOT_FOUND: chunk_printf(&trash, "File not found."); break; + case DATA_SET_INIT_STATUS_NOT_SET: + chunk_printf(&trash, "Data set not initialised."); + break; } if (_51d_dataset_status != DATA_SET_INIT_STATUS_SUCCESS) { if (trash.len) - Alert("51D Setup - Error reading 51Degrees data file: %s\n", trash.str); + Alert("51Degrees Setup - Error reading 51Degrees data file. %s\n", trash.str); else - Alert("51D Setup - Error reading 51Degrees data file.\n"); + Alert("51Degrees Setup - Error reading 51Degrees data file.\n"); exit(1); } -#endif + free(_51d_property_list); +#endif // USE_51DEGREES } static void deinit_acl_cond(struct acl_cond *cond) @@ -1488,13 +1507,18 @@ void deinit(void) #endif #ifdef USE_51DEGREES +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED + fiftyoneDegreesDestroy(); +#endif +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED fiftyoneDegreesDestroy(&global._51d_data_set); +#endif free(global._51d_data_file_path); global._51d_data_file_path = NULL; list_for_each_entry_safe(_51d_prop_name, _51d_prop_nameb, &global._51d_property_names, list) { LIST_DEL(&_51d_prop_name->list); free(_51d_prop_name); } -#endif +#endif // USE_51DEGREES free(global.log_send_hostname); global.log_send_hostname = NULL; free(global.log_tag); global.log_tag = NULL; diff --git a/src/sample.c b/src/sample.c index 6418be83d9..1993255a46 100644 --- a/src/sample.c +++ b/src/sample.c @@ -2130,13 +2130,64 @@ static int sample_conv_arith_even(const struct arg *arg_p, } #ifdef USE_51DEGREES -static int fiftyone_degrees(const struct arg *args, - struct sample *smp, void *private) +#ifdef FIFTYONEDEGREES_H_TRIE_INCLUDED +static int +sample_fiftyone_degrees(const struct arg *args, struct sample *smp, void *private) +{ + int i; // used in loops. + int device_offset; + int property_index; + char no_data[] = "NoData"; // response when no data could be found. + struct chunk *tmp; + + // use a temporary trash buffer and copy data in it + smp->data.str.str[smp->data.str.len] = '\0'; + + // perform detection. + device_offset = fiftyoneDegreesGetDeviceOffset(smp->data.str.str); + + i = 0; + tmp = get_trash_chunk(); + chunk_reset(tmp); + + // loop through property names passed to the filter and fetch them from the dataset. + while (args[i].data.str.str) { + // try to find request property in dataset. + property_index = fiftyoneDegreesGetPropertyIndex(args[i].data.str.str); + if (property_index > 0) { + chunk_appendf(tmp, "%s", fiftyoneDegreesGetValue(device_offset, property_index)); + } + else { + chunk_appendf(tmp, "%s", no_data); + } + // add seperator + if (global._51d_property_seperator) + chunk_appendf(tmp, "%c", global._51d_property_seperator); + else + chunk_appendf(tmp, ","); + ++i; + } + + if (tmp->len) { + --tmp->len; + tmp->str[tmp->len] = '\0'; + } + + smp->data.str.str = tmp->str; + smp->data.str.len = strlen(smp->data.str.str); + + return 1; +} +#endif // FIFTYONEDEGREES_H_TRIE_INCLUDED + +#ifdef FIFTYONEDEGREES_H_PATTERN_INCLUDED +static int +sample_fiftyone_degrees(const struct arg *args, struct sample *smp, void *private) { int i, j, found; // used in loops. fiftyoneDegreesWorkset* ws; // workset for detection. char no_data[] = "NoData"; // response when no data could be found. - struct _51d_property_names *property; + const char* property_name; struct chunk *tmp; // use a temporary trash buffer and copy data in it @@ -2157,17 +2208,18 @@ static int fiftyone_degrees(const struct arg *args, while (args[i].data.str.str) { found = j = 0; // try to find request property in dataset. - list_for_each_entry(property, &global._51d_property_names, list) { - if (strcmp(property->name, args[i].data.str.str) == 0) { + for (j = 0; j < ws->dataSet->requiredPropertyCount; j++) { + property_name = fiftyoneDegreesGetPropertyName(ws->dataSet, ws->dataSet->requiredProperties[j]); + if (strcmp(property_name, args[i].data.str.str) == 0) { found = 1; fiftyoneDegreesSetValues(ws, j); chunk_appendf(tmp, "%s", fiftyoneDegreesGetValueName(ws->dataSet, *ws->values)); break; } - ++j; } - if (!found) + if (!found) { chunk_appendf(tmp, "%s", no_data); + } // add seperator if (global._51d_property_seperator) @@ -2189,7 +2241,8 @@ static int fiftyone_degrees(const struct arg *args, return 1; } -#endif +#endif // FIFTYONEDEGREES_H_PATTERN_INCLUDED +#endif // USE_51DEGREES /************************************************************************/ @@ -2346,7 +2399,7 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, { { "mod", sample_conv_arith_mod, ARG1(1,UINT), NULL, SMP_T_UINT, SMP_T_UINT }, { "neg", sample_conv_arith_neg, 0, NULL, SMP_T_UINT, SMP_T_UINT }, #ifdef USE_51DEGREES - { "51d", fiftyone_degrees, ARG5(1,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_T_STR }, + { "51d", sample_fiftyone_degrees,ARG5(1,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_T_STR }, #endif { NULL, NULL, 0, 0, 0 },