Changes of Revision 15
[-] | Changed | haproxy.spec |
x 1
2 %define haproxy_home %{_localstatedir}/lib/haproxy 3 %define haproxy_confdir %{_sysconfdir}/haproxy 4 %define haproxy_datadir %{_datadir}/haproxy 5 -%define devtag dev24 6 +%define devtag dev26 7 8 Name: haproxy 9 Version: 1.5 10
11 License: GPLv2+ 12 13 URL: http://haproxy.1wt.eu/ 14 -Source0: http://haproxy.1wt.eu/download/1.4/src/haproxy-%{version}.tar.gz 15 +Source0: http://haproxy.1wt.eu/download/1.5/src/haproxy-%{version}-%{devtag}.tar.gz 16 Source1: %{name}.init 17 Source2: %{name}.cfg 18 Source3: %{name}.logrotate 19 +Source4: benchmark.cfg 20 +Source5: haproxy-geoip 21 + 22 +Patch1: 0001-Add-ability-to-externalize-health-check.patch 23 +Patch2: 0001-enhance-hash-type-directive-with-algorithm-options.patch 24 +Patch3: 0002-implement-avalanche-as-modifier.patch 25 +Patch4: haproxy-1.5-geolocation.patch 26 + 27 28 BuildRequires: pcre-devel, openssl-devel 29 30
31 32 %prep 33 %setup -n %{name}-%{version} 34 - 35 +%patch1 -p1 36 +%patch2 -p1 37 +%patch3 -p1 38 +%patch4 -p1 39 40 %build 41 # No configure script is present, it is all done via make flags 42
43 %doc examples/cttproxy-src.cfg 44 %doc examples/haproxy.cfg 45 %doc examples/tarpit.cfg 46 +%doc examples/benchmark.cfg 47 %doc CHANGELOG LICENSE README 48 %dir %{haproxy_datadir} 49 %{haproxy_datadir}/* 50
51 %config(noreplace) %{_sysconfdir}/logrotate.d/%{name} 52 %{_initrddir}/%{name} 53 %{_sbindir}/%{name} 54 +%{_sbindir}/haproxy-geoip 55 %{_sbindir}/haproxy-systemd-wrapper 56 %{_bindir}/halog 57 %{_mandir}/man1/%{name}.1.gz 58
59 60 61 %changelog 62 +* Fr May 06 2014 Juergen Gotteswinter <jg@internetx.com> 1.5-dev26 63 +- bumped to latest dev release 64 +- added geoip support 65 +- patched in additional hashing algorithms 66 + 67 * Sat Apr 26 2014 Juergen Gotteswinter <jg@internetx.com> 1.5-dev24 68 - pushed forward to latest dev build 69 - added some config samples and other probably useful thinsg 70 |
||
[+] | Added | 0001-Add-ability-to-externalize-health-check.patch ^ |
@@ -0,0 +1,609 @@ +From 1be0b98fcf9180091170d8d3bb108936cf2dc9db Mon Sep 17 00:00:00 2001 +From: Bhaskar Maddala <maddalab@gmail.com> +Date: Fri, 7 Feb 2014 13:55:35 -0500 +Subject: [PATCH] Add ability to externalize health check + +Summary: +We add new directives to the http-check keyword + +The server option is used to specify an external +health checking server to use for health checks. + +Example: + http-check server <ipv4|ipv6> + +The info option is used to specify a http +header to communicate information about the server +being checked to the external health checking server + +Example: + http-check info [header <http-header>] + +The default value of the header is 'X-Check-Info' + +This option is independent of the server directive. When +used includes a http header in the health check request +of the form + +<http-header>: <value> + +Finally, we add to the server directive a 'info' +option. This value assigned to this option is passed +to the external health checking server. + +Example: + server id <addr> [info <value>] + +Putting it all togeather + +backend bck1 + mode http + + # the host header works but wasn't the intent + option httpchk GET /health HTTP/1.1\r\nHost:\ www.hst1.com + + # specify a server to use for the check + http-check server chksrv1.dc.hst1.com + + # request for info about the server using the default host header + # the following 2 lines are equivalent + # http-check info + http-check info X-Check-Info + + # pass in the info using the default + # the following 2 lines are equivalent + # server a1 a1.dc.hst1.com:80 weight 20 maxconn 5 check inter 2s + server a1 a1.dc.hst1.com:80 weight 20 maxconn 5 check inter 2s info a1 + + # this is probably a better alternative + server a1 a1.dc.hst1.com:80 weight 20 maxconn 5 check inter 2s info a1.dc.hst1.com +--- + doc/configuration.txt | 41 +++++++++++++++-- + include/common/defaults.h | 1 + + include/types/proxy.h | 8 +++- + include/types/server.h | 3 ++ + src/cfgparse.c | 114 ++++++++++++++++++++++++++++++++++++++-------- + src/checks.c | 112 ++++++++++++++++++++++++++------------------- + 6 files changed, 209 insertions(+), 70 deletions(-) + +diff --git a/doc/configuration.txt b/doc/configuration.txt +index 6d4df7d..2a69b2a 100644 +--- a/doc/configuration.txt ++++ b/doc/configuration.txt +@@ -1215,6 +1215,8 @@ force-persist - X X X + fullconn X - X X + grace X X X X + hash-type X - X X ++http-check server X - X X ++http-check info X - X X + http-check disable-on-404 X - X X + http-check expect - - X X + http-check send-state X - X X +@@ -2681,9 +2683,35 @@ http-check disable-on-404 + is used with "http-check expect", then it has precedence over it so that 404 + responses will still be considered as soft-stop. + +- See also : "option httpchk", "http-check expect" ++ See also : "option httpchk", "http-check expect", "http-check server", ++ "http-check info" + ++http-check server <ipv4|ipv6> ++ Using the "server" parameter, it becomes possible to use a different IP address ++ to send health-checks. On some servers, it may be desirable to dedicate an IP ++ address to specific component able to perform complex tests which are more ++ suitable to health-checks than the application. ++ ++ May be used in sections : defaults | frontend | listen | backend ++ yes | no | yes | yes ++ Arguments : server ++ ++ See also : "option httpchk", "http-check expect", "http-check server", ++ "http-check info" ++ ++http-check info <header> ++ Using the "info" parameter, it becomes possible to send custom information ++ for use during health checks. The information is sent when using http checks ++ using the specified http header ++ ++ May be used in sections : defaults | frontend | listen | backend ++ yes | no | yes | yes ++ Arguments : header ++ ++ See also : "option httpchk", "http-check expect", "http-check server", ++ "http-check info" + ++ + http-check expect [!] <match> <pattern> + Make HTTP health checks consider response contents or specific status codes + May be used in sections : defaults | frontend | listen | backend +@@ -4185,8 +4213,8 @@ option httpchk <method> <uri> <version> + server apache1 192.168.1.1:443 check port 80 + + See also : "option ssl-hello-chk", "option smtpchk", "option mysql-check", +- "option pgsql-check", "http-check" and the "check", "port" and +- "inter" server options. ++ "option pgsql-check", "http-check" and the "check", "port", ++ "inter", "server" and "info" server options. + + + option httpclose +@@ -8159,6 +8187,13 @@ addr <ipv4|ipv6> + the "check" parameter is not set. See also the "port" parameter. + + Supported in default-server: No ++ ++info <information> ++ Using the "info" parameter, it becomes possible to send information useful for ++ health-checks. On some servers, it may be desirable to include additional ++ server information to perform complex tests which are more suitable to ++ health-checks than the application. This parameter is ignored if the "check" ++ parameter is not set. + + agent-check + Enable an auxiliary agent check which is run independently of a regular +diff --git a/include/common/defaults.h b/include/common/defaults.h +index f765e90..07e74b7 100644 +--- a/include/common/defaults.h ++++ b/include/common/defaults.h +@@ -131,6 +131,7 @@ + #define DEF_SMTP_CHECK_REQ "HELO localhost\r\n" + #define DEF_LDAP_CHECK_REQ "\x30\x0c\x02\x01\x01\x60\x07\x02\x01\x03\x04\x00\x80\x00" + #define DEF_REDIS_CHECK_REQ "*1\r\n$4\r\nPING\r\n" ++#define DEF_CHECK_HOST_HDR "X-Check-Info" + + #define DEF_HANA_ONERR HANA_ONERR_FAILCHK + #define DEF_HANA_ERRLIMIT 10 +diff --git a/include/types/proxy.h b/include/types/proxy.h +index af2a3ab..638b5f7 100644 +--- a/include/types/proxy.h ++++ b/include/types/proxy.h +@@ -142,7 +142,8 @@ enum pr_mode { + #define PR_O2_SRC_ADDR 0x00100000 /* get the source ip and port for logs */ + + #define PR_O2_FAKE_KA 0x00200000 /* pretend we do keep-alive with server eventhough we close */ +-/* unused: 0x00400000 */ ++#define PR_O2_CHK_INFO 0x00400000 /* include info header and value in http health checks */ ++ + #define PR_O2_EXP_NONE 0x00000000 /* http-check : no expect rule */ + #define PR_O2_EXP_STS 0x00800000 /* http-check expect status */ + #define PR_O2_EXP_RSTS 0x01000000 /* http-check expect rstatus */ +@@ -338,7 +339,10 @@ struct proxy { + int grace; /* grace time after stop request */ + struct list tcpcheck_rules; /* tcp-check send / expect rules */ + char *check_req; /* HTTP or SSL request to use for PR_O_HTTP_CHK|PR_O_SSL3_CHK */ +- int check_len; /* Length of the HTTP or SSL3 request */ ++ int check_req_len; /* Length of the HTTP or SSL3 request */ ++ struct sockaddr_storage check_addr; /* the address to check */ ++ char *check_for_hdr_name; /* HTTP header used to identify host being checked */ ++ int check_for_hdr_name_len; /* Length of the HTTP header */ + char *expect_str; /* http-check expected content : string or text version of the regex */ + regex_t *expect_regex; /* http-check expected content */ + struct chunk errmsg[HTTP_ERR_SIZE]; /* default or customized error messages for known errors */ +diff --git a/include/types/server.h b/include/types/server.h +index 54ab813..ef56a49 100644 +--- a/include/types/server.h ++++ b/include/types/server.h +@@ -161,6 +161,9 @@ struct server { + struct sockaddr_storage addr; /* the address to check, if different from <addr> */ + } check_common; + ++ char *check_for_hdr_val; /* http header value used for health checkes */ ++ int check_for_hdr_val_len; /* length of the http header value */ ++ + struct check check; /* health-check specific configuration */ + struct check agent; /* agent specific configuration */ + +diff --git a/src/cfgparse.c b/src/cfgparse.c +index 9993c61..9d213a5 100644 +--- a/src/cfgparse.c ++++ b/src/cfgparse.c | ||
[+] | Added | 0001-enhance-hash-type-directive-with-algorithm-options.patch ^ |
@@ -0,0 +1,531 @@ +From: Bhaskar <bhaskar@tumblr.com> +Date: Wed, 30 Oct 2013 03:30:51 +0000 (-0400) +Subject: MEDIUM: backend: Enhance hash-type directive with an algorithm options +X-Git-Tag: v1.5-dev20~246 +X-Git-Url: http://haproxy.1wt.eu:81/git?p=haproxy.git;a=commitdiff_plain;h=98634f0c7b8d6aff0086fef9fedd90ffc79abcc2 + +MEDIUM: backend: Enhance hash-type directive with an algorithm options + +Summary: +In testing at tumblr, we found that using djb2 hashing instead of the +default sdbm hashing resulted is better workload distribution to our backends. + +This commit implements a change, that allows the user to specify the hash +function they want to use. It does not limit itself to consistent hashing +scenarios. + +The supported hash functions are sdbm (default), and djb2. + +For a discussion of the feature and analysis, see mailing list thread +"Consistent hashing alternative to sdbm" : + + http://marc.info/?l=haproxy&m=138213693909219 + +Note: This change does NOT make changes to new features, for instance, +applying an avalance hashing always being performed before applying +consistent hashing. +--- + +diff --git a/Makefile b/Makefile +index 2acaee4..4c30cc0 100644 +--- a/Makefile ++++ b/Makefile +@@ -637,7 +637,7 @@ OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocol.o \ + src/stream_interface.o src/dumpstats.o src/proto_tcp.o \ + src/session.o src/hdr_idx.o src/ev_select.o src/signal.o \ + src/acl.o src/sample.o src/memory.o src/freq_ctr.o src/auth.o \ +- src/compression.o src/payload.o ++ src/compression.o src/payload.o src/hash.o + + EBTREE_OBJS = $(EBTREE_DIR)/ebtree.o \ + $(EBTREE_DIR)/eb32tree.o $(EBTREE_DIR)/eb64tree.o \ +diff --git a/doc/configuration.txt b/doc/configuration.txt +index ba8057f..643afd9 100644 +--- a/doc/configuration.txt ++++ b/doc/configuration.txt +@@ -2496,45 +2496,65 @@ grace <time> + simplify it. + + +-hash-type <method> ++hash-type <method> <function> + Specify a method to use for mapping hashes to servers + May be used in sections : defaults | frontend | listen | backend + yes | no | yes | yes + Arguments : +- map-based the hash table is a static array containing all alive servers. +- The hashes will be very smooth, will consider weights, but will +- be static in that weight changes while a server is up will be +- ignored. This means that there will be no slow start. Also, +- since a server is selected by its position in the array, most +- mappings are changed when the server count changes. This means +- that when a server goes up or down, or when a server is added +- to a farm, most connections will be redistributed to different +- servers. This can be inconvenient with caches for instance. +- +- avalanche this mechanism uses the default map-based hashing described +- above but applies a full avalanche hash before performing the +- mapping. The result is a slightly less smooth hash for most +- situations, but the hash becomes better than pure map-based +- hashes when the number of servers is a multiple of the size of +- the input set. When using URI hash with a number of servers +- multiple of 64, it's desirable to change the hash type to +- this value. +- +- consistent the hash table is a tree filled with many occurrences of each +- server. The hash key is looked up in the tree and the closest +- server is chosen. This hash is dynamic, it supports changing +- weights while the servers are up, so it is compatible with the +- slow start feature. It has the advantage that when a server +- goes up or down, only its associations are moved. When a server +- is added to the farm, only a few part of the mappings are +- redistributed, making it an ideal algorithm for caches. +- However, due to its principle, the algorithm will never be very +- smooth and it may sometimes be necessary to adjust a server's +- weight or its ID to get a more balanced distribution. In order +- to get the same distribution on multiple load balancers, it is +- important that all servers have the same IDs. +- +- The default hash type is "map-based" and is recommended for most usages. ++ <method> is the method used to select a server from the hash computed by ++ the <function> : ++ ++ map-based the hash table is a static array containing all alive servers. ++ The hashes will be very smooth, will consider weights, but ++ will be static in that weight changes while a server is up ++ will be ignored. This means that there will be no slow start. ++ Also, since a server is selected by its position in the array, ++ most mappings are changed when the server count changes. This ++ means that when a server goes up or down, or when a server is ++ added to a farm, most connections will be redistributed to ++ different servers. This can be inconvenient with caches for ++ instance. ++ ++ avalanche this mechanism uses the default map-based hashing described ++ above but applies a full avalanche hash before performing the ++ mapping. The result is a slightly less smooth hash for most ++ situations, but the hash becomes better than pure map-based ++ hashes when the number of servers is a multiple of the size of ++ the input set. When using URI hash with a number of servers ++ multiple of 64, it's desirable to change the hash type to ++ this value. ++ ++ consistent the hash table is a tree filled with many occurrences of each ++ server. The hash key is looked up in the tree and the closest ++ server is chosen. This hash is dynamic, it supports changing ++ weights while the servers are up, so it is compatible with the ++ slow start feature. It has the advantage that when a server ++ goes up or down, only its associations are moved. When a ++ server is added to the farm, only a few part of the mappings ++ are redistributed, making it an ideal method for caches. ++ However, due to its principle, the distribution will never be ++ very smooth and it may sometimes be necessary to adjust a ++ server's weight or its ID to get a more balanced distribution. ++ In order to get the same distribution on multiple load ++ balancers, it is important that all servers have the exact ++ same IDs. Note: by default, a full avalanche hash is always ++ performed before applying the consistent hash. ++ ++ <function> is the hash function to be used : ++ ++ sdbm this function was created intially for sdbm (a public-domain ++ reimplementation of ndbm) database library. It was found to do ++ well in scrambling bits, causing better distribution of the keys ++ and fewer splits. It also happens to be a good general hashing ++ function with good distribution. ++ ++ djb2 this function was first proposed by Dan Bernstein many years ago ++ on comp.lang.c. Studies have shown that for certain workload this ++ function provides a better distribution than sdbm. ++ ++ The default hash type is "map-based" and is recommended for most usages. The ++ default function is "sdbm", the selection of a function should be based on ++ the range of the values being hashed. + + See also : "balance", "server" + +diff --git a/include/common/hash.h b/include/common/hash.h +new file mode 100644 +index 0000000..f6875c9 +--- /dev/null ++++ b/include/common/hash.h +@@ -0,0 +1,28 @@ ++/* ++ * include/common/hash.h ++ * Macros for different hashing function. ++ * ++ * Copyright (C) 2000-2011 Willy Tarreau - w@1wt.eu ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation, version 2.1 ++ * exclusively. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef _COMMON_HASH_H_ ++#define _COMMON_HASH_H_ ++ ++unsigned long hash_djb2(const char *key, int len); ++unsigned long hash_sdbm(const char *key, int len); ++ ++#endif /* _COMMON_HASH_H_ */ +diff --git a/include/types/backend.h b/include/types/backend.h +index 1183b36..1a433cf 100644 +--- a/include/types/backend.h ++++ b/include/types/backend.h +@@ -108,6 +108,12 @@ + #define BE_LB_HASH_AVAL 0x200000 /* run an avalanche hash before a map */ + #define BE_LB_HASH_TYPE 0x300000 /* get/clear hash types */ + ++/* BE_LB_HFCN_* is the hash function, to be used with BE_LB_HASH_FUNC */ ++#define BE_LB_HFCN_SDBM 0x000000 /* sdbm hash */ ++#define BE_LB_HFCN_DJB2 0x400000 /* djb2 hash */ ++#define BE_LB_HASH_FUNC 0xC00000 /* get/clear hash function */ ++ ++ + /* various constants */ + + /* The scale factor between user weight and effective weight allows smooth +diff --git a/src/backend.c b/src/backend.c +index 48c8761..bf4a81d 100644 | ||
[+] | Added | 0002-implement-avalanche-as-modifier.patch ^ |
@@ -0,0 +1,275 @@ +From: Bhaskar Maddala <bhaskar@tumblr.com> +Date: Tue, 5 Nov 2013 16:54:02 +0000 (-0500) +Subject: MEDIUM: backend: Implement avalanche as a modifier of the hashing functions. +X-Git-Tag: v1.5-dev20~245 +X-Git-Url: http://haproxy.1wt.eu:81/git?p=haproxy.git;a=commitdiff_plain;h=b6c0ac94a444be5f965f14492bf447ba0910daf1 + +MEDIUM: backend: Implement avalanche as a modifier of the hashing functions. + +Summary: +Avalanche is supported not as a native hashing choice, but a modifier +on the hashing function. Note that this means that possible configs +written after 1.5-dev4 using "hash-type avalanche" will get an informative +error instead. But as discussed on the mailing list it seems nobody ever +used it anyway, so let's fix it before the final 1.5 release. + +The default values were selected for backward compatibility with previous +releases, as discussed on the mailing list, which means that the consistent +hashing will still apply the avalanche hash by default when no explicit +algorithm is specified. + +Examples + (default) hash-type map-based + Map based hashing using sdbm without avalanche + + (default) hash-type consistent + Consistent hashing using sdbm with avalanche + +Additional Examples: + + (a) hash-type map-based sdbm + Same as default for map-based above + (b) hash-type map-based sdbm avalanche + Map based hashing using sdbm with avalanche + (c) hash-type map-based djb2 + Map based hashing using djb2 without avalanche + (d) hash-type map-based djb2 avalanche + Map based hashing using djb2 with avalanche + (e) hash-type consistent sdbm avalanche + Same as default for consistent above + (f) hash-type consistent sdbm + Consistent hashing using sdbm without avalanche + (g) hash-type consistent djb2 + Consistent hashing using djb2 without avalanche + (h) hash-type consistent djb2 avalanche + Consistent hashing using djb2 with avalanche +--- + +diff --git a/doc/configuration.txt b/doc/configuration.txt +index 643afd9..c430ec3 100644 +--- a/doc/configuration.txt ++++ b/doc/configuration.txt +@@ -2496,7 +2496,7 @@ grace <time> + simplify it. + + +-hash-type <method> <function> ++hash-type <method> <function> <modifier> + Specify a method to use for mapping hashes to servers + May be used in sections : defaults | frontend | listen | backend + yes | no | yes | yes +@@ -2515,15 +2515,6 @@ hash-type <method> <function> + different servers. This can be inconvenient with caches for + instance. + +- avalanche this mechanism uses the default map-based hashing described +- above but applies a full avalanche hash before performing the +- mapping. The result is a slightly less smooth hash for most +- situations, but the hash becomes better than pure map-based +- hashes when the number of servers is a multiple of the size of +- the input set. When using URI hash with a number of servers +- multiple of 64, it's desirable to change the hash type to +- this value. +- + consistent the hash table is a tree filled with many occurrences of each + server. The hash key is looked up in the tree and the closest + server is chosen. This hash is dynamic, it supports changing +@@ -2537,8 +2528,8 @@ hash-type <method> <function> + server's weight or its ID to get a more balanced distribution. + In order to get the same distribution on multiple load + balancers, it is important that all servers have the exact +- same IDs. Note: by default, a full avalanche hash is always +- performed before applying the consistent hash. ++ same IDs. Note: consistent hash uses sdbm and avalanche if no ++ hash function is specified. + + <function> is the hash function to be used : + +@@ -2546,11 +2537,31 @@ hash-type <method> <function> + reimplementation of ndbm) database library. It was found to do + well in scrambling bits, causing better distribution of the keys + and fewer splits. It also happens to be a good general hashing +- function with good distribution. ++ function with good distribution, unless the total server weight ++ is a multiple of 64, in which case applying the avalanche ++ modifier may help. + + djb2 this function was first proposed by Dan Bernstein many years ago + on comp.lang.c. Studies have shown that for certain workload this +- function provides a better distribution than sdbm. ++ function provides a better distribution than sdbm. It generally ++ works well with text-based inputs though it can perform extremely ++ poorly with numeric-only input or when the total server weight is ++ a multiple of 33, unless the avalanche modifier is also used. ++ ++ <modifier> indicates an optional method applied after hashing the key : ++ ++ avalanche This directive indicates that the result from the hash ++ function above should not be used in its raw form but that ++ a 4-byte full avalanche hash must be applied first. The ++ purpose of this step is to mix the resulting bits from the ++ previous hash in order to avoid any undesired effect when ++ the input contains some limited values or when the number of ++ servers is a multiple of one of the hash's components (64 ++ for SDBM, 33 for DJB2). Enabling avalanche tends to make the ++ result less predictable, but it's also not as smooth as when ++ using the original function. Some testing might be needed ++ with some workloads. This hash is one of the many proposed ++ by Bob Jenkins. + + The default hash type is "map-based" and is recommended for most usages. The + default function is "sdbm", the selection of a function should be based on +diff --git a/include/types/backend.h b/include/types/backend.h +index 1a433cf..57d17bd 100644 +--- a/include/types/backend.h ++++ b/include/types/backend.h +@@ -105,8 +105,11 @@ + /* hash types */ + #define BE_LB_HASH_MAP 0x000000 /* map-based hash (default) */ + #define BE_LB_HASH_CONS 0x100000 /* consistent hashbit to indicate a dynamic algorithm */ +-#define BE_LB_HASH_AVAL 0x200000 /* run an avalanche hash before a map */ +-#define BE_LB_HASH_TYPE 0x300000 /* get/clear hash types */ ++#define BE_LB_HASH_TYPE 0x100000 /* get/clear hash types */ ++ ++/* additional modifier on top of the hash function (only avalanche right now) */ ++#define BE_LB_HMOD_AVAL 0x200000 /* avalanche modifier */ ++#define BE_LB_HASH_MOD 0x200000 /* get/clear hash modifier */ + + /* BE_LB_HFCN_* is the hash function, to be used with BE_LB_HASH_FUNC */ + #define BE_LB_HFCN_SDBM 0x000000 /* sdbm hash */ +diff --git a/src/backend.c b/src/backend.c +index bf4a81d..e044430 100644 +--- a/src/backend.c ++++ b/src/backend.c +@@ -147,7 +147,7 @@ struct server *get_server_sh(struct proxy *px, const char *addr, int len) + h ^= ntohl(*(unsigned int *)(&addr[l])); + l += sizeof (int); + } +- if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP) ++ if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) + h = full_hash(h); + hash_done: + if (px->lbprm.algo & BE_LB_LKUP_CHTREE) +@@ -199,7 +199,7 @@ struct server *get_server_uh(struct proxy *px, char *uri, int uri_len) + + hash = gen_hash(px, start, (end - start)); + +- if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP) ++ if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) + hash = full_hash(hash); + hash_done: + if (px->lbprm.algo & BE_LB_LKUP_CHTREE) +@@ -256,7 +256,7 @@ struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len) + } + hash = gen_hash(px, start, (end - start)); + +- if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP) ++ if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) + hash = full_hash(hash); + + if (px->lbprm.algo & BE_LB_LKUP_CHTREE) +@@ -330,7 +330,7 @@ struct server *get_server_ph_post(struct session *s) + } + hash = gen_hash(px, start, (end - start)); + +- if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP) ++ if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) + hash = full_hash(hash); + + if (px->lbprm.algo & BE_LB_LKUP_CHTREE) +@@ -422,7 +422,7 @@ struct server *get_server_hh(struct session *s) + } + hash = gen_hash(px, start, (end - start)); + } +- if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP) ++ if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) + hash = full_hash(hash); + hash_done: + if (px->lbprm.algo & BE_LB_LKUP_CHTREE) +@@ -466,7 +466,7 @@ struct server *get_server_rch(struct session *s) + */ + hash = gen_hash(px, smp.data.str.str, len); + +- if ((px->lbprm.algo & BE_LB_HASH_TYPE) != BE_LB_HASH_MAP) ++ if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL) + hash = full_hash(hash); + hash_done: + if (px->lbprm.algo & BE_LB_LKUP_CHTREE) +diff --git a/src/cfgparse.c b/src/cfgparse.c +index 051f600..bb79a34 100644 | ||
[+] | Added | haproxy-1.5-geolocation.patch ^ |
@@ -0,0 +1,701 @@ +From b0ed0615b148d1ee261c018011e0770b684d38f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr> +Date: Mon, 17 Jun 2013 22:36:19 +0200 +Subject: [PATCH] Geolocation based on haproxy 1.5-dev19 + +--- + include/common/chunk.h | 1 + + include/proto/acl.h | 4 ++ + include/proto/proto_http.h | 2 + + include/proto/proto_tcp.h | 1 + + include/types/acl.h | 1 + + include/types/proto_http.h | 1 + + include/types/proxy.h | 10 ++++ + src/acl.c | 63 ++++++++++++++++++++- + src/cfgparse.c | 88 +++++++++++++++++++++++++++++ + src/chunk.c | 50 +++++++++++++++++ + src/haproxy.c | 7 +++ + src/proto_http.c | 136 ++++++++++++++++++++++++++++++++++++++++++--- + src/proto_tcp.c | 5 +- + 13 files changed, 354 insertions(+), 15 deletions(-) + +diff --git a/include/common/chunk.h b/include/common/chunk.h +index 18f41af..4e883b5 100644 +--- a/include/common/chunk.h ++++ b/include/common/chunk.h +@@ -47,6 +47,7 @@ int chunk_htmlencode(struct chunk *dst, struct chunk *src); + int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc); + int chunk_strcmp(const struct chunk *chk, const char *str); + int chunk_strcasecmp(const struct chunk *chk, const char *str); ++int chunk_replace(struct chunk *chk, const char *token, const char *value, const int ofs); + int alloc_trash_buffers(int bufsize); + struct chunk *get_trash_chunk(void); + +diff --git a/include/proto/acl.h b/include/proto/acl.h +index 6859b3d..8c7dda5 100644 +--- a/include/proto/acl.h ++++ b/include/proto/acl.h +@@ -224,6 +224,10 @@ int acl_match_ip(struct sample *smp, struct acl_pattern *pattern); + */ + int acl_match_reg(struct sample *smp, struct acl_pattern *pattern); + ++void *acl_lookup_ip(struct sample *smp, struct acl_expr *expr); ++int init_geolocate(char *filename, struct acl_expr **geolocate, char **err); ++void deinit_geolocate(struct acl_expr *expr); ++ + #endif /* _PROTO_ACL_H */ + + /* +diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h +index 24e3581..315688e 100644 +--- a/include/proto/proto_http.h ++++ b/include/proto/proto_http.h +@@ -117,6 +117,8 @@ struct chunk *http_error_message(struct session *s, int msgnum); + struct redirect_rule *http_parse_redirect_rule(const char *file, int line, struct proxy *curproxy, + const char **args, char **errmsg); + ++int smp_fetch_hdr_ip(struct proxy *px, struct session *l4, void *l7, unsigned int opt, const struct arg *args, struct sample *smp); ++ + /* to be used when contents change in an HTTP message */ + #define http_msg_move_end(msg, bytes) do { \ + unsigned int _bytes = (bytes); \ +diff --git a/include/proto/proto_tcp.h b/include/proto/proto_tcp.h +index 4644452..3ac5230 100644 +--- a/include/proto/proto_tcp.h ++++ b/include/proto/proto_tcp.h +@@ -38,6 +38,7 @@ int tcp_drain(int fd); + int tcp_inspect_request(struct session *s, struct channel *req, int an_bit); + int tcp_inspect_response(struct session *s, struct channel *rep, int an_bit); + int tcp_exec_req_rules(struct session *s); ++int smp_fetch_src(struct proxy *px, struct session *l4, void *l7, unsigned int opt, const struct arg *args, struct sample *smp); + + /* Converts the INET/INET6 source address to a stick_table key usable for table + * lookups. Returns either NULL if the source cannot be converted (eg: not +diff --git a/include/types/acl.h b/include/types/acl.h +index 42e2e9c..80d7805 100644 +--- a/include/types/acl.h ++++ b/include/types/acl.h +@@ -77,6 +77,7 @@ enum { + ACL_PAT_F_FROM_FILE = 1 << 1, /* pattern comes from a file */ + ACL_PAT_F_TREE_OK = 1 << 2, /* the pattern parser is allowed to build a tree */ + ACL_PAT_F_TREE = 1 << 3, /* some patterns are arranged in a tree */ ++ ACL_PAT_F_DICTIONARY = 1 << 4, /* some patterns define a dictionary (geolocation) */ + }; + + /* ACL match methods */ +diff --git a/include/types/proto_http.h b/include/types/proto_http.h +index 1d7c92f..55ad5fe 100644 +--- a/include/types/proto_http.h ++++ b/include/types/proto_http.h +@@ -416,6 +416,7 @@ struct http_txn { + char *cli_cookie; /* cookie presented by the client, in capture mode */ + char *srv_cookie; /* cookie presented by the server, in capture mode */ + char *sessid; /* the appsession id, if found in the request or in the response */ ++ char *geoloc; /* geolocation detected for this transaction */ + int cookie_first_date; /* if non-zero, first date the expirable cookie was set/seen */ + int cookie_last_date; /* if non-zero, last date the expirable cookie was set/seen */ + +diff --git a/include/types/proxy.h b/include/types/proxy.h +index e6bc755..c25abe0 100644 +--- a/include/types/proxy.h ++++ b/include/types/proxy.h +@@ -173,6 +173,9 @@ enum { + #define STK_IS_STORE 0x00000002 /* store on request fetch */ + #define STK_ON_RSP 0x00000004 /* store on response fetch */ + ++#define GEOLOC_SRC 0x00000001 /* geolocation based on the client source IP */ ++#define GEOLOC_HDR 0x00000002 /* geolocation based on a HTTP header */ ++ + struct error_snapshot { + struct timeval when; /* date of this event, (tv_sec == 0) means "never" */ + unsigned int len; /* original length of the last invalid request/response */ +@@ -333,6 +336,13 @@ struct proxy { + unsigned int backlog; /* force the frontend's listen backlog */ + unsigned int bind_proc; /* bitmask of processes using this proxy. 0 = all. */ + ++ int geoloc_options; /* GEOLOC_SRC, GEOLOC_HDR */ ++ char *geoloc_hdr_name; /* header name used for geolocation if defined */ ++ int geoloc_hdr_len; /* length of the name of the header above */ ++ int geoloc_hdr_occ; /* occurrence number of header above: >0 = from first, <0 = from end, 0=disabled */ ++ struct acl_expr *geolocate; /* special acl expression reserved for the geolocation */ ++ struct acl_cond *geolocate_cond; /* acl condition to meet before applying geolocation */ ++ + /* warning: these structs are huge, keep them at the bottom */ + struct sockaddr_storage dispatch_addr; /* the default address to connect to */ + struct error_snapshot invalid_req, invalid_rep; /* captures of last errors */ +diff --git a/src/acl.c b/src/acl.c +index 664ef5c..a37a26e 100644 +--- a/src/acl.c ++++ b/src/acl.c +@@ -142,7 +142,7 @@ int acl_match_bin(struct sample *smp, struct acl_pattern *pattern) + /* Lookup a string in the expression's pattern tree. The node is returned if it + * exists, otherwise NULL. + */ +-static void *acl_lookup_str(struct sample *smp, struct acl_expr *expr) ++void *acl_lookup_str(struct sample *smp, struct acl_expr *expr) + { + /* data are stored in a tree */ + struct ebmb_node *node; +@@ -424,7 +424,7 @@ int acl_match_ip(struct sample *smp, struct acl_pattern *pattern) + /* Lookup an IPv4 address in the expression's pattern tree using the longest + * match method. The node is returned if it exists, otherwise NULL. + */ +-static void *acl_lookup_ip(struct sample *smp, struct acl_expr *expr) ++void *acl_lookup_ip(struct sample *smp, struct acl_expr *expr) + { + struct in_addr *s; + +@@ -797,14 +797,18 @@ int acl_parse_ip(const char **text, struct acl_pattern *pattern, int *opaque, ch + */ + pattern->type = SMP_T_IPV4; + if (mask + (mask & -mask) == 0 && tree) { ++ int len = (pattern->ptr.str ? strlen(pattern->ptr.str) + 1 : 0); /* optional null terminated string length */ + mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */ + /* FIXME: insert <addr>/<mask> into the tree here */ +- node = calloc(1, sizeof(*node) + 4); /* reserve 4 bytes for IPv4 address */ ++ node = calloc(1, sizeof(*node) + 4 + len); /* reserve 4 bytes for IPv4 address + optional tring length */ + if (!node) { + memprintf(err, "out of memory while loading IPv4 pattern"); + return 0; + } + memcpy(node->key, &pattern->val.ipv4.addr, 4); /* network byte order */ ++ if (len) ++ memcpy(node->key + 4, pattern->ptr.str, len); ++ + node->node.pfx = mask; + if (ebmb_insert_prefix(tree, node, 4) != node) + free(node); /* was a duplicate */ +@@ -965,6 +969,8 @@ static int acl_read_patterns_from_file(struct acl_expr *expr, + pattern = NULL; + args[1] = ""; + while (fgets(trash.str, trash.size, file) != NULL) { ++ char *value = NULL; ++ + line++; + c = trash.str; + +@@ -978,6 +984,14 @@ static int acl_read_patterns_from_file(struct acl_expr *expr, + + + args[0] = c; ++ if (patflags & ACL_PAT_F_DICTIONARY) { ++ while (*c && *c != '\n' && *c != '\r' && *c != '\t' && *c != ' ') ++ c++; ++ while (*c == ' ' || *c == '\t') ++ *c++ = 0; ++ value = c; ++ } ++ + while (*c && *c != '\n' && *c != '\r') + c++; + *c = 0; +@@ -997,6 +1011,9 @@ static int acl_read_patterns_from_file(struct acl_expr *expr, + memset(pattern, 0, sizeof(*pattern)); + pattern->flags = patflags; + ++ if (value) { ++ pattern->ptr.str = strdup(value); ++ } + if (!(pattern->flags & ACL_PAT_F_IGNORE_CASE) && | ||
[+] | Added | benchmark.cfg ^ |
@@ -0,0 +1,504 @@ +defaults + mode http + option http-server-close + timeout connect 5s + timeout client 60s + timeout server 60s + timeout http-keep-alive 5s + +listen original-acl-redirects :9001 + redirect location /a1 if { hdr_ip(X-Forwarded-For,-1) -f A1.subnets } + redirect location /a2 if { hdr_ip(X-Forwarded-For,-1) -f A2.subnets } + redirect location /ad if { hdr_ip(X-Forwarded-For,-1) -f AD.subnets } + redirect location /ae if { hdr_ip(X-Forwarded-For,-1) -f AE.subnets } + redirect location /af if { hdr_ip(X-Forwarded-For,-1) -f AF.subnets } + redirect location /ag if { hdr_ip(X-Forwarded-For,-1) -f AG.subnets } + redirect location /ai if { hdr_ip(X-Forwarded-For,-1) -f AI.subnets } + redirect location /al if { hdr_ip(X-Forwarded-For,-1) -f AL.subnets } + redirect location /am if { hdr_ip(X-Forwarded-For,-1) -f AM.subnets } + redirect location /ao if { hdr_ip(X-Forwarded-For,-1) -f AO.subnets } + redirect location /ap if { hdr_ip(X-Forwarded-For,-1) -f AP.subnets } + redirect location /aq if { hdr_ip(X-Forwarded-For,-1) -f AQ.subnets } + redirect location /ar if { hdr_ip(X-Forwarded-For,-1) -f AR.subnets } + redirect location /as if { hdr_ip(X-Forwarded-For,-1) -f AS.subnets } + redirect location /at if { hdr_ip(X-Forwarded-For,-1) -f AT.subnets } + redirect location /au if { hdr_ip(X-Forwarded-For,-1) -f AU.subnets } + redirect location /aw if { hdr_ip(X-Forwarded-For,-1) -f AW.subnets } + redirect location /ax if { hdr_ip(X-Forwarded-For,-1) -f AX.subnets } + redirect location /az if { hdr_ip(X-Forwarded-For,-1) -f AZ.subnets } + redirect location /ba if { hdr_ip(X-Forwarded-For,-1) -f BA.subnets } + redirect location /bb if { hdr_ip(X-Forwarded-For,-1) -f BB.subnets } + redirect location /bd if { hdr_ip(X-Forwarded-For,-1) -f BD.subnets } + redirect location /be if { hdr_ip(X-Forwarded-For,-1) -f BE.subnets } + redirect location /bf if { hdr_ip(X-Forwarded-For,-1) -f BF.subnets } + redirect location /bg if { hdr_ip(X-Forwarded-For,-1) -f BG.subnets } + redirect location /bh if { hdr_ip(X-Forwarded-For,-1) -f BH.subnets } + redirect location /bi if { hdr_ip(X-Forwarded-For,-1) -f BI.subnets } + redirect location /bj if { hdr_ip(X-Forwarded-For,-1) -f BJ.subnets } + redirect location /bl if { hdr_ip(X-Forwarded-For,-1) -f BL.subnets } + redirect location /bm if { hdr_ip(X-Forwarded-For,-1) -f BM.subnets } + redirect location /bn if { hdr_ip(X-Forwarded-For,-1) -f BN.subnets } + redirect location /bo if { hdr_ip(X-Forwarded-For,-1) -f BO.subnets } + redirect location /bq if { hdr_ip(X-Forwarded-For,-1) -f BQ.subnets } + redirect location /br if { hdr_ip(X-Forwarded-For,-1) -f BR.subnets } + redirect location /bs if { hdr_ip(X-Forwarded-For,-1) -f BS.subnets } + redirect location /bt if { hdr_ip(X-Forwarded-For,-1) -f BT.subnets } + redirect location /bv if { hdr_ip(X-Forwarded-For,-1) -f BV.subnets } + redirect location /bw if { hdr_ip(X-Forwarded-For,-1) -f BW.subnets } + redirect location /by if { hdr_ip(X-Forwarded-For,-1) -f BY.subnets } + redirect location /bz if { hdr_ip(X-Forwarded-For,-1) -f BZ.subnets } + redirect location /ca if { hdr_ip(X-Forwarded-For,-1) -f CA.subnets } + redirect location /cd if { hdr_ip(X-Forwarded-For,-1) -f CD.subnets } + redirect location /cf if { hdr_ip(X-Forwarded-For,-1) -f CF.subnets } + redirect location /cg if { hdr_ip(X-Forwarded-For,-1) -f CG.subnets } + redirect location /ch if { hdr_ip(X-Forwarded-For,-1) -f CH.subnets } + redirect location /ci if { hdr_ip(X-Forwarded-For,-1) -f CI.subnets } + redirect location /ck if { hdr_ip(X-Forwarded-For,-1) -f CK.subnets } + redirect location /cl if { hdr_ip(X-Forwarded-For,-1) -f CL.subnets } + redirect location /cm if { hdr_ip(X-Forwarded-For,-1) -f CM.subnets } + redirect location /cn if { hdr_ip(X-Forwarded-For,-1) -f CN.subnets } + redirect location /co if { hdr_ip(X-Forwarded-For,-1) -f CO.subnets } + redirect location /cr if { hdr_ip(X-Forwarded-For,-1) -f CR.subnets } + redirect location /cu if { hdr_ip(X-Forwarded-For,-1) -f CU.subnets } + redirect location /cv if { hdr_ip(X-Forwarded-For,-1) -f CV.subnets } + redirect location /cw if { hdr_ip(X-Forwarded-For,-1) -f CW.subnets } + redirect location /cy if { hdr_ip(X-Forwarded-For,-1) -f CY.subnets } + redirect location /cz if { hdr_ip(X-Forwarded-For,-1) -f CZ.subnets } + redirect location /de if { hdr_ip(X-Forwarded-For,-1) -f DE.subnets } + redirect location /dj if { hdr_ip(X-Forwarded-For,-1) -f DJ.subnets } + redirect location /dk if { hdr_ip(X-Forwarded-For,-1) -f DK.subnets } + redirect location /dm if { hdr_ip(X-Forwarded-For,-1) -f DM.subnets } + redirect location /do if { hdr_ip(X-Forwarded-For,-1) -f DO.subnets } + redirect location /dz if { hdr_ip(X-Forwarded-For,-1) -f DZ.subnets } + redirect location /ec if { hdr_ip(X-Forwarded-For,-1) -f EC.subnets } + redirect location /ee if { hdr_ip(X-Forwarded-For,-1) -f EE.subnets } + redirect location /eg if { hdr_ip(X-Forwarded-For,-1) -f EG.subnets } + redirect location /er if { hdr_ip(X-Forwarded-For,-1) -f ER.subnets } + redirect location /es if { hdr_ip(X-Forwarded-For,-1) -f ES.subnets } + redirect location /et if { hdr_ip(X-Forwarded-For,-1) -f ET.subnets } + redirect location /eu if { hdr_ip(X-Forwarded-For,-1) -f EU.subnets } + redirect location /fi if { hdr_ip(X-Forwarded-For,-1) -f FI.subnets } + redirect location /fj if { hdr_ip(X-Forwarded-For,-1) -f FJ.subnets } + redirect location /fk if { hdr_ip(X-Forwarded-For,-1) -f FK.subnets } + redirect location /fm if { hdr_ip(X-Forwarded-For,-1) -f FM.subnets } + redirect location /fo if { hdr_ip(X-Forwarded-For,-1) -f FO.subnets } + redirect location /fr if { hdr_ip(X-Forwarded-For,-1) -f FR.subnets } + redirect location /ga if { hdr_ip(X-Forwarded-For,-1) -f GA.subnets } + redirect location /gb if { hdr_ip(X-Forwarded-For,-1) -f GB.subnets } + redirect location /gd if { hdr_ip(X-Forwarded-For,-1) -f GD.subnets } + redirect location /ge if { hdr_ip(X-Forwarded-For,-1) -f GE.subnets } + redirect location /gf if { hdr_ip(X-Forwarded-For,-1) -f GF.subnets } + redirect location /gg if { hdr_ip(X-Forwarded-For,-1) -f GG.subnets } + redirect location /gh if { hdr_ip(X-Forwarded-For,-1) -f GH.subnets } + redirect location /gi if { hdr_ip(X-Forwarded-For,-1) -f GI.subnets } + redirect location /gl if { hdr_ip(X-Forwarded-For,-1) -f GL.subnets } + redirect location /gm if { hdr_ip(X-Forwarded-For,-1) -f GM.subnets } + redirect location /gn if { hdr_ip(X-Forwarded-For,-1) -f GN.subnets } + redirect location /gp if { hdr_ip(X-Forwarded-For,-1) -f GP.subnets } + redirect location /gq if { hdr_ip(X-Forwarded-For,-1) -f GQ.subnets } + redirect location /gr if { hdr_ip(X-Forwarded-For,-1) -f GR.subnets } + redirect location /gt if { hdr_ip(X-Forwarded-For,-1) -f GT.subnets } + redirect location /gu if { hdr_ip(X-Forwarded-For,-1) -f GU.subnets } + redirect location /gw if { hdr_ip(X-Forwarded-For,-1) -f GW.subnets } + redirect location /gy if { hdr_ip(X-Forwarded-For,-1) -f GY.subnets } + redirect location /hk if { hdr_ip(X-Forwarded-For,-1) -f HK.subnets } + redirect location /hm if { hdr_ip(X-Forwarded-For,-1) -f HM.subnets } + redirect location /hn if { hdr_ip(X-Forwarded-For,-1) -f HN.subnets } + redirect location /hr if { hdr_ip(X-Forwarded-For,-1) -f HR.subnets } + redirect location /ht if { hdr_ip(X-Forwarded-For,-1) -f HT.subnets } + redirect location /hu if { hdr_ip(X-Forwarded-For,-1) -f HU.subnets } + redirect location /id if { hdr_ip(X-Forwarded-For,-1) -f ID.subnets } + redirect location /ie if { hdr_ip(X-Forwarded-For,-1) -f IE.subnets } + redirect location /il if { hdr_ip(X-Forwarded-For,-1) -f IL.subnets } + redirect location /im if { hdr_ip(X-Forwarded-For,-1) -f IM.subnets } + redirect location /in if { hdr_ip(X-Forwarded-For,-1) -f IN.subnets } + redirect location /io if { hdr_ip(X-Forwarded-For,-1) -f IO.subnets } + redirect location /iq if { hdr_ip(X-Forwarded-For,-1) -f IQ.subnets } + redirect location /ir if { hdr_ip(X-Forwarded-For,-1) -f IR.subnets } + redirect location /is if { hdr_ip(X-Forwarded-For,-1) -f IS.subnets } + redirect location /it if { hdr_ip(X-Forwarded-For,-1) -f IT.subnets } + redirect location /je if { hdr_ip(X-Forwarded-For,-1) -f JE.subnets } + redirect location /jm if { hdr_ip(X-Forwarded-For,-1) -f JM.subnets } + redirect location /jo if { hdr_ip(X-Forwarded-For,-1) -f JO.subnets } + redirect location /jp if { hdr_ip(X-Forwarded-For,-1) -f JP.subnets } + redirect location /ke if { hdr_ip(X-Forwarded-For,-1) -f KE.subnets } + redirect location /kg if { hdr_ip(X-Forwarded-For,-1) -f KG.subnets } + redirect location /kh if { hdr_ip(X-Forwarded-For,-1) -f KH.subnets } + redirect location /ki if { hdr_ip(X-Forwarded-For,-1) -f KI.subnets } + redirect location /km if { hdr_ip(X-Forwarded-For,-1) -f KM.subnets } + redirect location /kn if { hdr_ip(X-Forwarded-For,-1) -f KN.subnets } + redirect location /kp if { hdr_ip(X-Forwarded-For,-1) -f KP.subnets } + redirect location /kr if { hdr_ip(X-Forwarded-For,-1) -f KR.subnets } + redirect location /kw if { hdr_ip(X-Forwarded-For,-1) -f KW.subnets } + redirect location /ky if { hdr_ip(X-Forwarded-For,-1) -f KY.subnets } + redirect location /kz if { hdr_ip(X-Forwarded-For,-1) -f KZ.subnets } + redirect location /la if { hdr_ip(X-Forwarded-For,-1) -f LA.subnets } + redirect location /lb if { hdr_ip(X-Forwarded-For,-1) -f LB.subnets } + redirect location /lc if { hdr_ip(X-Forwarded-For,-1) -f LC.subnets } + redirect location /li if { hdr_ip(X-Forwarded-For,-1) -f LI.subnets } + redirect location /lk if { hdr_ip(X-Forwarded-For,-1) -f LK.subnets } + redirect location /lr if { hdr_ip(X-Forwarded-For,-1) -f LR.subnets } + redirect location /ls if { hdr_ip(X-Forwarded-For,-1) -f LS.subnets } + redirect location /lt if { hdr_ip(X-Forwarded-For,-1) -f LT.subnets } + redirect location /lu if { hdr_ip(X-Forwarded-For,-1) -f LU.subnets } + redirect location /lv if { hdr_ip(X-Forwarded-For,-1) -f LV.subnets } + redirect location /ly if { hdr_ip(X-Forwarded-For,-1) -f LY.subnets } + redirect location /ma if { hdr_ip(X-Forwarded-For,-1) -f MA.subnets } + redirect location /mc if { hdr_ip(X-Forwarded-For,-1) -f MC.subnets } + redirect location /md if { hdr_ip(X-Forwarded-For,-1) -f MD.subnets } + redirect location /me if { hdr_ip(X-Forwarded-For,-1) -f ME.subnets } + redirect location /mf if { hdr_ip(X-Forwarded-For,-1) -f MF.subnets } + redirect location /mg if { hdr_ip(X-Forwarded-For,-1) -f MG.subnets } + redirect location /mh if { hdr_ip(X-Forwarded-For,-1) -f MH.subnets } + redirect location /mk if { hdr_ip(X-Forwarded-For,-1) -f MK.subnets } + redirect location /ml if { hdr_ip(X-Forwarded-For,-1) -f ML.subnets } + redirect location /mm if { hdr_ip(X-Forwarded-For,-1) -f MM.subnets } + redirect location /mn if { hdr_ip(X-Forwarded-For,-1) -f MN.subnets } + redirect location /mo if { hdr_ip(X-Forwarded-For,-1) -f MO.subnets } + redirect location /mp if { hdr_ip(X-Forwarded-For,-1) -f MP.subnets } + redirect location /mq if { hdr_ip(X-Forwarded-For,-1) -f MQ.subnets } + redirect location /mr if { hdr_ip(X-Forwarded-For,-1) -f MR.subnets } + redirect location /ms if { hdr_ip(X-Forwarded-For,-1) -f MS.subnets } + redirect location /mt if { hdr_ip(X-Forwarded-For,-1) -f MT.subnets } + redirect location /mu if { hdr_ip(X-Forwarded-For,-1) -f MU.subnets } + redirect location /mv if { hdr_ip(X-Forwarded-For,-1) -f MV.subnets } + redirect location /mw if { hdr_ip(X-Forwarded-For,-1) -f MW.subnets } + redirect location /mx if { hdr_ip(X-Forwarded-For,-1) -f MX.subnets } + redirect location /my if { hdr_ip(X-Forwarded-For,-1) -f MY.subnets } + redirect location /mz if { hdr_ip(X-Forwarded-For,-1) -f MZ.subnets } + redirect location /na if { hdr_ip(X-Forwarded-For,-1) -f NA.subnets } + redirect location /nc if { hdr_ip(X-Forwarded-For,-1) -f NC.subnets } + redirect location /ne if { hdr_ip(X-Forwarded-For,-1) -f NE.subnets } + redirect location /nf if { hdr_ip(X-Forwarded-For,-1) -f NF.subnets } + redirect location /ng if { hdr_ip(X-Forwarded-For,-1) -f NG.subnets } + redirect location /ni if { hdr_ip(X-Forwarded-For,-1) -f NI.subnets } + redirect location /nl if { hdr_ip(X-Forwarded-For,-1) -f NL.subnets } + redirect location /no if { hdr_ip(X-Forwarded-For,-1) -f NO.subnets } + redirect location /np if { hdr_ip(X-Forwarded-For,-1) -f NP.subnets } + redirect location /nr if { hdr_ip(X-Forwarded-For,-1) -f NR.subnets } + redirect location /nu if { hdr_ip(X-Forwarded-For,-1) -f NU.subnets } + redirect location /nz if { hdr_ip(X-Forwarded-For,-1) -f NZ.subnets } + redirect location /om if { hdr_ip(X-Forwarded-For,-1) -f OM.subnets } + redirect location /pa if { hdr_ip(X-Forwarded-For,-1) -f PA.subnets } + redirect location /pe if { hdr_ip(X-Forwarded-For,-1) -f PE.subnets } + redirect location /pf if { hdr_ip(X-Forwarded-For,-1) -f PF.subnets } + redirect location /pg if { hdr_ip(X-Forwarded-For,-1) -f PG.subnets } + redirect location /ph if { hdr_ip(X-Forwarded-For,-1) -f PH.subnets } + redirect location /pk if { hdr_ip(X-Forwarded-For,-1) -f PK.subnets } + redirect location /pl if { hdr_ip(X-Forwarded-For,-1) -f PL.subnets } + redirect location /pm if { hdr_ip(X-Forwarded-For,-1) -f PM.subnets } + redirect location /pr if { hdr_ip(X-Forwarded-For,-1) -f PR.subnets } + redirect location /ps if { hdr_ip(X-Forwarded-For,-1) -f PS.subnets } + redirect location /pt if { hdr_ip(X-Forwarded-For,-1) -f PT.subnets } + redirect location /pw if { hdr_ip(X-Forwarded-For,-1) -f PW.subnets } + redirect location /py if { hdr_ip(X-Forwarded-For,-1) -f PY.subnets } + redirect location /qa if { hdr_ip(X-Forwarded-For,-1) -f QA.subnets } + redirect location /re if { hdr_ip(X-Forwarded-For,-1) -f RE.subnets } + redirect location /ro if { hdr_ip(X-Forwarded-For,-1) -f RO.subnets } + redirect location /rs if { hdr_ip(X-Forwarded-For,-1) -f RS.subnets } + redirect location /ru if { hdr_ip(X-Forwarded-For,-1) -f RU.subnets } | ||
Added | haproxy-1.5-dev26.tar.gz ^ | |
[+] | Added | haproxy-geoip ^ |
@@ -0,0 +1,97 @@ +#!/bin/bash + +set -e -o pipefail + +DEFAULT_INFILE="http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip" +DEFAULT_CACHEFILE="/etc/haproxy/GeoIPCountryCSV.zip" + +function usage() +{ + cat >&2 << EOF + +Usage: $0 [-l] [-i <input file>] [<country code>...] + +Options : + -h display this help and exit + -l applies a lowercase filter to the output + -c <cachefile> when using an HTTP URL, defines where the file will be cached + on disk. This prevents downloading a file that was not + modified + Default: $DEFAULT_CACHEFILE + -i <infile> the input file containing the GeOIP database. + it can be a local file or an HTTP URL. If the file name + ends with ".zip", it will be automatically unzipped + Default: $DEFAULT_INFILE + + <country code> if specified, only those countries will be sent to the + output. If not specified, all of them will + + +Example : +$ $0 -l -i $DEFAULT_INFILE FR UK IT US +EOF + exit 1 +} +# Initialize the parameters from the command line +filters="" +infile=$DEFAULT_INFILE +cachefile=$DEFAULT_CACHEFILE +lowercase_opts=0 +while getopts "c:i:hl" opt; +do + case $opt in + c) cachefile=$OPTARG;; + i) infile=$OPTARG;; + l) lowercase_opts=1;; + h | \?) usage;; + esac +done +shift $(($OPTIND - 1)) + + +# Fetch the file if it's a HTTP URL, then use the cache file as input +if [[ "$infile" =~ ^http://.* ]]; +then + curl -fs -z $cachefile -o $cachefile $infile || { echo "Unable to fetch the GeoIP data file"; exit 1; } + infile=$cachefile +fi + +if [ ! -e $infile ]; +then + echo "Le fichier source de géolocalisation $infile n'existe pas". >&2 + exit 1 +fi + +# Should we decompress it on the fly ? +if [[ "$infile" =~ ^.*\.zip ]]; +then + reader="funzip" +else + reader="cat" +fi + +# Initialize the country filter +countries="" +for country in $*; +do + if [ "$countries" = "" ]; + then + countries="$country" + else + countries="$countries|$country" + fi +done + +if [ "$countries" != "" ]; +then + filters="$filters|grep -Ei '($countries)'" +fi + +# Initialize the lowercase filter +if [ $lowercase_opts -eq 1 ]; +then + filters="$filters|tr A-Z a-z" +fi + +# Now we can launch the conversion process +eval "$reader $infile | cut -d, -f1,2,5 | iprange | sed 's/\"//g' $filters" || { echo "GeoIP data conversion failure"; exit 1; } |