]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] Fix memory freeing at exit, part 2
authorKrzysztof Piotr Oledzki <ole@ans.pl>
Sat, 31 May 2008 11:53:23 +0000 (13:53 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 7 Jun 2008 09:06:14 +0000 (11:06 +0200)
- free oldpids
- call free(exp->preg), not only regfree(exp->preg): req_exp, rsp_exp
- build a list of unique uri_auths and eventually free it
- prune_acl_cond/free for switching_rules
- add a callback pointer to free ptr from acl_pattern (used for regexs) and execute it

==1180== malloc/free: in use at exit: 0 bytes in 0 blocks.
==1180== malloc/free: 5,599 allocs, 5,599 frees, 4,220,556 bytes allocated.
==1180== All heap blocks were freed -- no leaks are possible.

include/common/uri_auth.h
include/types/acl.h
src/acl.c
src/haproxy.c

index fbbe7df8164df2c19ea00abbcbfc10d506adee9c..e52387c1deaaa3dad573c7c2381b94afde336851 100644 (file)
@@ -42,6 +42,7 @@ struct uri_auth {
        int flags;                      /* some flags describing the statistics page */
        struct user_auth *users;        /* linked list of valid user:passwd couples */
        struct stat_scope *scope;       /* linked list of authorized proxies */
+       struct uri_auth *next;          /* Used at deinit() to build a list of unique elements */
 };
 
 /* This is the default statistics URI */
index ef5be58dc0aa5bf61f428f167c244946c6bdad56..53f9e708b4e790bbf4a7c6839a944fe2b15d8f42 100644 (file)
@@ -101,6 +101,7 @@ struct acl_pattern {
                char *str;              /* any string  */
                regex_t *reg;           /* a compiled regex */
        } ptr;                          /* indirect values, allocated */
+       void(*freeptrbuf)(void *ptr);   /* a destructor able to free objects from the ptr */
        int len;                        /* data length when required  */
        int flags;                      /* expr or pattern flags. */
 };
index 96b21de42bf3e7d6bc86295ca8629b34fc23fe3c..02678f2d1fe599b06bcb3f73dea0b5b64fda97b8 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -285,6 +285,12 @@ int acl_parse_str(const char **text, struct acl_pattern *pattern, int *opaque)
        return 1;
 }
 
+/* Free data allocated by acl_parse_reg */
+static void acl_free_reg(void *ptr) {
+
+       regfree((regex_t *)ptr);
+}
+
 /* Parse a regex. It is allocated. */
 int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque)
 {
@@ -303,6 +309,7 @@ int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque)
        }
 
        pattern->ptr.reg = preg;
+       pattern->freeptrbuf = &acl_free_reg;
        return 1;
 }
 
@@ -452,8 +459,14 @@ struct acl_keyword *find_acl_kw(const char *kw)
 
 static void free_pattern(struct acl_pattern *pat)
 {
-       if (pat->ptr.ptr)
+
+       if (pat->ptr.ptr) {
+               if (pat->freeptrbuf)
+                       pat->freeptrbuf(pat->ptr.ptr);
+
                free(pat->ptr.ptr);
+       }
+
        free(pat);
 }
 
index 4b6bdf899a8b002230d40f9ed9cca80a1a3523ea..d52524f6bc466faf30f37c2c0456624320f96102 100644 (file)
@@ -647,8 +647,11 @@ void deinit(void)
        struct acl_cond *cond, *condb;
        struct hdr_exp *exp, *expb;
        struct acl *acl, *aclb;
+       struct switching_rule *rule, *ruleb;
+       struct uri_auth *uap, *ua = NULL;
+       struct user_auth *user;
        int i;
-  
+
        while (p) {
                if (p->id)
                        free(p->id);
@@ -699,8 +702,11 @@ void deinit(void)
                }
 
                for (exp = p->req_exp; exp != NULL; ) {
-                       if (exp->preg)
+                       if (exp->preg) {
                                regfree((regex_t *)exp->preg);
+                               free((regex_t *)exp->preg);
+                       }
+
                        if (exp->replace && exp->action != ACT_SETBE)
                                free((char *)exp->replace);
                        expb = exp;
@@ -709,8 +715,11 @@ void deinit(void)
                }
 
                for (exp = p->rsp_exp; exp != NULL; ) {
-                       if (exp->preg)
+                       if (exp->preg) {
                                regfree((regex_t *)exp->preg);
+                               free((regex_t *)exp->preg);
+                       }
+
                        if (exp->replace && exp->action != ACT_SETBE)
                                free((char *)exp->replace);
                        expb = exp;
@@ -718,9 +727,21 @@ void deinit(void)
                        free(expb);
                }
 
-               /* FIXME: this must also be freed :
-                *  - uri_auth (but it's shared)
-                */
+               /* build a list of unique uri_auths */
+               if (!ua)
+                       ua = p->uri_auth;
+               else {
+                       /* check if p->uri_auth is unique */
+                       for (uap = ua; uap; uap=uap->next)
+                               if (uap == p->uri_auth)
+                                       break;
+
+                       if (!uap) {
+                               /* add it, if it is */
+                               p->uri_auth->next = ua;
+                               ua = p->uri_auth;
+                       }
+               }
 
                list_for_each_entry_safe(acl, aclb, &p->acl, list) {
                        LIST_DEL(&acl->list);
@@ -728,6 +749,15 @@ void deinit(void)
                        free(acl);
                }
 
+               list_for_each_entry_safe(rule, ruleb, &p->switching_rules, list) {
+                       LIST_DEL(&rule->list);
+
+                       prune_acl_cond(rule->cond);
+                       free(rule->cond);
+
+                       free(rule);
+               }
+
                if (p->appsession_name)
                        free(p->appsession_name);
 
@@ -791,6 +821,27 @@ void deinit(void)
                free(p0);
        }/* end while(p) */
 
+       while (ua) {
+               uap = ua;
+               ua = ua->next;
+
+               if (uap->uri_prefix)
+                       free(uap->uri_prefix);
+
+               if (uap->auth_realm)
+                       free(uap->auth_realm);
+
+               while (uap->users) {
+                       user = uap->users;
+                       uap->users = uap->users->next;
+
+                       free(user->user_pwd);
+                       free(user);
+               }
+
+               free(uap);
+       }
+
        protocol_unbind_all();
 
        if (global.chroot)    free(global.chroot);
@@ -802,6 +853,9 @@ void deinit(void)
        if (fdtab)            free(fdtab);
        fdtab = NULL;
 
+       if (oldpids)
+               free(oldpids);
+
        pool_destroy2(pool2_session);
        pool_destroy2(pool2_buffer);
        pool_destroy2(pool2_requri);