diff -ur inn-2.5.2/innd/chan.c inn-2.5.2-wipgroup/innd/chan.c --- inn-2.5.2/innd/chan.c 2010-03-24 21:10:36.000000000 +0100 +++ inn-2.5.2-wipgroup/innd/chan.c 2011-04-10 21:52:09.000000000 +0200 @@ -200,6 +200,8 @@ cp->In = in; cp->Out = out; cp->Tracing = Tracing; + cp->WIPGroup = 1; + cp->WIPMask = ~0L; HashClear(&cp->CurrentMessageIDHash); ARTprepare(cp); diff -ur inn-2.5.2/innd/innd.h inn-2.5.2-wipgroup/innd/innd.h --- inn-2.5.2/innd/innd.h 2010-03-24 21:10:36.000000000 +0100 +++ inn-2.5.2-wipgroup/innd/innd.h 2011-04-10 21:49:36.000000000 +0200 @@ -395,6 +395,8 @@ HASH CurrentMessageIDHash; struct _WIP * PrecommitWIP[PRECOMMITCACHESIZE]; int PrecommitiCachenext; + long WIPGroup; + long WIPMask; int XBatchSize; int LargeArtSize; int LargeCmdSize; @@ -564,6 +566,7 @@ time_t Timestamp; /* Time we last looked at this MessageID */ CHANNEL *Chan; /* Channel that this message is associated with */ + long WIPGroup; struct _WIP *Next; /* Next item in this bucket */ } WIP; diff -ur inn-2.5.2/innd/rc.c inn-2.5.2-wipgroup/innd/rc.c --- inn-2.5.2/innd/rc.c 2010-03-24 21:10:36.000000000 +0100 +++ inn-2.5.2-wipgroup/innd/rc.c 2011-04-10 21:54:29.000000000 +0200 @@ -47,6 +47,8 @@ char *Comment; /* Commentary [max size = MAXBUFF] */ int HoldTime; /* Hold time before disconnect over MaxCnx */ int Keysetbit; /* Bit to check duplicated key */ + long WIPGroup; + long WIPMask; } REMOTEHOST; typedef struct _REMOTEHOST_DATA { @@ -85,11 +87,13 @@ #define NORESENDID "noresendid:" #define HOLD_TIME "hold-time:" #define NOLIST "nolist:" +#define WIPGROUP "wipgroup:" +#define WIPMASK "wipmask:" typedef enum {K_END, K_BEGIN_PEER, K_BEGIN_GROUP, K_END_PEER, K_END_GROUP, K_STREAM, K_HOSTNAME, K_MAX_CONN, K_PASSWORD, K_IDENTD, K_EMAIL, K_PATTERNS, K_COMMENT, K_SKIP, K_IGNORE, K_NORESENDID, - K_HOLD_TIME, K_NOLIST + K_HOLD_TIME, K_NOLIST, K_WIPGROUP, K_WIPMASK } _Keywords; typedef enum {T_STRING, T_BOOLEAN, T_INTEGER} _Types; @@ -582,6 +586,8 @@ new->CanAuthenticate = true; /* Can use AUTHINFO. */ new->MaxCnx = rp->MaxCnx; new->HoldTime = rp->HoldTime; + new->WIPGroup = rp->WIPGroup; + new->WIPMask = rp->WIPMask; memcpy(&new->Address, &remote, sizeof(new->Address)); if (new->MaxCnx > 0 && new->HoldTime == 0) { CHANcount_active(new); @@ -841,6 +847,8 @@ rp->NoResendId = false; rp->Nolist = false; rp->HoldTime = 0; + rp->WIPGroup = 1; + rp->WIPMask = ~0L; rp++; (*count)++; #endif /* !defined(HAVE_UNIX_DOMAIN_SOCKETS) */ @@ -862,6 +870,8 @@ default_params.Email = xstrdup(NOEMAIL); default_params.Comment = xstrdup(NOCOMMENT); default_params.Pattern = NULL; + default_params.WIPGroup = 1; + default_params.WIPMask = ~0L; peer_params.Keysetbit = 0; /* Read the file to add all the hosts. */ @@ -916,6 +926,10 @@ groups[groupcount - 2].MaxCnx : default_params.MaxCnx; group_params->HoldTime = groupcount > 1 ? groups[groupcount - 2].HoldTime : default_params.HoldTime; + group_params->WIPGroup = groupcount > 1 ? + groups[groupcount - 2].WIPGroup : default_params.WIPGroup; + group_params->WIPMask = groupcount > 1 ? + groups[groupcount - 2].WIPMask : default_params.WIPMask; if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) { syslog(L_ERROR, LEFT_BRACE, LogName, filename, linecount); @@ -975,6 +989,10 @@ group_params->MaxCnx : default_params.MaxCnx; peer_params.HoldTime = groupcount > 0 ? group_params->HoldTime : default_params.HoldTime; + peer_params.WIPGroup = groupcount > 0 ? + group_params->WIPGroup : default_params.WIPGroup; + peer_params.WIPMask = groupcount > 0 ? + group_params->WIPMask : default_params.WIPMask; peer_params.Keysetbit = 0; @@ -1053,6 +1071,8 @@ RCCommaSplit(xstrdup(peer_params.Pattern)) : NULL; rp->MaxCnx = peer_params.MaxCnx; rp->HoldTime = peer_params.HoldTime; + rp->WIPGroup = peer_params.WIPGroup; + rp->WIPMask = peer_params.WIPMask; rp++; } freeaddrinfo(res0); @@ -1301,6 +1321,62 @@ continue; } + /* wipgroup */ + if (!strncmp (word, WIPGROUP, sizeof WIPGROUP)) { + free(word); + TEST_CONFIG(K_WIPGROUP, bit); + if (bit) { + syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount); + break; + } + if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) { + break; + } + RCadddata(data, &infocount, K_WIPGROUP, T_STRING, word); + for (p = word; (isdigit((unsigned char) *p) || (*p == '-' && p == word)) && *p != '\0'; p++); + if (*p != '\0') { + syslog(L_ERROR, MUST_BE_INT, LogName, filename, linecount); + break; + } + if (peer_params.Label != NULL) + peer_params.WIPGroup = atol(word); + else + if (groupcount > 0 && group_params->Label != NULL) + group_params->WIPGroup = atol(word); + else + default_params.WIPGroup = atol(word); + SET_CONFIG(K_WIPGROUP); + continue; + } + + /* wipmask */ + if (!strncmp (word, WIPMASK, sizeof WIPMASK)) { + free(word); + TEST_CONFIG(K_WIPMASK, bit); + if (bit) { + syslog(L_ERROR, DUPLICATE_KEY, LogName, filename, linecount); + break; + } + if ((word = RCreaddata (&linecount, F, &toolong)) == NULL) { + break; + } + RCadddata(data, &infocount, K_WIPMASK, T_STRING, word); + for (p = word; (isdigit((unsigned char) *p) || (*p == '-' && p == word)) && *p != '\0'; p++); + if (*p != '\0') { + syslog(L_ERROR, MUST_BE_INT, LogName, filename, linecount); + break; + } + if (peer_params.Label != NULL) + peer_params.WIPMask = ~(atol(word)); + else + if (groupcount > 0 && group_params->Label != NULL) + group_params->WIPMask = ~(atol(word)); + else + default_params.WIPMask = ~(atol(word)); + SET_CONFIG(K_WIPMASK); + continue; + } + /* hostname */ if (!strncmp (word, HOSTNAME, sizeof HOSTNAME)) { free(word); @@ -1596,6 +1672,18 @@ RCwritelistvalue (F, RCpeerlistfile[i].value); fputc ('\n', F); break; + case K_WIPGROUP: + RCwritelistindent (F, inc); + fprintf(F, "%s\t", WIPGROUP); + RCwritelistvalue (F, RCpeerlistfile[i].value); + fputc ('\n', F); + break; + case K_WIPMASK: + RCwritelistindent (F, inc); + fprintf(F, "%s\t", WIPMASK); + RCwritelistvalue (F, RCpeerlistfile[i].value); + fputc ('\n', F); + break; case K_PASSWORD: RCwritelistindent (F, inc); fprintf(F, "%s\t", PASSWORD); diff -ur inn-2.5.2/innd/wip.c inn-2.5.2-wipgroup/innd/wip.c --- inn-2.5.2/innd/wip.c 2010-03-24 21:10:36.000000000 +0100 +++ inn-2.5.2-wipgroup/innd/wip.c 2011-04-10 21:46:50.000000000 +0200 @@ -41,6 +41,11 @@ new->MessageID = hash; new->Timestamp = Now.tv_sec; new->Chan = cp; + if (cp != NULL) { + new->WIPGroup = cp->WIPGroup; + } else { + new->WIPGroup = 1; + } /* Link the new entry into the list */ new->Next = WIPtable[bucket]; WIPtable[bucket] = new; @@ -117,8 +122,11 @@ i = WIP_ARTMAX; } - if ((Now.tv_sec - wp->Timestamp) < (time_t) (i + innconf->wipcheck)) - return true; + if (((Now.tv_sec - wp->Timestamp) < (time_t) (i + innconf->wipcheck)) && + (wp->WIPGroup & cp->WIPMask)) { + return true; + } + wp->WIPGroup = wp->WIPGroup | cp->WIPGroup; if ((Now.tv_sec - wp->Timestamp) > (time_t) (i + innconf->wipexpire)) { for (i = 0 ; i < PRECOMMITCACHESIZE ; i++) { if (wp->Chan->PrecommitWIP[i] == wp) {