There are some assumptions in spamd-setup that are likely to be
false.
1) If you have a large number of IP addresses without a netmask
(common) then the assumption of one IP for every 16 bytes in
black/whitelist files will be wrong. One IP for every 14 bytes
seems closer in practice.
2) If you have whitelist entries that chop up the nice cidr
blocks then the cidr list can get reallocated many times.
Allocating an extra 10% reduces the need to realloc, though
perhaps increasing the realloc increment would be good too.
- todd
Index: spamd-setup.c
===================================================================
RCS file: /cvs/src/libexec/spamd-setup/spamd-setup.c,v
retrieving revision 1.42
diff -u -r1.42 spamd-setup.c
--- spamd-setup.c 14 Jan 2015 11:59:10 -0000 1.42
+++ spamd-setup.c 14 Jan 2015 11:59:22 -0000
@@ -478,12 +478,12 @@
}
parse:
start = 0;
- /* we assume that there is an IP for every 16 bytes */
- if (*blc + bu / 8 >= *bls) {
- *bls += bu / 8;
+ /* we assume that there is an IP for every 14 bytes */
+ if (*blc + bu / 7 >= *bls) {
+ *bls += bu / 7;
blt = reallocarray(bl, *bls, sizeof(struct bl));
if (blt == NULL) {
- *bls -= bu / 8;
+ *bls -= bu / 7;
serrno = errno;
goto bldone;
}
@@ -546,12 +546,16 @@
if (blc == 0)
return (NULL);
+
+ /*
+ * Overallocate by 10% to avoid excessive realloc due to white
+ * entries splitting up CIDR blocks.
+ */
cli = 0;
- cls = (blc / 2) + 1;
- cl = calloc(cls, sizeof(struct cidr));
- if (cl == NULL) {
+ cls = (blc / 2) + (blc / 20) + 1;
+ cl = reallocarray(NULL, cls, sizeof(struct cidr));
+ if (cl == NULL)
return (NULL);
- }
qsort(bl, blc, sizeof(struct bl), cmpbl);
for (i = 0; i < blc;) {
laststate = state;