PATCH: diablo style hashfeeds

Julien ÉLIE julien at trigofacile.com
Sun Mar 23 15:25:42 UTC 2008


Hi Miquel,

> +    md5_update(&context, MessageID, strlen(MessageID));

It should be:

    md5_update(&context, (unsigned char *)MessageID, strlen(MessageID));



> +static bool
> +HashFeedMatch(HASHFEEDLIST *hf, char *MessageID)
> +{
> +  unsigned char *p;
> +  unsigned int qhash;
> +  unsigned int h;
> +  int n;
> +
> +  /* Calculate old diablo (< 5.1) 32 bits quickhash */
> +  p = (unsigned char *)MessageID;
> +  n = 0;
> +  while (*p)
> +    n += *p++;
> +  qhash = n;
> +
> +  while (hf) {
> +    if (hf->type == HASHFEED_MD5)
> +      h = HashFeedMD5(MessageID, hf->offset);
> +    else if (hf->type == HASHFEED_QH)
> +      h = qhash;
> +    else
> +      continue;
> +    if ((h % hf->mod + 1) >= hf->begin &&
> +        (h % hf->mod + 1) <= hf->end)
> +   return true;
> +    hf = hf->next;
> +  }
> +
> +  return false;
> +}

I would put the quickhash calculation in the condition
(hf->type == HASHFEED_QH) because it is otherwise always computed.
By the way, I had to cast:

    if ((h % hf->mod + 1) >= (unsigned int) hf->begin &&
        (h % hf->mod + 1) <= (unsigned int) hf->end)


> +     if ((u = strchr(p, ':')) != NULL)
> + hf->offset = atoi(u + 1);
> +     else
> + hf->offset = 0;

Hmm... Something is then missing in the documentation:

-=-=-
As MD5 generates a 128-bit return value, it is possible to specify
from which byte the 32-bit integer used by hashfeed starts:  it should
be appended to the C<mod> value.  The default is C<:0> and thirteen
overlapping values from C<:0> to C<:12> can be used (only four totally
independent values exist:  C<:0>, C<:4>, C<:8> and C<:12>).

Therefore, it allows to a generate a second level of deterministic
distribution.  Indeed, if a news server is fed C<Q1/2>, it can go on
splitting thanks to C<Q1-3/9:4> for instance.
-=-=-

Do you agree with that?  Feel free to modify it if you want.


> +     if (sscanf(p, "%d-%d/%d", &hf->begin, &hf->end, &hf->mod) != 3) {
> +     if (sscanf(p, "%d/%d", &hf->begin, &hf->mod) == 2) {
> + hf->end = hf->begin;
> + } else {
> + free(hf);
> + return "hash not in x/z or x-y/z format";
> + }

I have also put according to your suggestion:

    if (hf->begin > hf->end || hf->end > hf->mod)
        return "incorrect hash values for Q";

I hope it suits you (other errors in newsfeeds flags do that).


And there is also this patch:

--- scripts/inncheck.in (révision 7712)
+++ scripts/inncheck.in (copie de travail)
@@ -360,6 +360,7 @@
     'N',       '^[mu]$',
     'O',       '^\S+$',
     'P',       '^\d+$',
+    'Q',       '^@?\d(-\d)?/\d(:\d)?$',
     'S',       '^\d+$',
     'T',       '^[cflmpx]$',
     'U',        '^\d+$',

I hope the regexp is correct.  Please tell me otherwise.


Regards,

-- 
Julien ÉLIE

« Un clavier azerty en vaut deux. » 



More information about the inn-workers mailing list