0105-Optimse-RR-digest-calculation-in-DNSSEC.patch 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. From 059aded0700309308dafd9720b0313ce52f6e189 Mon Sep 17 00:00:00 2001
  2. From: Simon Kelley <simon@thekelleys.org.uk>
  3. Date: Thu, 12 Nov 2020 23:09:15 +0000
  4. Subject: Optimse RR digest calculation in DNSSEC.
  5. If an RR is of a type which doesn't need canonicalisation,
  6. bypass the relatively slow canonicalisation code, and insert
  7. it direct into the digest.
  8. ---
  9. src/dnssec.c | 82 +++++++++++++++++++++++++++++++---------------------
  10. 1 file changed, 49 insertions(+), 33 deletions(-)
  11. --- a/src/dnssec.c
  12. +++ b/src/dnssec.c
  13. @@ -559,7 +559,7 @@ static int validate_rrset(time_t now, st
  14. hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname);
  15. from_wire(keyname);
  16. -#define RRBUFLEN 300 /* Most RRs are smaller than this. */
  17. +#define RRBUFLEN 128 /* Most RRs are smaller than this. */
  18. for (i = 0; i < rrsetidx; ++i)
  19. {
  20. @@ -597,50 +597,66 @@ static int validate_rrset(time_t now, st
  21. hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name_start);
  22. hash->update(ctx, 4, p); /* class and type */
  23. hash->update(ctx, 4, (unsigned char *)&nsigttl);
  24. -
  25. - p += 8; /* skip class, type, ttl */
  26. +
  27. + p += 8; /* skip type, class, ttl */
  28. GETSHORT(rdlen, p);
  29. if (!CHECK_LEN(header, p, plen, rdlen))
  30. return STAT_BOGUS;
  31. -
  32. - /* canonicalise rdata and calculate length of same, use
  33. - name buffer as workspace for get_rdata. */
  34. - state.ip = p;
  35. - state.op = NULL;
  36. - state.desc = rr_desc;
  37. - state.buff = name;
  38. - state.end = p + rdlen;
  39. -
  40. - for (j = 0; get_rdata(header, plen, &state); j++)
  41. - if (j < RRBUFLEN)
  42. - rrbuf[j] = *state.op;
  43. - len = htons((u16)j);
  44. - hash->update(ctx, 2, (unsigned char *)&len);
  45. -
  46. - /* If the RR is shorter than RRBUFLEN (most of them, in practice)
  47. - then we can just digest it now. If it exceeds RRBUFLEN we have to
  48. - go back to the start and do it in chunks. */
  49. - if (j >= RRBUFLEN)
  50. + /* Optimisation for RR types which need no cannonicalisation.
  51. + This includes DNSKEY DS NSEC and NSEC3, which are also long, so
  52. + it saves lots of calls to get_rdata, and avoids the pessimal
  53. + segmented insertion, even with a small rrbuf[].
  54. +
  55. + If canonicalisation is not needed, a simple insertion into the hash works.
  56. + */
  57. + if (*rr_desc == (u16)-1)
  58. + {
  59. + len = htons(rdlen);
  60. + hash->update(ctx, 2, (unsigned char *)&len);
  61. + hash->update(ctx, rdlen, p);
  62. + }
  63. + else
  64. {
  65. + /* canonicalise rdata and calculate length of same, use
  66. + name buffer as workspace for get_rdata. */
  67. state.ip = p;
  68. state.op = NULL;
  69. state.desc = rr_desc;
  70. -
  71. + state.buff = name;
  72. + state.end = p + rdlen;
  73. +
  74. for (j = 0; get_rdata(header, plen, &state); j++)
  75. + if (j < RRBUFLEN)
  76. + rrbuf[j] = *state.op;
  77. +
  78. + len = htons((u16)j);
  79. + hash->update(ctx, 2, (unsigned char *)&len);
  80. +
  81. + /* If the RR is shorter than RRBUFLEN (most of them, in practice)
  82. + then we can just digest it now. If it exceeds RRBUFLEN we have to
  83. + go back to the start and do it in chunks. */
  84. + if (j >= RRBUFLEN)
  85. {
  86. - rrbuf[j] = *state.op;
  87. -
  88. - if (j == RRBUFLEN - 1)
  89. - {
  90. - hash->update(ctx, RRBUFLEN, rrbuf);
  91. - j = -1;
  92. - }
  93. + state.ip = p;
  94. + state.op = NULL;
  95. + state.desc = rr_desc;
  96. +
  97. + for (j = 0; get_rdata(header, plen, &state); j++)
  98. + {
  99. + rrbuf[j] = *state.op;
  100. +
  101. + if (j == RRBUFLEN - 1)
  102. + {
  103. + hash->update(ctx, RRBUFLEN, rrbuf);
  104. + j = -1;
  105. + }
  106. + }
  107. }
  108. +
  109. + if (j != 0)
  110. + hash->update(ctx, j, rrbuf);
  111. }
  112. -
  113. - if (j != 0)
  114. - hash->update(ctx, j, rrbuf);
  115. }
  116. hash->digest(ctx, hash->digest_size, digest);