diff --git a/main.c b/main.c index c01b20d..cf46562 100644 --- a/main.c +++ b/main.c @@ -91,6 +91,55 @@ static void filters_init() #endif } +#ifdef INTFILTER +// o - old filter, n - new +// return -1 - old stays, 0 - no conflict, 1 - new overrides old +// assumes masked bits are cleared already +static inline int ifilter_conflict(struct intfilter *o,struct intfilter *n) +{ + if ((o->f & n->m) != (n->f & o->m)) + return 0; + // determine which filter contain less bits + // this shit needs code independent of endianess, so not direct <= + if (memcmp(&o->m,&n->m,sizeof(o->m)) <= 0) + return -1; + return 1; +} +#else +// o - old filter, n - new +// return: -1 - old stays, 0 - no conflict, 1 - new overrides old +// assumes irrelevant bits are cleared already +static inline int bfilter_conflict(struct binfilter *o,struct binfilter *n) +{ + for (size_t i = 0;i < sizeof(o->f);++i) { + u8 oo,nn; + if (i < n->len) + oo = o->f[i]; + else if (i == n->len) + oo = o->f[i] & n->mask; + else + oo = 0; + if (i < o->len) + nn = n->f[i]; + else if (i == o->len) + nn = n->f[i] & o->mask; + else + nn = 0; + if (oo != nn) + return 0; + } + // functional filters subset was the same + // determine which filter contain less bits + if (o->len < n->len) + return -1; + if (o->len > n->len) + return 1; + if (o->mask <= n->mask) + return -1; + return 1; +} +#endif + static void filters_add(const char *filter) { struct binfilter bf; @@ -102,6 +151,8 @@ static void filters_add(const char *filter) } fc,mc; #endif + memset(&bf,0,sizeof(bf)); + if (!base32_valid(filter,&ret)) { fprintf(stderr, "filter \"%s\" is invalid\n", filter); return; @@ -120,7 +171,6 @@ static void filters_add(const char *filter) } ret2 = base32_from(bf.f,&bf.mask,filter); assert(ret == ret2); - //printf("--m:%02X\n", bf.mask); bf.len = ret - 1; #ifdef INTFILTER mc.i = 0; @@ -129,9 +179,29 @@ static void filters_add(const char *filter) mc.b[bf.len] = bf.mask; memcpy(fc.b,bf.f,8); fc.i &= mc.i; - struct intfilter ifltr = {fc.i,mc.i}; + struct intfilter ifltr = {.f = fc.i,.m = mc.i}; + VEC_FOR(ifilters,i) { + int c = ifilter_conflict(&VEC_BUF(ifilters,i),&ifltr); + if (c < 0) + return; // old filter eats us + else if (c > 0) { + VEC_REMOVE(ifilters,i); + --i; + // we eat old filter + } + } VEC_ADD(ifilters,ifltr); #else + VEC_FOR(bfilters,i) { + int c = bfilter_conflict(&VEC_BUF(bfilters,i),&bf); + if (c < 0) + return; // old filter eats us + else if (c > 0) { + VEC_REMOVE(bfilters,i); + --i; + // we eat old filter + } + } VEC_ADD(bfilters,bf); #endif } @@ -721,14 +791,14 @@ int main(int argc,char **argv) signal(SIGINT,termhandler); VEC_INIT(threads); - VEC_ADDN(threads,pthread_t,numthreads); + VEC_ADDN(threads,numthreads); #ifdef STATISTICS VEC_INIT(stats); + VEC_ADDN(stats,numthreads); + VEC_ZERO(stats); VEC_INIT(tstats); - VEC_ADDN(stats,struct statstruct,numthreads); - VEC_ADDN(tstats,struct tstatstruct,numthreads); - memset(&VEC_BUF(stats,0),0,sizeof(struct statstruct) * VEC_LENGTH(stats)); - memset(&VEC_BUF(tstats,0),0,sizeof(struct tstatstruct) * VEC_LENGTH(tstats)); + VEC_ADDN(tstats,numthreads); + VEC_ZERO(tstats); #endif for (size_t i = 0;i < VEC_LENGTH(threads);++i) { diff --git a/vec.h b/vec.h index f7d0631..64477e7 100644 --- a/vec.h +++ b/vec.h @@ -1,38 +1,74 @@ -#define VEC_STRUCT(typename, inttype) \ +#define VEC_STRUCT(typename,inttype) \ struct typename { \ inttype *buf; \ size_t len, alen; \ } -#define VEC_INIT(ctl) memset(&ctl, 0, sizeof(ctl)) +#define VEC_INIT(ctl) memset(&ctl,0,sizeof(ctl)) -#define VEC_ADD(ctl, val) { \ +#define VEC_ADD1(ctl) { \ if (!(ctl).alen) { \ (ctl).alen = 8; \ - (ctl).buf = malloc(8 * sizeof(val)); \ + (ctl).buf = malloc(8 * sizeof(*(ctl).buf)); \ } else if ((ctl).len >= (ctl).alen) { \ (ctl).alen *= 2; \ - (ctl).buf = realloc((ctl).buf, (ctl).alen * sizeof(val)); \ + (ctl).buf = realloc((ctl).buf,(ctl).alen * sizeof(*(ctl).buf)); \ } \ - (ctl).buf[(ctl).len++] = val; \ + ++(ctl).len; \ } -#define VEC_ADDN(ctl, valt, n) { \ +#define VEC_ADD(ctl,val) { \ if (!(ctl).alen) { \ (ctl).alen = 8; \ - (ctl).buf = malloc(8 * sizeof(valt)); \ + (ctl).buf = malloc(8 * sizeof(*(ctl).buf)); \ + } else if ((ctl).len >= (ctl).alen) { \ + (ctl).alen *= 2; \ + (ctl).buf = realloc((ctl).buf,(ctl).alen * sizeof(*(ctl).buf)); \ + } \ + (ctl).buf[(ctl).len++] = (val); \ +} + +#define VEC_ADDN(ctl,n) { \ + if (!(ctl).alen) { \ + (ctl).alen = 8; \ + (ctl).buf = malloc(8 * sizeof(*(ctl).buf)); \ } \ size_t nlen = (ctl).alen; \ while ((ctl).len + n > nlen) \ nlen *= 2; \ if (nlen > (ctl).alen) { \ (ctl).alen = nlen; \ - (ctl).buf = realloc((ctl).buf, nlen * sizeof(valt)); \ + (ctl).buf = realloc((ctl).buf,nlen * sizeof(*(ctl).buf)); \ } \ (ctl).len += n; \ } -#define VEC_FREE(ctl) { free((ctl).buf); memset(&(ctl), 0, sizeof((ctl))); } +#define VEC_REMOVE(ctl,n) { \ + --(ctl).len; \ + memmove( \ + &(ctl).buf[(n) * sizeof(*(ctl).buf)], \ + &(ctl).buf[(n + 1) * sizeof(*(ctl).buf)], \ + ((ctl).len - (n)) * sizeof(*(ctl).buf)); \ +} + +#define VEC_INSERT(ctl,n,val) { \ + VEC_ADD1(ctl); \ + memmove( \ + &(ctl).buf[(n + 1) * sizeof(*(ctl).buf)], \ + &(ctl).buf[(n) * sizeof(*(ctl).buf)], \ + ((ctl).len - (n) - 1) * sizeof(*(ctl).buf)); \ + (ctl).buf[n] = (val); \ +} + +#define VEC_ZERO(ctl) \ + memset((ctl).buf,0,(ctl).len * sizeof(*(ctl).buf)) + +#define VEC_FREE(ctl) { \ + free((ctl).buf); \ + memset(&(ctl), 0, sizeof((ctl))); \ +} #define VEC_LENGTH(ctl) ((ctl).len) -#define VEC_BUF(ctl, num) ((ctl).buf[num]) +#define VEC_BUF(ctl,num) ((ctl).buf[num]) + +#define VEC_FOR(ctl,it) for (size_t it = 0;it < VEC_LENGTH((ctl));++it)