diff options
author | Pablo Neira <pablo@eurodev.net> | 2005-05-29 19:05:23 +0000 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2005-05-29 19:05:23 +0000 |
commit | dfdcd641085d22f7f911ca431db845590493c336 (patch) | |
tree | bad7a2205c28951d22fc32834e8618f7fd6e2eb2 /ip6tables.c | |
parent | 56506a10c3bc3e13134db607fd94b4f4067426f3 (diff) |
Release previously merged options from merge_opts(), reduces memory-usage of iptables-restore dramatically (Pablo Neira)
Diffstat (limited to 'ip6tables.c')
-rw-r--r-- | ip6tables.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/ip6tables.c b/ip6tables.c index cea72292..11d8cd16 100644 --- a/ip6tables.c +++ b/ip6tables.c @@ -252,6 +252,16 @@ in6addrcpy(struct in6_addr *dst, struct in6_addr *src) /* dst->s6_addr = src->s6_addr; */ } +static void free_opts(int reset_offset) +{ + if (opts != original_opts) { + free(opts); + opts = original_opts; + if (reset_offset) + global_option_offset = 0; + } +} + void exit_error(enum exittype status, char *msg, ...) { @@ -267,6 +277,8 @@ exit_error(enum exittype status, char *msg, ...) if (status == VERSION_PROBLEM) fprintf(stderr, "Perhaps ip6tables or your kernel needs to be upgraded.\n"); + /* On error paths, make sure that we don't leak memory */ + free_opts(1); exit(status); } @@ -277,6 +289,7 @@ exit_tryhelp(int status) fprintf(stderr, "Error occurred at line: %d\n", line); fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n", program_name, program_name ); + free_opts(1); exit(status); } @@ -1016,6 +1029,9 @@ merge_options(struct option *oldopts, const struct option *newopts, unsigned int num_old, num_new, i; struct option *merge; + /* Release previous options merged if any */ + free_opts(0); + for (num_old = 0; oldopts[num_old].name; num_old++); for (num_new = 0; newopts[num_new].name; num_new++); @@ -2336,11 +2352,7 @@ int do_command6(int argc, char *argv[], char **table, ip6tc_handle_t *handle) for (c = 0; c < ndaddrs; c++) free(&daddrs[c]); - if (opts != original_opts) { - free(opts); - opts = original_opts; - global_option_offset = 0; - } + free_opts(1); return ret; } |