[PATCH] Remove more global state from systemd wrapper
Hi, this is the next step in my ongoing quest to give some lovin' to the systemd wrapper. It's against 1.6, I guess there is no reason to backport this to 1.5. Does it look acceptable? Cheers, Conrad -- Conrad Hoffmann Traffic Engineer SoundCloud Ltd. | Rheinsberger Str. 76/77, 10115 Berlin, Germany Managing Director: Alexander Ljung | Incorporated in England & Wales with Company No. 6343600 | Local Branch Office | AG Charlottenburg | HRB 110657B >From b7f869424c6a75dc0b7ff734b61a98080448e5ad Mon Sep 17 00:00:00 2001 From: Conrad Hoffmann Date: Thu, 21 Aug 2014 07:44:12 +0200 Subject: [PATCH] Remove more global state from systemd wrapper. Now that the signal handling is reduced to a minimum, all state can be kept locally, making functions easier to read and debug. Signed-off-by: Conrad Hoffmann --- src/haproxy-systemd-wrapper.c | 54 +++ 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c index 90a94ce..97e80e5 100644 --- a/src/haproxy-systemd-wrapper.c +++ b/src/haproxy-systemd-wrapper.c @@ -19,15 +19,12 @@ #include #define REEXEC_FLAG "HAPROXY_SYSTEMD_REEXEC" +#define DEFAULT_PID_FILE "/run/haproxy.pid" #define SD_DEBUG "<7>" #define SD_NOTICE "<5>" static volatile sig_atomic_t caught_signal; -static char *pid_file = "/run/haproxy.pid"; -static int wrapper_argc; -static char **wrapper_argv; - static void locate_haproxy(char *buffer, size_t buffer_size) { char *end = NULL; @@ -44,7 +41,7 @@ static void locate_haproxy(char *buffer, size_t buffer_size) buffer[buffer_size - 1] = '\0'; } -static void spawn_haproxy(char **pid_strv, int nb_pid) +static void spawn_haproxy(int wrapper_argc, char **wrapper_argv, int pidc, char **pidv) { char haproxy_bin[512]; pid_t pid; @@ -57,7 +54,7 @@ static void spawn_haproxy(char **pid_strv, int nb_pid) pid = fork(); if (!pid) { /* 3 for "haproxy -Ds -sf" */ - char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *)); + char **argv = calloc(4 + main_argc + pidc + 1, sizeof(char *)); int i; int argno = 0; locate_haproxy(haproxy_bin, 512); @@ -65,10 +62,10 @@ static void spawn_haproxy(char **pid_strv, int nb_pid) for (i = 0; i < main_argc; ++i) argv[argno++] = main_argv[i]; argv[argno++] = "-Ds"; - if (nb_pid > 0) { + if (pidc > 0) { argv[argno++] = "-sf"; - for (i = 0; i < nb_pid; ++i) -argv[argno++] = pid_strv[i]; + for (i = 0; i < pidc; ++i) +argv[argno++] = pidv[i]; } argv[argno] = NULL; @@ -82,7 +79,7 @@ static void spawn_haproxy(char **pid_strv, int nb_pid) } } -static int read_pids(char ***pid_strv) +static int read_pids(const char *pid_file, char ***pid_strv) { FILE *f = fopen(pid_file, "r"); int read = 0, allocated = 8; @@ -110,19 +107,19 @@ static void signal_handler(int signum) caught_signal = signum; } -static void do_restart(void) +static void do_restart(char *const *argv) { setenv(REEXEC_FLAG, "1", 1); fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: re-executing\n"); - execv(wrapper_argv[0], wrapper_argv); + execv(argv[0], argv); } -static void do_shutdown(void) +static void do_shutdown(const char *pid_file) { int i, pid; char **pid_strv = NULL; - int nb_pid = read_pids(&pid_strv); + int nb_pid = read_pids(pid_file, &pid_strv); for (i = 0; i < nb_pid; ++i) { pid = atoi(pid_strv[i]); if (pid > 0) { @@ -134,25 +131,22 @@ static void do_shutdown(void) free(pid_strv); } -static void init(int argc, char **argv) +static char* get_pid_file(int argc, char **argv) { + char *pid_file = DEFAULT_PID_FILE; while (argc > 1) { if ((*argv)[0] == '-' && (*argv)[1] == 'p') { pid_file = *(argv + 1); } --argc; ++argv; } + return pid_file; } int main(int argc, char **argv) { int status; - - wrapper_argc = argc; - wrapper_argv = argv; - - --argc; ++argv; - init(argc, argv); + char *pid_file = get_pid_file(argc, argv); struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); @@ -163,30 +157,30 @@ int main(int argc, char **argv) if (getenv(REEXEC_FLAG) != NULL) { /* We are being re-executed: restart HAProxy gracefully */ int i; - char **pid_strv = NULL; - int nb_pid = read_pids(&pid_strv); + char **pidv = NULL; + int pidc = read_pids(pid_file, &pidv); unsetenv(REEXEC_FLAG); - spawn_haproxy(pid_strv, nb_pid); + spawn_haproxy(argc, argv, pidc, pidv); - for (i = 0; i < nb_pid; ++i) - free(pid_strv[i]); - free(pid_strv); + for (i = 0; i < pidc; ++i) + free(pidv[i]); + free(pidv); } else { /* Start a fresh copy of HAProxy */ - spawn_haproxy(NULL, 0); + spawn_haproxy(argc, argv, 0, NULL); } status = -1; while (-1 != wait(&status) || errno == EINTR) { if (caught_signal == SIGUSR2) { caught_signal = 0; - do_restart(); + do_restart(argv); } else if (caught_signal == SIGINT) { caught_signal = 0; - do_shutdown(); + do_shutdown(pid_file);
Re: tracking multiple samples in stick-table
2014-08-18 18:49 GMT+02:00 Emeric Brun : > On 08/18/2014 05:49 PM, Baptiste wrote: >> >> On Sun, Aug 17, 2014 at 4:49 PM, bjun...@gmail.com >> wrote: >>> >>> Hi, >>> >>> i was digging through some old threads: >>> >>> >>> http://t53814.web-haproxy.webtalks.info/help-with-tcp-request-content-track-sc1-t53814.html >>> http://marc.info/?l=haproxy&m=139458469126719&w=2 >>> >>> >>> I have the same requirement and want to track not only on src (source >>> ip), i want to concatenate src + hdr(User-Agent) or hdr(User-Agent) + >>> hdr(X-Forward-For). >>> >>> >>> >>> Is there a way to actually do this ? (maybe it could be hashed, like >>> it is possible with "base32+src" ?) >>> >>> >>> Thanks, >>> >>> --- >>> Bjoern >>> >> >> >> Hi Bjoern, >> >> There is no way to do this currently in HAProxy. >> >> Baptiste >> > > > Hi All, > > I think it is possible: > > You need to add a new header to the request, with a concat of these > different values ("http-request add-header" and use log format to create the > value). > > And use the fetch on this header on the stickin rule. > > Regards, > Emeric > > > > > Hi, i've tried the following config, but HAProxy isn't tracking anything : frontend http_in_01 bind 0.0.0.0:80 log global option httplog reqidel ^X-Forwarded-For:.* option forwardfor option http-server-close # http-request set-header X-Concat %[req.fhdr(User-Agent)]_%[req.fhdr(X-Forwarded-For,-1)] http-request set-header X-Concat %[req.fhdr(User-Agent)]_%[src] # stick-table type binary len 180 size 32m expire 1m store http_req_rate(10s) stick-table type string len 180 size 32m expire 1m store http_req_rate(10s) tcp-request inspect-delay 10s tcp-request content track-sc0 req.fhdr(X-Concat) if HTTP unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid unique-id-header X-Unique-ID # acl is_found req.hdr(X-Concat) -m sub Firefox # http-request set-header X-Found yes if is_found Example "X-Concat"-Header: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0_192.168.138.185 Does anyone have any ideas why HAProxy isn't tracking anything or if my config is wrong ? --- Bjoern
Re: Connect to SNI-only server (haproxy as a client)
On Mon, Aug 18, 2014 at 05:46:14PM +0200, Baptiste wrote: > On Mon, Aug 18, 2014 at 2:40 PM, Willy Tarreau wrote: > > Hi Benedikt, > > > > On Mon, Aug 18, 2014 at 10:17:02AM +0200, Benedikt Fraunhofer wrote: > >> Hello List, > >> > >> I'm trying to help an java6-app that can't connect to a server which > >> seems to support SNI-only. > >> > >> I thought I could just add some frontend and backend stancas > >> and include the sni-only server as a server in the backend-section like so: > >> > >>server a 1.2.3.4:443 ssl verify none force-tlsv12 > >> > >> (I had verify set, just removed it to keep it simple and rule it out) > >> > >> But it seems the server in question insists on SNI, whatever force-* I > >> use and the connection is tcp-reset by the server (a) right after the > >> Client-Hello from haproxy. > >> > >> Is there a way to specify the "TLS SNI field" haproxy should use for > >> these outgoing connections? > > > > Not yet. We identified multiple needs for this field which a single > > constant in the configuration will not solve. While some users will > > only need a constant value (which seems to be your case), others > > need to forward the SNI they got on the other side, or to build one > > from a Host header field. > > > > So it's likely that we'll end up with a sample expression instead of > > a constant. Additionally that means that for health checks we need an > > extra setting (likely a constant this time). > > > > But for now, the whole solution is not designed yet, let alone implented. > > Btw is this something you're actively looking at, to design/implement? People on the list should be able to provide feedback about the planned expression to set the SNI field for client connections.. > > regards, > > Willy > > > > Hi, > > Microsoft Lync seems to have the same requirement for SNI... > We need it in both traffic and health checks. > OK, good to know. Thanks, -- Pasi > Baptiste >
Re: Application Persistence with WebSockets
Hi Ryan, > I recently started investigating using HAProxy to ensure that multiple > WebSocket connections from the same browser (or device) end up > communicating with the same application server. Forwarding all > connections from the same origin to the respective application server > greatly reduces the complexity on the application. > > My setup is simple: 1 HAProxy in front, 2 App servers on the back. The > browser makes several connections via WebSockets (using ws:// or > wss://). My goal is to have those connections all go to the same app > server. When a new browser is opened on another PC or device then those > will go to the other server (round-robin), etc. > > HAProxy was easy enough to configure and I decided to use the cookie > injection persistence method rather than URL parameter, HTTP header > field, or cookie modification (e.g. JSESSIONID) since it seemed the > most transparent and straightforward. However, I noticed it wasn't > forwarding the subsequent WebSocket connections to the same application > server. I started to sniff the packets to see what the HTTP response > from HAProxy looked like and found that the cookie wasn't present. I > did notice, however, that the cookie was present with non-WebSocket > HTTP responses. This led me to the source code proto_http.c to see if > there was any code that treated WebSocket handshakes differently. > Nothing really stood out. However, I did notice that around line 6305 > there is a check for status codes less than 200. In the event that the > status code is less than 200 it skips the header mangling. Note that > WebSocket HTTP responses are usually '101 Switching Protocols'. This > means that the initial response from the application server will not > have the cookie injected into the response via HAProxy. If I comment > out the goto, things work as I would expect. > > My question is, is this line really necessary? I understand that the > HTTP RFC indicates that for 1xx responses that the following header > fields are optional, but does that mean that the injection should not > be done? What if I were to update the code so that it was a little more > stateful and WebSocket aware so that in the event that the > request/response was WebSockets it would perform the header mangling? Yes, I wonder if we need this condition at all. Since commit 628c40cd961d ("MEDIUM: http: move skipping of 100-continue earlier") a "100 continue" response doesn't even make it to that condition. Webdav has a "102 Processing" response, but I doubt it would do harm it if we would add response headers or cookies there. Of course, to keep the change minimal we could just make an exception for 101. Note that the same issue applies to the add-response headers feature, with the same condition just some 20 lines above this one. For example, if we would like to enable HSTS but only use HTTP to upgrade to WS, haproxy would never be able to send the hsts header. Willy, whats your opinion on this, is there a reason to keep the condition and make an exception for status 101, or should we remove the check entirely? Regards, Lukas
number of usable servers
Hello! nbsrv() return the number of usable servers for the backend *excluding* servers marked as "backup". Is there any way to get the number of usable servers for the backend *including* backup ones? Thanks!
Uneven distribution by haproxy
Hi We've been using haproxy for load balancing on Amazon ec2 instances across two different Amazon zones in the same region. But we are observing a strange phenomena. The servers in the same zone as haproxy are giving less throughput as compared to the servers in the other zone. Though the throughput should be same if haproxy is working on perfect round robin strategy. We are not using any weights for distributing the load, and it should be perfect round robin. But still we are getting different throughput on servers located in different zones. Can someone please elaborate this haproxy behavior? Thanks Himanshu Sahu
Application Persistence with WebSockets
I recently started investigating using HAProxy to ensure that multiple WebSocket connections from the same browser (or device) end up communicating with the same application server. Forwarding all connections from the same origin to the respective application server greatly reduces the complexity on the application. My setup is simple: 1 HAProxy in front, 2 App servers on the back. The browser makes several connections via WebSockets (using ws:// or wss://). My goal is to have those connections all go to the same app server. When a new browser is opened on another PC or device then those will go to the other server (round-robin), etc. HAProxy was easy enough to configure and I decided to use the cookie injection persistence method rather than URL parameter, HTTP header field, or cookie modification (e.g. JSESSIONID) since it seemed the most transparent and straightforward. However, I noticed it wasn't forwarding the subsequent WebSocket connections to the same application server. I started to sniff the packets to see what the HTTP response from HAProxy looked like and found that the cookie wasn't present. I did notice, however, that the cookie was present with non-WebSocket HTTP responses. This led me to the source code proto_http.c to see if there was any code that treated WebSocket handshakes differently. Nothing really stood out. However, I did notice that around line 6305 there is a check for status codes less than 200. In the event that the status code is less than 200 it skips the header mangling. Note that WebSocket HTTP responses are usually '101 Switching Protocols'. This means that the initial response from the application server will not have the cookie injected into the response via HAProxy. If I comment out the goto, things work as I would expect. My question is, is this line really necessary? I understand that the HTTP RFC indicates that for 1xx responses that the following header fields are optional, but does that mean that the injection should not be done? What if I were to update the code so that it was a little more stateful and WebSocket aware so that in the event that the request/response was WebSockets it would perform the header mangling? Just as an aside, I did try the URL parameter method, and if I have the browsers ws:// connection use a URL parameter things appear to work. That may have to be my backup option, but it isn't as attractive given that I have to modify the clients to use additional parameters and make sure they are random or unique values. Again, it is an option, but not my first choice. I suspect HTTP header field based persistence would work similar to the URL parameter method. Note that IP-based persistence isn't attractive because most addresses will be NAT'd and look as though they come from the same address. I am looking for some guidance and some history on this logic. Is this code something that should be re-evaluated with the newer WebSocket protocol gaining popularity? Here is my configuration: global log 127.0.0.1 local0 debug maxconn 4096 #debug #quiet user haproxy group haproxy defaults log global modehttp retries 3 timeout client 50s timeout connect 5s timeout server 50s option dontlognull option httplog option redispatch option logasap option http-server-close balance roundrobin # Set up application listeners here. listen admin bind 0.0.0.0:22002 mode http stats uri / frontend http maxconn 2000 bind 0.0.0.0:8080 default_backend servers-http capture cookie SSNID len 63 backend servers-http cookie SSNID insert nocache server 03PM1 127.0.0.1:8081 cookie 03PM1 check server 03PM2 127.0.0.1:8082 cookie 03PM2 check Here is the code I am referring to in proto_http.c: /* OK that's all we can do for 1xx responses */ if (unlikely(txn->status < 200)) goto skip_header_mangling;
Afacerea ta - pe prima pagina de rezultate Google!
Use this area to offer a short teaser of your email's content. Text here will show in the content preview area of some email clients. Email not displaying correctly? View it in your browser ( *%7CARCHIVE%7C* ). www.eStores.ro ( http://www.estores.ro ) *** Alege cea mai buna solutie pentru promovarea afacerii tale! *** *** Profita acum de oferta noastra! *** Vrei ca site-ul tau sa fie pe prima pagina de rezultate GOOGLE? Vrei ca afacerea ta sa fie mai prospera? Noi sustinem promovarea afacerii tale, in mediul online, de aceea in perioada 21.08 - 20.09.2014 acordam o reducere de 30 % pentru dezvoltare unui Site de Prezentare ( http://estores.ro/ro/site-prezentare.html ), Magazin Online ( http://estores.ro/ro/magazin-online.html ) sau Optimizare SEO ( http://estores.ro/ro/optimizare-seo.html ) - - ( http://estores.ro/ro/ ) Site de prezentare: ( http://estores.ro/ro/site-prezentare.html ) - Astazi internetul a devenit un instrument indispensabil de promovare. De acea, imaginea companiei dumneavoastra este esentiala, ea poate atrage clienti sau din contra, ii poate orienta catre competitie. Noi venim in intimpinarea dvs cu : -- Design unic si original; Grafica web complet personalizata; Structura website cu 2-5 varinte lingvistice; Panou de administrare al continutului ce permite: Crearea/ modificarea unui numar nelimitat de pagini Administrarea imaginilor din galeria foto Inserarea/ modificare butoanelor din meniul secundar Formular de contact Statistici vizitatori. Altii s-au convins deja… http://practicata.ro/ ( http://practicata.ro/ ) http://www.jurnaluldeafaceri.ro/ ( http://www.jurnaluldeafaceri.ro/ ) http://spoons.ro/ ( http://spoons.ro/ ) Optimizare SEO : ( http://estores.ro/ro/optimizare-seo.html ) - Search Engine Optimization ( http://estores.ro/ro/optimizare-seo.html ) este un complex de tehnici, menit sa ajute la obtinerea unor rezultate mai bune in motoarele de cautare, avand ca si rezultat obtinerea unei pozitionari cat mai avantajoase in motoarele de cautare: GOOGLE, YAHOO, BING etc. Scopul SEO este un trafic crescut rezultat din urma unor cautari organice. - Caracteristici: Optimizare pe Brand Marketing-ul site-ului; Numar nelimitat de cuvinte cheie; Implementarea etichetelor Meta completa; Analiza concurentei; Optimizarea navigarii, imaginilor si linkurilor din site; Rezolvarea problemelor de HTML si CSS + Viteza de incarcare; Inscriere manuala in directoare WEB Romanesti si Straine; Creare profiluri Twitter, Facebook si LinkedIn. http://www.inforegio.ro/ro/ http://www.jaluzele-ieftine.ro ( http://www.jaluzele-ieftine.ro ) http://www.gliacenter.ro/ - Magazin online: ( http://estores.ro/ro/magazin-online.html ) Comertul electronic nu are frontiera pentru lumea afacerilor, deoarece ofera oportunitatea de a castiga mai multi clienti si de a comunica strans cu acestia. Pe internet fiecare afacere este disponibila non-stop si indiferent de dimensiunea acesteia, isi poate castiga clienti importanti din intreaga lume. Nu ai nevoie de angajati pentru acesta. Noi va punem la dispozitie: - Design complet personalizat; - Sincronizare cu sistemul de gestiune; - Sistem de inregistrare personalizat pentru clienti; - Numar nelimitat de imagini / produs. - Garantam ca platesti doar pe masura rezultatelor. Vizitati portofoliu web si va veti convinge… - http://redzip.ro/ ( http://redzip.ro/ ) http://www.brandsdiscounts.ro/ ( http://www.brandsdiscounts.ro/ ) http://www.lovelylauren.ro/ ( http://estores.ro/ro/portofoliu.html ) Ing Iulian Pop Mobil: 0720031123 Tel/Fax: 0362 404 903 E-mail: iulian@holisun.r ( mailto:iulian@holisun.com )o Website: www.estores.ro.com ( http://client.campaign%0D%0A%20sender.ro/tl.php?p=34r/rs/rs/rt/1gg/rt//http%3A%2F%2Fwww.holisun.com ) Adres: str Carbunari, nr 8 unsubscribe from this list ( *%7CUNSUB%7C* ) | update subscription preferences ( *%7CUPDATE_PROFILE%7C* )