diff -urN inn-2.5.1/innd/chan.c inn-2.5.1-wipgroup/innd/chan.c --- inn-2.5.1/innd/chan.c 2009-10-12 20:24:04.000000000 +0200 +++ inn-2.5.1-wipgroup/innd/chan.c 2009-11-10 03:20:10.000000000 +0100 @@ -198,6 +198,8 @@ cp->In = in; cp->Out = out; cp->Tracing = Tracing; + cp->WIPGroup = 1; + cp->WIPMask = ~0L; HashClear(&cp->CurrentMessageIDHash); ARTprepare(cp); diff -urN inn-2.5.1/innd/innd.h inn-2.5.1-wipgroup/innd/innd.h --- inn-2.5.1/innd/innd.h 2009-10-12 20:24:04.000000000 +0200 +++ inn-2.5.1-wipgroup/innd/innd.h 2009-11-10 03:20:10.000000000 +0100 @@ -375,6 +375,8 @@ HASH CurrentMessageIDHash; struct _WIP * PrecommitWIP[PRECOMMITCACHESIZE]; int PrecommitiCachenext; + long WIPGroup; + long WIPMask; int XBatchSize; int LargeArtSize; int LargeCmdSize; @@ -543,6 +545,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 -urN inn-2.5.1/innd/rc.c inn-2.5.1-wipgroup/innd/rc.c --- inn-2.5.1/innd/rc.c 2009-10-12 20:24:04.000000000 +0200 +++ inn-2.5.1-wipgroup/innd/rc.c 2009-11-10 03:22:57.000000000 +0100 @@ -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; @@ -579,6 +583,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); @@ -836,6 +842,8 @@ rp->NoResendId = false; rp->Nolist = false; rp->HoldTime = 0; + rp->WIPGroup = 1; + rp->WIPMask = ~0L; rp++; (*count)++; #endif /* !defined(HAVE_UNIX_DOMAIN_SOCKETS) */ @@ -857,6 +865,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. */ @@ -911,6 +921,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); @@ -970,6 +984,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; @@ -1048,6 +1066,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); @@ -1296,6 +1316,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; (CTYPE(isdigit, *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; (CTYPE(isdigit, *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); @@ -1591,6 +1667,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 -urN inn-2.5.1/innd/wip.c inn-2.5.1-wipgroup/innd/wip.c --- inn-2.5.1/innd/wip.c 2009-10-12 20:24:04.000000000 +0200 +++ inn-2.5.1-wipgroup/innd/wip.c 2009-11-10 03:20:10.000000000 +0100 @@ -41,6 +41,7 @@ new->MessageID = hash; new->Timestamp = Now.tv_sec; new->Chan = cp; + new->WIPGroup = cp->WIPGroup; /* Link the new entry into the list */ new->Next = WIPtable[bucket]; WIPtable[bucket] = new; @@ -117,8 +118,12 @@ i = WIP_ARTMAX; } - if ((Now.tv_sec - wp->Timestamp) < (i + innconf->wipcheck)) - return true; + if ((Now.tv_sec - wp->Timestamp) < (i + innconf->wipcheck)) { + if (wp->WIPGroup & cp->WIPMask) + return true; + else + wp->WIPGroup = wp->WIPGroup | cp->WIPGroup; + } if ((Now.tv_sec - wp->Timestamp) > (i + innconf->wipexpire)) { for (i = 0 ; i < PRECOMMITCACHESIZE ; i++) { if (wp->Chan->PrecommitWIP[i] == wp) {