Repository: trafficserver Updated Branches: refs/heads/master 426879358 -> 2ac12c4a2
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/lib/ts/INK_MD5.h ---------------------------------------------------------------------- diff --git a/lib/ts/INK_MD5.h b/lib/ts/INK_MD5.h index 37585eb..d5d4e91 100644 --- a/lib/ts/INK_MD5.h +++ b/lib/ts/INK_MD5.h @@ -26,132 +26,19 @@ #include "ink_code.h" #include "ink_defs.h" - -struct INK_MD5 -{ - - // This union is needed to fix strict-aliasing warnings. - // It is anonymous so that the 'b' member can remain in - // the top level scope of the struct. This is because - // other code touches that directly. Once that code is - // also fixed we can make this an Alias64 type from - // ink_align.h - union - { - uint64_t b[2]; // Legacy placeholder - uint64_t u64[2]; - uint32_t u32[4]; - uint8_t u8[16]; - }; - - const INK_MD5 & operator =(const INK_MD5 & md5) - { - u64[0] = md5.u64[0]; - u64[1] = md5.u64[1]; - return *this; - } - uint32_t word(int i) - { - return u32[i]; - } - unsigned char byte(int i) - { - return u8[i]; - } - INK_MD5 & loadFromBuffer(char const* md5_buf) { - memcpy((void *) u8, (void *) md5_buf, 16); - return (*this); - } - INK_MD5 & storeToBuffer(char const* md5_buf) { - memcpy((void *) md5_buf, (void *) u8, 16); - return (*this); - } - INK_MD5 & operator =(char const* md5) { - return (loadFromBuffer(md5)); - } - INK_MD5 & operator =(unsigned char const* md5) { - return (loadFromBuffer((char *) md5)); - } - - char *toStr(char *md5_str) - { - return (char *) memcpy((void *) md5_str, (void *) u8, 16); - } - void encodeBuffer(unsigned char const* buffer, int len) - { - ink_code_md5(buffer, len, u8); - } - void encodeBuffer(const char *buffer, int len) - { - encodeBuffer(reinterpret_cast<unsigned char const*>(buffer), len); - } - char *str() - { - return ((char *) u8); - } - char *toHexStr(char hex_md5[33]) - { - return (ink_code_md5_stringify_fast(hex_md5, str())); - } - void set(INK_MD5 & md5) - { - loadFromBuffer((char *) md5.u8); - } - void set(INK_MD5 * md5) - { - loadFromBuffer((char *) md5->u8); - } - void set(char *p) - { - loadFromBuffer(p); - } - void set(uint64_t a1, uint64_t a2) - { - u64[0] = a1; - u64[1] = a2; - } - char *string(char buf[33]) - { - char hex_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - int i, j; - - for (i = 0, j = 0; i < 16; i += 1, j += 2) { - buf[j + 0] = hex_digits[u8[i] >> 4]; - buf[j + 1] = hex_digits[u8[i] & 0xF]; - } - buf[32] = '\0'; - return buf; - } - - uint64_t fold() const - { - return (u64[0] ^ u64[1]); - } - - uint64_t operator[] (int i) const - { - return u64[i]; - } - bool operator==(INK_MD5 const& md5) const - { - return u64[0] == md5.u64[0] && u64[1] == md5.u64[1]; - } - bool operator != (INK_MD5 const& that) const - { - return !(*this == that); - } - - INK_MD5() { - u64[0] = 0; - u64[1] = 0; - } - INK_MD5(uint64_t a1, uint64_t a2) { - u64[0] = a1; - u64[1] = a2; - } - - /// Static default constructed instance. - static INK_MD5 const ZERO; +#include "CryptoHash.h" + +class MD5Context : public CryptoContext { +protected: + MD5_CTX _ctx; +public: + MD5Context(); + /// Update the hash with @a data of @a length bytes. + virtual bool update(void const* data, int length); + /// Finalize and extract the @a hash. + virtual bool finalize(CryptoHash& hash); }; +typedef CryptoHash INK_MD5; + #endif http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/lib/ts/MMH.cc ---------------------------------------------------------------------- diff --git a/lib/ts/MMH.cc b/lib/ts/MMH.cc new file mode 100644 index 0000000..66d5c48 --- /dev/null +++ b/lib/ts/MMH.cc @@ -0,0 +1,588 @@ +/** @file + + A brief file description + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#include <stdlib.h> +#include <string.h> +#include "ink_assert.h" +#include "ink_platform.h" +#include "MMH.h" + +#define MMH_X_SIZE 512 + +/* BUG: INKqa11504: need it be to 64 bits...otherwise it overflows */ +static uint64_t MMH_x[MMH_X_SIZE + 8] = { + 0x3ee18b32, 0x746d0d6b, 0x591be6a3, 0x760bd17f, + 0x363c765d, 0x4bf3d5c5, 0x10f0510a, 0x39a84605, + 0x2282b48f, 0x6903652e, 0x1b491170, 0x1ab8407a, + 0x776b8aa8, 0x5b126ffe, 0x5095db1a, 0x565fe90c, + 0x3ae1f068, 0x73fdf0cb, 0x72f39a81, 0x6a40a4a3, + 0x4ef557fe, 0x360c1a2c, 0x4579b0ea, 0x61dfd174, + 0x269b242f, 0x752d6298, 0x15f10fa3, 0x618b7ab3, + 0x6699171f, 0x488f2c6c, 0x790f8cdb, 0x5ed15565, + 0x04eba3c0, 0x5009ac0b, 0x3a5d6c1f, 0x1a4f7853, + 0x1affabd4, 0x74aace1f, 0x2310b46d, 0x466b611a, + 0x18c5d4a0, 0x7eb9fffe, 0x76098df6, 0x4172f860, + 0x689e3c2f, 0x722cdc29, 0x64548175, 0x28f46721, + 0x58fdf93f, 0x12c2dcee, 0x58cb1327, 0x02d4af27, + 0x4d1c6fcd, 0x72fe572d, 0x7038d366, 0x0bfa1898, + 0x788d2438, 0x1f131f37, 0x25729ee6, 0x635ea6a9, + 0x3b0b5714, 0x6ac759d2, 0x5faf688a, 0x0c2fe571, + 0x7487538e, 0x65491b59, 0x60cd86e4, 0x5d6482d8, + 0x4a59fa77, 0x78439700, 0x56a51f48, 0x360544ae, + 0x6c01b3ef, 0x2228c036, 0x15b7e88b, 0x326e0dd8, + 0x509491af, 0x72d06023, 0x26181f5d, 0x7924c4a4, + 0x70c60bf2, 0x7b5bc151, 0x28e42640, 0x48af0c3e, + 0x009b6301, 0x06dd3366, 0x2ad1eb24, 0x102ce33c, + 0x1e504f5a, 0x5ab4c90f, 0x669ccca1, 0x118d5954, + 0x1a1e4a7c, 0x1807d1f9, 0x525a58d0, 0x2f13ae2d, + 0x17335a52, 0x714eb2f9, 0x1865dfc7, 0x61b64b52, + 0x0dc9e939, 0x4fccde4c, 0x6d5873af, 0x47c62b43, + 0x0fa1d4b0, 0x2f00cdf8, 0x68029083, 0x52645fa6, + 0x4bb37c9b, 0x53d60251, 0x48364566, 0x35b4889b, + 0x46783d34, 0x30c12697, 0x210459a1, 0x36962f2d, + 0x36305d8f, 0x170e9dbd, 0x687c8739, 0x261c14e4, + 0x3cc51cc7, 0x02add945, 0x01a88529, 0x6617aa77, + 0x6be627ca, 0x14c7fc46, 0x46fb3b41, 0x1bffff9e, + 0x1e6c61be, 0x10966c8f, 0x3f69199b, 0x1b5e9e06, + 0x4880890f, 0x055613e6, 0x6c742db5, 0x7be1e15e, + 0x2522e317, 0x41fe3369, 0x2b462f30, 0x605b7e8e, + 0x1c19b868, 0x3fadcb16, 0x781c5e24, 0x1c6b0c08, + 0x499f0bb9, 0x04b0b766, 0x7d6cad1e, 0x097f7d36, + 0x2e02956a, 0x03adc713, 0x4ce950b7, 0x6e57a313, + 0x557badb5, 0x73212afb, 0x3f7f6ed2, 0x0558e3d6, + 0x28376f73, 0x54dac21d, 0x6c3f4771, 0x67147bc8, + 0x5ae9fd88, 0x51ede3c0, 0x1067d134, 0x5246b937, + 0x056e74ed, 0x5d7869b2, 0x62356370, 0x76a0c583, + 0x3defb558, 0x5200dcae, 0x1432a7e8, 0x3ae4ad55, + 0x0c4cca8a, 0x0607c4d7, 0x1944ae2b, 0x726479f0, + 0x558e6035, 0x5ae64061, 0x4e1e9a8a, 0x0cf04d9f, + 0x46ef4a87, 0x0554224f, 0x70d70ab3, 0x03cc954e, + 0x39d0cd57, 0x1b11fb56, 0x62a0e9ee, 0x55888135, + 0x3e93ebeb, 0x29578ee1, 0x0bcb0ef4, 0x529e16af, + 0x165bab64, 0x39ed562e, 0x52c59d67, 0x48c84d29, + 0x0fd0d1c7, 0x795fd395, 0x79a1c4f3, 0x5010c835, + 0x4fbe4ba8, 0x49a597e9, 0x29f017ff, 0x59dde0be, + 0x2c660275, 0x15fcfbf7, 0x1eab540f, 0x38e2cf56, + 0x74608d5c, 0x7cd4b02c, 0x52a115b9, 0x2bdee9ac, + 0x5456c6da, 0x63626453, 0x15279241, 0x19b60519, + 0x508af0e1, 0x2e3ce97b, 0x568710d4, 0x6abb3059, + 0x7897b1a5, 0x17034ff6, 0x2aef7d5e, 0x5a281657, + 0x0fa5d304, 0x76f0a37e, 0x31be0f08, 0x46ce7c20, + 0x563e4e90, 0x31540773, 0x1cdc9c51, 0x10366bfa, + 0x1b6cd03a, 0x615f1540, 0x18c3d6c8, 0x3cb2bf8e, + 0x29bf799c, 0x40b87edb, 0x42c34863, 0x1e9edb40, + 0x64734fe2, 0x3ddf176a, 0x1c458c7f, 0x06138c9f, + 0x5e695e56, 0x02c98403, 0x0474de75, 0x660e1df8, + 0x6df73788, 0x3770f68c, 0x758bb7d5, 0x0763d105, + 0x16e61f16, 0x153974c1, 0x29ded842, 0x1a0d12c3, + 0x599ec61d, 0x05904d54, 0x79e9b0ea, 0x4976da61, + 0x5834243c, 0x67c17d2f, 0x65fbcda0, 0x17bdc554, + 0x465e9741, 0x7a0ee6d5, 0x3b357597, 0x0d1da287, + 0x01211373, 0x04a05de6, 0x5deb5dbd, 0x6d993eb0, + 0x2064ce7c, 0x3011a8c1, 0x36ece6b1, 0x4a0963be, + 0x0cf46ef0, 0x0d53ba44, 0x63260063, 0x187f1d6e, + 0x7e866a7e, 0x4b6885af, 0x254d6d47, 0x715474fd, + 0x6896dcb2, 0x7554eea6, 0x2161bf36, 0x5387f5f8, + 0x5c4bc064, 0x059a7755, 0x7d4307e1, 0x17326e2f, + 0x5e2315c1, 0x14c26eae, 0x1e5cd6f2, 0x352b7ac8, + 0x66591ef3, 0x381e80cd, 0x19b3bfc1, 0x3668946f, + 0x4b6d7d70, 0x20feab7d, 0x1b6340af, 0x356b6cab, + 0x299099dc, 0x295ab8d4, 0x184c8623, 0x134f8e4c, + 0x7caf609c, 0x716d81f9, 0x2e04231f, 0x1dd45301, + 0x43e9fcf9, 0x1c225c06, 0x0994797e, 0x5b3f6006, + 0x1d22dcec, 0x32993108, 0x3f0c2bcc, 0x4d44fbfa, + 0x389de78c, 0x7f8be723, 0x5dab92c1, 0x7866afce, + 0x3bfc7011, 0x4a27d7d3, 0x0c79d05c, 0x268dc4da, + 0x3fe10f84, 0x1f18394d, 0x20b9ba99, 0x312e520a, + 0x64cf2f05, 0x322a7c04, 0x4cc077ce, 0x7218aa35, + 0x550cacb8, 0x5943be47, 0x15b346a8, 0x0d6a1d8e, + 0x3f08a54d, 0x7a6e9807, 0x274f8bbc, 0x6feb2033, + 0x64b10c2b, 0x2cbaa0b7, 0x0db7decc, 0x22b807e3, + 0x10d15c39, 0x6a9b314c, 0x5ff27199, 0x5072b2cd, + 0x4eaf4b49, 0x5a890464, 0x7df0ca60, 0x548e8983, + 0x5e3f0a21, 0x70027683, 0x503e6bf2, 0x47ad6e0d, + 0x77173b26, 0x6dc04878, 0x4d73a573, 0x439b4a1a, + 0x2e6569a7, 0x1630e5de, 0x1be363af, 0x6f5f0e52, + 0x5b266bc3, 0x2f2a51be, 0x204e7e14, 0x1b3314c6, + 0x4472b8f9, 0x4162fb52, 0x72549950, 0x3223f889, + 0x0e655f4a, 0x65c3dce4, 0x04825988, 0x22b41458, + 0x53a4e10d, 0x3e2a66d5, 0x29de3e31, 0x0252fa74, + 0x267fe54f, 0x42d6d8ba, 0x5951218f, 0x73db5791, + 0x618444e4, 0x79abcaa1, 0x0ddcf5c8, 0x2cbed2e6, + 0x73159e0e, 0x7aadc871, 0x10e3f9a4, 0x762e9d65, + 0x2a7138c9, 0x59fe016f, 0x5b6c3ee4, 0x28888205, + 0x695fa5b1, 0x50f92ddd, 0x07eefc3b, 0x42bb693a, + 0x71312191, 0x3653ecbd, 0x1d80c4ed, 0x5a536187, + 0x6a286789, 0x4a1ffbb3, 0x1e976003, 0x5a8c5f29, + 0x2ac83bdb, 0x5ab9cb08, 0x63039928, 0x5a4c04f4, + 0x7b329952, 0x40d40fcb, 0x01810524, 0x2555e83c, + 0x748d0b4f, 0x534f1612, 0x272353f2, 0x6992e1ea, + 0x33cc5e71, 0x5163b55e, 0x29886a7f, 0x7cfb1eae, + 0x330271e0, 0x6f05e91c, 0x35b01e02, 0x64bbc053, + 0x76eb9337, 0x62612f48, 0x044e0af2, 0x1dac022e, + 0x1ca56f0c, 0x0210ef2c, 0x5af7a1a9, 0x2632f2b0, + 0x23d0401c, 0x0c594a46, 0x77582293, 0x297df41b, + 0x4c7b8718, 0x6c48d948, 0x4835e412, 0x74795651, + 0x28ca3506, 0x4071f739, 0x032fdbf2, 0x097f7bc8, + 0x44ced256, 0x47f25cb9, 0x43500684, 0x45481b9a, + 0x5a5ecc82, 0x4fe9ed61, 0x337ee559, 0x556852b9, + 0x0b24b460, 0x696db949, 0x7a2def9d, 0x4fcd5640, + 0x1babd707, 0x5c9254a3, 0x44d26e0d, 0x0e26b8e4, + 0x3b1c3b5c, 0x0078c784, 0x27a7dc96, 0x1d525589, + 0x4384ae38, 0x447b77c3, 0x78488b8c, 0x5eab10f1, + 0x16812737, 0x37cc8efa, 0x219cda83, 0x00bcc48f, + 0x3c667020, 0x492d7eaa, 0x710d06ce, 0x4172c47a, + 0x358098ec, 0x1fff647b, 0x65672792, 0x1a7b927d, + 0x24006275, 0x04e630a0, 0x2f2a9185, 0x5873704b, + 0x0a8c69bc, 0x06b49059, 0x49837c48, 0x4f90a2d0, + 0x29ad7dd7, 0x3674be92, 0x46d5635f, 0x782758a2, + 0x721a2a75, 0x13427ca9, 0x20e03cc9, 0x5f884596, + 0x19dc210f, 0x066c954d, 0x52f43f40, 0x5d9c256f, + 0x7f0acaae, 0x1e186b81, 0x55e9920f, 0x0e4f77b2, + 0x6700ec53, 0x268837c0, 0x554ce08b, 0x4284e695, + 0x2127e806, 0x384cb53b, 0x51076b2f, 0x23f9eb15 +}; + +// We don't need this generator in release. +#ifdef TEST +// generator for above +static void +ink_init_MMH() +{ + srand48(13); // must remain the same! + for (int i = 0; i < MMH_X_SIZE; i++) + MMH_x[i] = lrand48(); +} +#endif /* TEST */ + + +#ifndef __GNUC__ +// these are short < 16 bytes, help by permitting inlining +static inline void +_memcpy(void *dest, const void *src, int nbytes) +{ + for (int i = 0; i < nbytes; i++) + ((char *) dest)[i] = ((char *) src)[i]; +} + +#define memcpy _memcpy +#endif + +int +ink_code_incr_MMH_init(MMH_CTX * ctx) +{ + ctx->buffer_size = 0; + ctx->blocks = 0; + ctx->state[0] = ((uint64_t) MMH_x[MMH_X_SIZE + 0] << 32) + MMH_x[MMH_X_SIZE + 1]; + ctx->state[1] = ((uint64_t) MMH_x[MMH_X_SIZE + 2] << 32) + MMH_x[MMH_X_SIZE + 3]; + ctx->state[2] = ((uint64_t) MMH_x[MMH_X_SIZE + 4] << 32) + MMH_x[MMH_X_SIZE + 5]; + ctx->state[3] = ((uint64_t) MMH_x[MMH_X_SIZE + 6] << 32) + MMH_x[MMH_X_SIZE + 7]; + return 0; +} + +int +ink_code_MMH(unsigned char *input, int len, unsigned char *sixteen_byte_hash) +{ + MMH_CTX ctx; + ink_code_incr_MMH_init(&ctx); + ink_code_incr_MMH_update(&ctx, (const char *) input, len); + ink_code_incr_MMH_final(sixteen_byte_hash, &ctx); + return 0; +} + +static inline void +MMH_update(MMH_CTX * ctx, unsigned char *ab) +{ + uint32_t *b = (uint32_t *) ab; + ctx->state[0] += b[0] * MMH_x[(ctx->blocks + 0) % MMH_X_SIZE]; + ctx->state[1] += b[1] * MMH_x[(ctx->blocks + 1) % MMH_X_SIZE]; + ctx->state[2] += b[2] * MMH_x[(ctx->blocks + 2) % MMH_X_SIZE]; + ctx->state[3] += b[3] * MMH_x[(ctx->blocks + 3) % MMH_X_SIZE]; + ctx->blocks += 4; +} + +static inline void +MMH_updateb1(MMH_CTX * ctx, unsigned char *ab) +{ + uint32_t *b = (uint32_t *) (ab - 1); + uint32_t b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4]; + b0 = (b0 << 8) + (b1 >> 24); + b1 = (b1 << 8) + (b2 >> 24); + b2 = (b2 << 8) + (b3 >> 24); + b3 = (b3 << 8) + (b4 >> 24); + ctx->state[0] += b0 * MMH_x[(ctx->blocks + 0) % MMH_X_SIZE]; + ctx->state[1] += b1 * MMH_x[(ctx->blocks + 1) % MMH_X_SIZE]; + ctx->state[2] += b2 * MMH_x[(ctx->blocks + 2) % MMH_X_SIZE]; + ctx->state[3] += b3 * MMH_x[(ctx->blocks + 3) % MMH_X_SIZE]; + ctx->blocks += 4; +} + +static inline void +MMH_updateb2(MMH_CTX * ctx, unsigned char *ab) +{ + uint32_t *b = (uint32_t *) (ab - 2); + uint32_t b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4]; + b0 = (b0 << 16) + (b1 >> 16); + b1 = (b1 << 16) + (b2 >> 16); + b2 = (b2 << 16) + (b3 >> 16); + b3 = (b3 << 16) + (b4 >> 16); + ctx->state[0] += b0 * MMH_x[(ctx->blocks + 0) % MMH_X_SIZE]; + ctx->state[1] += b1 * MMH_x[(ctx->blocks + 1) % MMH_X_SIZE]; + ctx->state[2] += b2 * MMH_x[(ctx->blocks + 2) % MMH_X_SIZE]; + ctx->state[3] += b3 * MMH_x[(ctx->blocks + 3) % MMH_X_SIZE]; + ctx->blocks += 4; +} + +static inline void +MMH_updateb3(MMH_CTX * ctx, unsigned char *ab) +{ + uint32_t *b = (uint32_t *) (ab - 3); + uint32_t b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4]; + b0 = (b0 << 24) + (b1 >> 8); + b1 = (b1 << 24) + (b2 >> 8); + b2 = (b2 << 24) + (b3 >> 8); + b3 = (b3 << 24) + (b4 >> 8); + ctx->state[0] += b0 * MMH_x[(ctx->blocks + 0) % MMH_X_SIZE]; + ctx->state[1] += b1 * MMH_x[(ctx->blocks + 1) % MMH_X_SIZE]; + ctx->state[2] += b2 * MMH_x[(ctx->blocks + 2) % MMH_X_SIZE]; + ctx->state[3] += b3 * MMH_x[(ctx->blocks + 3) % MMH_X_SIZE]; + ctx->blocks += 4; +} + +static inline void +MMH_updatel1(MMH_CTX * ctx, unsigned char *ab) +{ + uint32_t *b = (uint32_t *) (ab - 1); + uint32_t b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4]; + b0 = (b0 >> 8) + (b1 << 24); + b1 = (b1 >> 8) + (b2 << 24); + b2 = (b2 >> 8) + (b3 << 24); + b3 = (b3 >> 8) + (b4 << 24); + ctx->state[0] += b0 * MMH_x[(ctx->blocks + 0) % MMH_X_SIZE]; + ctx->state[1] += b1 * MMH_x[(ctx->blocks + 1) % MMH_X_SIZE]; + ctx->state[2] += b2 * MMH_x[(ctx->blocks + 2) % MMH_X_SIZE]; + ctx->state[3] += b3 * MMH_x[(ctx->blocks + 3) % MMH_X_SIZE]; + ctx->blocks += 4; +} + +static inline void +MMH_updatel2(MMH_CTX * ctx, unsigned char *ab) +{ + uint32_t *b = (uint32_t *) (ab - 2); + uint32_t b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4]; + b0 = (b0 >> 16) + (b1 << 16); + b1 = (b1 >> 16) + (b2 << 16); + b2 = (b2 >> 16) + (b3 << 16); + b3 = (b3 >> 16) + (b4 << 16); + ctx->state[0] += b0 * MMH_x[(ctx->blocks + 0) % MMH_X_SIZE]; + ctx->state[1] += b1 * MMH_x[(ctx->blocks + 1) % MMH_X_SIZE]; + ctx->state[2] += b2 * MMH_x[(ctx->blocks + 2) % MMH_X_SIZE]; + ctx->state[3] += b3 * MMH_x[(ctx->blocks + 3) % MMH_X_SIZE]; + ctx->blocks += 4; +} + +static inline void +MMH_updatel3(MMH_CTX * ctx, unsigned char *ab) +{ + uint32_t *b = (uint32_t *) (ab - 3); + uint32_t b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4]; + b0 = (b0 >> 24) + (b1 << 8); + b1 = (b1 >> 24) + (b2 << 8); + b2 = (b2 >> 24) + (b3 << 8); + b3 = (b3 >> 24) + (b4 << 8); + ctx->state[0] += b0 * MMH_x[(ctx->blocks + 0) % MMH_X_SIZE]; + ctx->state[1] += b1 * MMH_x[(ctx->blocks + 1) % MMH_X_SIZE]; + ctx->state[2] += b2 * MMH_x[(ctx->blocks + 2) % MMH_X_SIZE]; + ctx->state[3] += b3 * MMH_x[(ctx->blocks + 3) % MMH_X_SIZE]; + ctx->blocks += 4; +} + +int +ink_code_incr_MMH_update(MMH_CTX * ctx, const char *ainput, int input_length) +{ + unsigned char *in = (unsigned char *) ainput; + unsigned char *end = in + input_length; + if (ctx->buffer_size) { + int l = 16 - ctx->buffer_size; + if (input_length >= l) { + memcpy(ctx->buffer + ctx->buffer_size, in, l); + ctx->buffer_size = 0; + in += l; + if (ctx->buffer_size & 0x0f) + return 0; + MMH_update(ctx, ctx->buffer); + } else + goto Lstore; + } + { + // check alignment + int alignment = (int)((intptr_t) in & 0x3); + if (alignment) { +#if defined(_BIG_ENDIAN) +#define big_endian 1 +#elif defined(_LITTLE_ENDIAN) +#define big_endian 0 +#else + unsigned int endian = 1; + int big_endian = !*(char *) &endian; +#endif + if (big_endian) { + if (alignment == 1) { + while (in + 16 <= end) { + MMH_updateb1(ctx, in); + in += 16; + } + } else if (alignment == 2) { + while (in + 16 <= end) { + MMH_updateb2(ctx, in); + in += 16; + } + } else if (alignment == 3) + while (in + 16 <= end) { + MMH_updateb3(ctx, in); + in += 16; + } + } else { + if (alignment == 1) { + while (in + 16 <= end) { + MMH_updatel1(ctx, in); + in += 16; + } + } else if (alignment == 2) { + while (in + 16 <= end) { + MMH_updatel2(ctx, in); + in += 16; + } + } else if (alignment == 3) + while (in + 16 <= end) { + MMH_updatel3(ctx, in); + in += 16; + } + } + } else { + while (in + 16 <= end) { + MMH_update(ctx, in); + in += 16; + } + } + } +Lstore: + if (end - in) { + int oldbs = ctx->buffer_size; + ctx->buffer_size += (int) (end - in); +#ifndef TEST + ink_assert(ctx->buffer_size < 16); +#endif + memcpy(ctx->buffer + oldbs, in, (int) (end - in)); + } + return 0; +} + +#if defined(__GNUC__) +#define _memset memset +#else +// NOT general purpose +inline void +_memset(unsigned char *b, int c, int len) +{ + (void) c; + int o = len & 0x3, i; + for (i = 0; i < o; i++) + b[i] = 0; + for (i = 0; i < (len - o) / 4; i++) + ((uint32_t *) (b + o))[i] = 0; +} +#endif + + +int +ink_code_incr_MMH_final(uint8_t *presult, MMH_CTX * ctx) +{ + unsigned int len = ctx->blocks * 4 + ctx->buffer_size; + // pad out to 16 bytes + if (ctx->buffer_size) { + _memset(ctx->buffer + ctx->buffer_size, 0, 16 - ctx->buffer_size); + ctx->buffer_size = 0; + MMH_update(ctx, ctx->buffer); + } + // append length (before padding) + unsigned int *pbuffer = (unsigned int *) ctx->buffer; + pbuffer[1] = pbuffer[2] = pbuffer[3] = pbuffer[0] = len; + MMH_update(ctx, ctx->buffer); + // final phase + uint32_t *b = (uint32_t *) presult; + uint64_t d = (((uint64_t) 1) << 32) + 15; + uint32_t b0 = uint32_t(ctx->state[0] % d); + uint32_t b1 = uint32_t(ctx->state[1] % d); + uint32_t b2 = uint32_t(ctx->state[2] % d); + uint32_t b3 = uint32_t(ctx->state[3] % d); + // scramble the bits, losslessly (reversibly) + b[0] = b0; + b[1] = b1 ^ (b0 >> 24) ^ (b0 << 8); + b[2] = b2 ^ (b1 >> 16) ^ (b1 << 16) + ^ (b0 >> 24) ^ (b0 << 8); + b[3] = b3 ^ (b1 >> 8) ^ (b1 << 24) + ^ (b2 >> 16) ^ (b2 << 16) + ^ (b0 >> 24) ^ (b0 << 8); + + b0 = b[0]; + b1 = b[1]; + b2 = b[2]; + b3 = b[3]; + + b[2] = b2 ^ (b3 >> 24) ^ (b3 << 8); + b[1] = b1 ^ (b2 >> 16) ^ (b2 << 16) + ^ (b3 >> 24) ^ (b3 << 8); + b[0] = b0 ^ (b3 >> 8) ^ (b3 << 24) + ^ (b2 >> 16) ^ (b2 << 16) + ^ (b1 >> 24) ^ (b1 << 8); + return 0; +} + +MMHContext::MMHContext() { + ink_code_incr_MMH_init(&_ctx); +} + +bool +MMHContext::update(void const* data, int length) { + return 0 == ink_code_incr_MMH_update(&_ctx, static_cast<char const*>(data), length); +} + +bool +MMHContext::finalize(CryptoHash& hash) { + return 0 == ink_code_incr_MMH_final(hash.u8, &_ctx); +} + +#ifdef TEST + +#define TEST_COLLISIONS 10000000 + +static int +xxcompar(uint32_t ** x, uint32_t ** y) +{ + for (int i = 0; i < 4; i++) { + if (x[i] > y[i]) + return 1; + if (x[i] < y[i]) + return -1; + } + return 0; +} + +typedef uint32_t i4_t[4]; +i4_t *xxh; +double *xf; + +main() +{ + union + { + unsigned char hash[16]; + uint32_t h[4]; + } h; + + xxh = (i4_t *)ats_malloc(4 * sizeof(uint32_t) * TEST_COLLISIONS); + xf = (double *)ats_malloc(sizeof(double) * TEST_COLLISIONS); + + printf("test collisions\n"); + char *sc1 = "http://npdev:19080/1.6664000000/4000"; + char *sc2 = "http://npdev:19080/1.8666000000/4000"; + char *sc3 = "http://:@npdev/1.6664000000/4000;?"; + char *sc4 = "http://:@npdev/1.8666000000/4000;?"; + ink_code_MMH((unsigned char *) sc1, strlen(sc1), h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + ink_code_MMH((unsigned char *) sc2, strlen(sc2), h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + ink_code_MMH((unsigned char *) sc3, strlen(sc3), h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + ink_code_MMH((unsigned char *) sc4, strlen(sc4), h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + + srand48(time(NULL)); + for (int xx = 0; xx < TEST_COLLISIONS; xx++) { + char xs[256]; + xf[xx] = drand48(); + sprintf(xs, "http://@npdev/%16.14f/4000;?", xf[xx]); + ink_code_MMH((unsigned char *) xs, strlen(xs), (unsigned char *) &xxh[xx]); + } + qsort(xxh, TEST_COLLISIONS, 16, xxcompar); + for (int xy = 0; xy < TEST_COLLISIONS - 1; xy++) { + if (xxh[xy][0] == xxh[xy + 1][0] && + xxh[xy][1] == xxh[xy + 1][1] && xxh[xy][2] == xxh[xy + 1][2] && xxh[xy][3] == xxh[xy + 1][3]) + printf("********** collision %d\n", xy); + } + + unsigned char *s = (unsigned char *) MMH_x; + int l = sizeof(MMH_x); + unsigned char *s1 = (unsigned char *)ats_malloc(l + 3); + s1 += 1; + memcpy(s1, s, l); + unsigned char *s2 = (unsigned char *)ats_malloc(l + 3); + s2 += 2; + memcpy(s2, s, l); + unsigned char *s3 = (unsigned char *)ats_malloc(l + 3); + s3 += 3; + memcpy(s3, s, l); + + printf("test alignment\n"); + ink_code_MMH(s, l, h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + ink_code_MMH(s1, l, h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + ink_code_MMH(s2, l, h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + ink_code_MMH(s3, l, h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + + int i = 0; + MMH_CTX c; + unsigned char *t = s; + printf("test chunking\n"); + ink_code_incr_MMH_init(&c); + for (i = 0; i < 24; i++) { + ink_code_incr_MMH_update(&c, (char *) t, i); + t += i; + } + ink_code_incr_MMH_final((char *) h.hash, &c); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + int q = t - s; + ink_code_MMH(s, q, h.hash); + printf("%X %X %X %X\n", h.h[0], h.h[1], h.h[2], h.h[3]); + + FILE *fp = fopen("/kernel/genunix", "r"); + char x[4096]; + int hist[256]; + memset(hist, 0, sizeof(hist)); + size_t xx; + while (((xx = fread(x, 1, 128, fp)) == 128)) { + ink_code_MMH((unsigned char *) x, 128, h.hash); + hist[h.h[0] & 255]++; + } + for (int z = 0; z < 256; z++) { + printf("%6d ", hist[z]); + if (!(z % 7)) + printf("\n"); + } +} + +#endif http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/lib/ts/MMH.h ---------------------------------------------------------------------- diff --git a/lib/ts/MMH.h b/lib/ts/MMH.h new file mode 100644 index 0000000..74f2c3c --- /dev/null +++ b/lib/ts/MMH.h @@ -0,0 +1,119 @@ +/** @file + + A brief file description + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#ifndef _MMH_h_ +#define _MMH_h_ + +#include "ink_code.h" +#include "ink_defs.h" +#include "CryptoHash.h" + +struct MMH_CTX +{ + uint64_t state[4]; + unsigned char buffer[32]; + int buffer_size; + int blocks; +}; + +// signed-unsigned-const gratuitous differences brought +// to you by history and the ANSI committee + +int inkcoreapi ink_code_incr_MMH_init(MMH_CTX * context); +int inkcoreapi ink_code_incr_MMH_update(MMH_CTX * context, const char *input, int input_length); +int inkcoreapi ink_code_incr_MMH_final(uint8_t *sixteen_byte_hash_pointer, MMH_CTX * context); +int inkcoreapi ink_code_MMH(unsigned char *input, int len, unsigned char *sixteen_byte_hash); + +/** + MMH will return different values on big-endian and little-endian + machines. It can be adapted to return the same values at some additional + cost. + +*/ +class MMHContext : public CryptoContext +{ +protected: + MMH_CTX _ctx; +public: + MMHContext(); + /// Update the hash with @a data of @a length bytes. + virtual bool update(void const* data, int length); + /// Finalize and extract the @a hash. + virtual bool finalize(CryptoHash& hash); +# if 0 + MMH & loadFromBuffer(char *MMH_buf) + { + int i; + char *s, *d; + + for (i = 0, s = MMH_buf, d = (char *) (&(b[0])); i < 8; i++, *d++ = *s++); + for (i = 0, d = (char *) (&(b[1])); i < 8; i++, *d++ = *s++); + return *this; + } + MMH & storeToBuffer(char *MMH_buf) { + int i; + char *s, *d; + + for (i = 0, d = MMH_buf, s = (char *) (&(b[0])); i < 8; i++, *d++ = *s++); + for (i = 0, s = (char *) (&(b[1])); i < 8; i++, *d++ = *s++); + return *this; + } + MMH & operator =(char *MMH) { + return loadFromBuffer(MMH); + } + MMH & operator =(unsigned char *MMH) { + return loadFromBuffer(reinterpret_cast<char *>(MMH)); + } + + char *toStr(char *MMH_str) const + { + int i; + char *s, *d; + + for (i = 0, d = MMH_str, s = (char *) (&(b[0])); i < 8; i++, *d++ = *s++); + for (i = 0, s = (char *) (&(b[1])); i < 8; i++, *d++ = *s++); + + return MMH_str; + } + void encodeBuffer(unsigned char *buffer, int len) + { + unsigned char MMH[16]; + ink_code_MMH(buffer, len, MMH); + *this = MMH; + } + void encodeBuffer(char *buffer, int len) + { + encodeBuffer((unsigned char *) buffer, len); + } + char *str() + { + return reinterpret_cast<char *>(b); + } + char *toHexStr(char hex_MMH[33]) + { + return ink_code_md5_stringify_fast(hex_MMH, str()); + } +# endif +}; + +#endif http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/lib/ts/Makefile.am ---------------------------------------------------------------------- diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am index 73b04ad..437d654 100644 --- a/lib/ts/Makefile.am +++ b/lib/ts/Makefile.am @@ -46,6 +46,7 @@ libtsutil_la_SOURCES = \ Bitops.cc \ Bitops.h \ Compatability.h \ + Cryptohash.h \ Diags.cc \ Diags.h \ DynArray.h \ @@ -70,6 +71,8 @@ libtsutil_la_SOURCES = \ MatcherUtils.h \ MimeTable.cc \ MimeTable.h \ + MMH.h \ + MMH.cc \ ParseRules.cc \ ParseRules.h \ Ptr.h \ http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/lib/ts/ink_code.cc ---------------------------------------------------------------------- diff --git a/lib/ts/ink_code.cc b/lib/ts/ink_code.cc index f3a403f..9d17a44 100644 --- a/lib/ts/ink_code.cc +++ b/lib/ts/ink_code.cc @@ -26,8 +26,23 @@ #include "ink_code.h" #include "INK_MD5.h" #include "ink_assert.h" +#include "INK_MD5.h" + +ats::CryptoHash const ats::CRYPTO_HASH_ZERO; // default constructed is correct. + +MD5Context::MD5Context() { + MD5_Init(&_ctx); +} -INK_MD5 const INK_MD5::ZERO; // default constructed is correct. +bool +MD5Context::update(void const* data, int length) { + return 0 != MD5_Update(&_ctx, data, length); +} + +bool +MD5Context::finalize(CryptoHash& hash) { + return 0 != MD5_Final(hash.u8, &_ctx); +} /** @brief Wrapper around MD5_Init @@ -111,7 +126,7 @@ ink_code_md5_stringify(char *dest33, const size_t destSize, const char *md5) */ /* reentrant version */ char * -ink_code_md5_stringify_fast(char *dest33, const char *md5) +ink_code_to_hex_str(char *dest33, uint8_t const* hash) { int i; char *d; @@ -120,17 +135,17 @@ ink_code_md5_stringify_fast(char *dest33, const char *md5) d = dest33; for (i = 0; i < 16; i += 4) { - *(d + 0) = hex_digits[((unsigned char) md5[i + 0]) >> 4]; - *(d + 1) = hex_digits[((unsigned char) md5[i + 0]) & 15]; - *(d + 2) = hex_digits[((unsigned char) md5[i + 1]) >> 4]; - *(d + 3) = hex_digits[((unsigned char) md5[i + 1]) & 15]; - *(d + 4) = hex_digits[((unsigned char) md5[i + 2]) >> 4]; - *(d + 5) = hex_digits[((unsigned char) md5[i + 2]) & 15]; - *(d + 6) = hex_digits[((unsigned char) md5[i + 3]) >> 4]; - *(d + 7) = hex_digits[((unsigned char) md5[i + 3]) & 15]; + *(d + 0) = hex_digits[hash[i + 0] >> 4]; + *(d + 1) = hex_digits[hash[i + 0] & 15]; + *(d + 2) = hex_digits[hash[i + 1] >> 4]; + *(d + 3) = hex_digits[hash[i + 1] & 15]; + *(d + 4) = hex_digits[hash[i + 2] >> 4]; + *(d + 5) = hex_digits[hash[i + 2] & 15]; + *(d + 6) = hex_digits[hash[i + 3] >> 4]; + *(d + 7) = hex_digits[hash[i + 3] & 15]; d += 8; } *d = '\0'; return (dest33); -} /* End ink_code_stringify_md5_fast */ +} http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/lib/ts/ink_code.h ---------------------------------------------------------------------- diff --git a/lib/ts/ink_code.h b/lib/ts/ink_code.h index 70bc830..ee492f6 100644 --- a/lib/ts/ink_code.h +++ b/lib/ts/ink_code.h @@ -26,6 +26,7 @@ #include "ink_apidefs.h" #include <openssl/md5.h> +#include "ink_defs.h" /* INK_MD5 context. */ typedef MD5_CTX INK_DIGEST_CTX; @@ -36,7 +37,7 @@ typedef MD5_CTX INK_DIGEST_CTX; inkcoreapi int ink_code_md5(unsigned char const* input, int input_length, unsigned char *sixteen_byte_hash_pointer); inkcoreapi char *ink_code_md5_stringify(char *dest33, const size_t destSize, const char *md5); -inkcoreapi char *ink_code_md5_stringify_fast(char *dest33, const char *md5); +inkcoreapi char *ink_code_to_hex_str(char *dest33, uint8_t const* md5); inkcoreapi int ink_code_incr_md5_init(INK_DIGEST_CTX * context); inkcoreapi int ink_code_incr_md5_update(INK_DIGEST_CTX * context, const char *input, int input_length); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/lib/ts/libts.h ---------------------------------------------------------------------- diff --git a/lib/ts/libts.h b/lib/ts/libts.h index aa19d40..97ce163 100644 --- a/lib/ts/libts.h +++ b/lib/ts/libts.h @@ -85,6 +85,7 @@ #include "InkPool.h" #include "List.h" #include "INK_MD5.h" +#include "MMH.h" #include "Map.h" #include "MimeTable.h" #include "ParseRules.h" http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/proxy/InkAPI.cc ---------------------------------------------------------------------- diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc index abc652f..157df6f 100644 --- a/proxy/InkAPI.cc +++ b/proxy/InkAPI.cc @@ -3914,11 +3914,12 @@ TSCacheKeyDigestSet(TSCacheKey key, const char *input, int length) sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS); sdk_assert(sdk_sanity_check_iocore_structure((void*) input) == TS_SUCCESS); sdk_assert(length > 0); - - if (((CacheInfo *) key)->magic != CACHE_INFO_MAGIC_ALIVE) + CacheInfo* ci = reinterpret_cast<CacheInfo*>(key); + + if (ci->magic != CACHE_INFO_MAGIC_ALIVE) return TS_ERROR; - ((CacheInfo *) key)->cache_key.encodeBuffer((char *) input, length); + MD5Context().hash_immediate(ci->cache_key, input, length); return TS_SUCCESS; } @@ -4890,8 +4891,8 @@ TSHttpTxnNewCacheLookupDo(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc url_loc) s->cache_info.lookup_url = &(s->cache_info.lookup_url_storage); l_url = s->cache_info.lookup_url; } else { - l_url->MD5_get(&md51); - new_url.MD5_get(&md52); + l_url->hash_get(&md51); + new_url.hash_get(&md52); if (md51 == md52) return TS_ERROR; o_url = &(s->cache_info.original_url); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/proxy/Prefetch.cc ---------------------------------------------------------------------- diff --git a/proxy/Prefetch.cc b/proxy/Prefetch.cc index 9f49f19..213c200 100644 --- a/proxy/Prefetch.cc +++ b/proxy/Prefetch.cc @@ -636,9 +636,9 @@ PrefetchTransform::hash_add(char *s) Debug("PrefetchParserURLs", "Normalized URL: %s\n", s); - INK_MD5 md5; - md5.encodeBuffer(s, str_len); - index = md5.word(1) % HASH_TABLE_LENGTH; + INK_MD5 hash; + MD5Context().hash_immediate(hash, s, str_len); + index = hash.slice32(1) % HASH_TABLE_LENGTH; PrefetchUrlEntry **e = &hash_table[index]; for (; *e; e = &(*e)->hash_link) @@ -646,7 +646,7 @@ PrefetchTransform::hash_add(char *s) return NULL; *e = prefetchUrlEntryAllocator.alloc(); - (*e)->init(ats_strdup(s), md5); + (*e)->init(ats_strdup(s), hash); return *e; } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/proxy/Update.cc ---------------------------------------------------------------------- diff --git a/proxy/Update.cc b/proxy/Update.cc index 6481a49..1b1f75b 100644 --- a/proxy/Update.cc +++ b/proxy/Update.cc @@ -1674,8 +1674,7 @@ RecursiveHttpGet::RecursiveHttpGetEvent(int event, Event * d) } // I think we're generating the cache key just to get a hash of the URL. // Used to use Cache::generate_key that no longer works with vary_on_user_agent - // isn't turned on. ToDo. - ue->_URLhandle.MD5_get(&ue->_url_md5); + ue->_URLhandle.hash_get(&ue->_url_md5); if (_CL->HashAdd(ue)) { // Entry already exists http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/proxy/hdrs/URL.cc ---------------------------------------------------------------------- diff --git a/proxy/hdrs/URL.cc b/proxy/hdrs/URL.cc index 732e018..7a34106 100644 --- a/proxy/hdrs/URL.cc +++ b/proxy/hdrs/URL.cc @@ -22,6 +22,7 @@ */ #include <assert.h> +#include <new> #include "libts.h" #include "URL.h" #include "MIME.h" @@ -96,6 +97,20 @@ int url_hash_method = 0; /*------------------------------------------------------------------------- -------------------------------------------------------------------------*/ +URLHashContext::HashType URLHashContext::Setting = URLHashContext::MMH; + +URLHashContext::URLHashContext() { + switch (Setting) { + case UNSPECIFIED: + case MD5: + _ctx = new(_obj) MD5Context; + break; + case MMH: + _ctx = new(_obj) MMHContext; + break; + default: ink_assert("Invalid global URL hash context"); + }; +} void url_init() @@ -191,6 +206,10 @@ url_init() URL_LEN_MMS = hdrtoken_wks_to_length(URL_SCHEME_MMS); URL_LEN_MMSU = hdrtoken_wks_to_length(URL_SCHEME_MMSU); URL_LEN_MMST = hdrtoken_wks_to_length(URL_SCHEME_MMST); + + ink_assert(URLHashContext::OBJ_SIZE >= sizeof(MD5Context)); + ink_assert(URLHashContext::OBJ_SIZE >= sizeof(MMHContext)); + } } @@ -1581,14 +1600,11 @@ memcpy_tolower(char *d, const char *s, int n) // no buffer overflow, no unescaping needed static inline void -url_MD5_get_fast(URLImpl * url, INK_MD5 * md5) +url_MD5_get_fast(URLImpl * url, CryptoContext& ctx, CryptoHash* hash) { - INK_DIGEST_CTX md5_ctx; char buffer[BUFSIZE]; char *p; - ink_code_incr_md5_init(&md5_ctx); - p = buffer; memcpy_tolower(p, url->m_ptr_scheme, url->m_len_scheme); p += url->m_len_scheme; @@ -1614,21 +1630,19 @@ url_MD5_get_fast(URLImpl * url, INK_MD5 * md5) *p++ = ((char *) &port)[0]; *p++ = ((char *) &port)[1]; - ink_code_incr_md5_update(&md5_ctx, buffer, p - buffer); - ink_code_incr_md5_final((char *) md5, &md5_ctx); + ctx.update(buffer, p - buffer); + ctx.finalize(hash); } static inline void -url_MD5_get_general(URLImpl * url, INK_MD5 * md5) +url_MD5_get_general(URLImpl * url, CryptoContext& ctx, CryptoHash& hash) { - INK_DIGEST_CTX md5_ctx; - char buffer[BUFSIZE]; char *p, *e; const char *strs[13], *ends[13]; const char *t; - uint16_t port; + in_port_t port; int i, s; strs[0] = url->m_ptr_scheme; @@ -1663,8 +1677,6 @@ url_MD5_get_general(URLImpl * url, INK_MD5 * md5) p = buffer; e = buffer + BUFSIZE; - ink_code_incr_md5_init(&md5_ctx); - for (i = 0; i < 13; i++) { if (strs[i]) { t = strs[i]; @@ -1678,29 +1690,26 @@ url_MD5_get_general(URLImpl * url, INK_MD5 * md5) } if (p == e) { - ink_code_incr_md5_update(&md5_ctx, buffer, BUFSIZE); + ctx.update(buffer, BUFSIZE); p = buffer; } } } } - if (p != buffer) { - ink_code_incr_md5_update(&md5_ctx, buffer, p - buffer); - } + if (p != buffer) ctx.update(buffer, p-buffer); port = url_canonicalize_port(url->m_url_type, url->m_port); - ink_code_incr_md5_update(&md5_ctx, (char *) &port, sizeof(port)); - ink_code_incr_md5_final((char *) md5, &md5_ctx); + ctx.update(&port, sizeof(port)); + ctx.finalize(hash); + Debug("amc", "hash 0x%" PRIx64 ":%" PRIx64, hash[0], hash[1]); } - - - void -url_MD5_get(URLImpl * url, INK_MD5 * md5) +url_MD5_get(URLImpl * url, CryptoHash* hash) { + URLHashContext ctx; if ((url_hash_method != 0) && (url->m_url_type == URL_TYPE_HTTP) && ((url->m_len_user + url->m_len_password + url->m_len_params + url->m_len_query) == 0) && @@ -1710,15 +1719,14 @@ url_MD5_get(URLImpl * url, INK_MD5 * md5) url->m_len_path < BUFSIZE) && (memchr(url->m_ptr_host, '%', url->m_len_host) == NULL) && (memchr(url->m_ptr_path, '%', url->m_len_path) == NULL)) { - url_MD5_get_fast(url, md5); - + url_MD5_get_fast(url, ctx, hash); #ifdef DEBUG - INK_MD5 md5_general; - url_MD5_get_general(url, &md5_general); - ink_assert(*md5 == md5_general); + CryptoHash md5_general; + url_MD5_get_general(url, ctx, md5_general); + ink_assert(*hash == md5_general); #endif } else { - url_MD5_get_general(url, md5); + url_MD5_get_general(url, ctx, *hash); } } @@ -1730,23 +1738,23 @@ url_MD5_get(URLImpl * url, INK_MD5 * md5) void url_host_MD5_get(URLImpl * url, INK_MD5 * md5) { - INK_DIGEST_CTX md5_ctx; - - ink_code_incr_md5_init(&md5_ctx); + MD5Context ctx; if (url->m_ptr_scheme) { - ink_code_incr_md5_update(&md5_ctx, url->m_ptr_scheme, url->m_len_scheme); + ctx.update(url->m_ptr_scheme, url->m_len_scheme); } - ink_code_incr_md5_update(&md5_ctx, "://", 3); + ctx.update("://", 3); if (url->m_ptr_host) { - ink_code_incr_md5_update(&md5_ctx, url->m_ptr_host, url->m_len_host); + ctx.update(url->m_ptr_host, url->m_len_host); } - ink_code_incr_md5_update(&md5_ctx, ":", 1); + ctx.update(":", 1); + // [amc] Why is this <int> and not <in_port_t>? + // Especially since it's in_port_t for url_MD5_get. int port = url_canonicalize_port(url->m_url_type, url->m_port); - ink_code_incr_md5_update(&md5_ctx, (char *) &port, sizeof(port)); - ink_code_incr_md5_final((char *) md5, &md5_ctx); + ctx.update(&port, sizeof(port)); + ctx.finalize(*md5); } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/proxy/hdrs/URL.h ---------------------------------------------------------------------- diff --git a/proxy/hdrs/URL.h b/proxy/hdrs/URL.h index 0a6cd81..5bed604 100644 --- a/proxy/hdrs/URL.h +++ b/proxy/hdrs/URL.h @@ -28,6 +28,7 @@ #include "HdrToken.h" #include "HdrHeap.h" #include "INK_MD5.h" +#include "MMH.h" #include "MIME.h" #include "ink_apidefs.h" @@ -86,6 +87,34 @@ struct URLImpl:public HdrHeapObjImpl void check_strings(HeapCheck *heaps, int num_heaps); }; +/// Crypto Hash context for URLs. +/// @internal This just forwards on to another specific context but avoids +/// putting that switch logic in multiple places. +class URLHashContext : public CryptoContext { +protected: + CryptoContext* _ctx; ///< Generic pointer to use for operations. + uint64_t _obj[32]; ///< Raw storage for instantiated context. +public: + URLHashContext(); + /// Update the hash with @a data of @a length bytes. + virtual bool update(void const* data, int length); + /// Finalize and extract the @a hash. + virtual bool finalize(CryptoHash& hash); + + enum HashType { UNSPECIFIED, MD5, MMH }; ///< What type of hash we really are. + static HashType Setting; + + /// For external checking. + static size_t const OBJ_SIZE = sizeof(_obj); +}; + +inline bool URLHashContext::update(void const* data, int length) { + return _ctx->update(data, length); +} + +inline bool URLHashContext::finalize(CryptoHash& hash) { + return _ctx->finalize(hash); +} extern const char *URL_SCHEME_FILE; extern const char *URL_SCHEME_FTP; @@ -176,8 +205,8 @@ void url_called_set(URLImpl *url); char *url_string_get_buf(URLImpl *url, char *dstbuf, int dstbuf_size, int *length); const char *url_scheme_get(URLImpl *url, int *length); -void url_MD5_get(URLImpl *url, INK_MD5 *md5); -void url_host_MD5_get(URLImpl *url, INK_MD5 *md5); +void url_MD5_get(URLImpl *url, CryptoHash *md5); +void url_host_MD5_get(URLImpl *url, CryptoHash *md5); const char *url_scheme_set(HdrHeap *heap, URLImpl *url, const char *value, int value_wks_idx, int length, bool copy_string); @@ -249,8 +278,8 @@ public: char *string_get(Arena *arena, int *length = NULL); char *string_get_ref(int *length = NULL); char *string_get_buf(char *dstbuf, int dsbuf_size, int *length = NULL); - void MD5_get(INK_MD5 *md5); - void host_MD5_get(INK_MD5 *md5); + void hash_get(CryptoHash *md5); + void host_hash_get(CryptoHash *md5); const char *scheme_get(int *length); int scheme_get_wksidx(); @@ -440,7 +469,7 @@ URL::string_get_buf(char *dstbuf, int dsbuf_size, int *length) -------------------------------------------------------------------------*/ inline void -URL::MD5_get(INK_MD5 *md5) +URL::hash_get(CryptoHash *md5) { ink_assert(valid()); url_MD5_get(m_url_impl, md5); @@ -450,7 +479,7 @@ URL::MD5_get(INK_MD5 *md5) -------------------------------------------------------------------------*/ inline void -URL::host_MD5_get(INK_MD5 *md5) +URL::host_hash_get(CryptoHash *md5) { ink_assert(valid()); url_host_MD5_get(m_url_impl, md5); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/proxy/http/HttpServerSession.h ---------------------------------------------------------------------- diff --git a/proxy/http/HttpServerSession.h b/proxy/http/HttpServerSession.h index a788a35..2ac4602 100644 --- a/proxy/http/HttpServerSession.h +++ b/proxy/http/HttpServerSession.h @@ -175,7 +175,7 @@ extern ClassAllocator<HttpServerSession> httpServerSessionAllocator; inline void HttpServerSession::attach_hostname(const char *hostname) { - if (INK_MD5::ZERO == hostname_hash) { + if (CRYPTO_HASH_ZERO == hostname_hash) { ink_code_md5((unsigned char *) hostname, strlen(hostname), (unsigned char *) &hostname_hash); } } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/proxy/logging/LogFormat.cc ---------------------------------------------------------------------- diff --git a/proxy/logging/LogFormat.cc b/proxy/logging/LogFormat.cc index 3dc5c0c..db371d7 100644 --- a/proxy/logging/LogFormat.cc +++ b/proxy/logging/LogFormat.cc @@ -104,21 +104,19 @@ LogFormat::setup(const char *name, const char *format_str, unsigned interval_sec int32_t LogFormat::id_from_name(const char *name) { - int32_t - id = 0; + int32_t id = 0; if (name) { - INK_MD5 - name_md5; - name_md5.encodeBuffer(name, (int)::strlen(name)); + CryptoHash hash; + MD5Context().hash_immediate(hash, name, static_cast<int>(strlen(name))); #if defined(linux) /* Mask most signficant bit so that return value of this function * is not sign extended to be a negative number. * This problem is only known to occur on Linux which * is a 32-bit OS. */ - id = (int32_t) name_md5.fold() & 0x7fffffff; + id = (int32_t) hash.fold() & 0x7fffffff; #else - id = (int32_t) name_md5.fold(); + id = (int32_t) hash.fold(); #endif } return id; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2ac12c4a/proxy/logging/LogObject.cc ---------------------------------------------------------------------- diff --git a/proxy/logging/LogObject.cc b/proxy/logging/LogObject.cc index 2e305c9..f8d829b 100644 --- a/proxy/logging/LogObject.cc +++ b/proxy/logging/LogObject.cc @@ -337,10 +337,9 @@ uint64_t LogObject::compute_signature(LogFormat * format, char *filename, unsign ink_string_concatenate_strings(buffer, fl, ps, filename, flags & LogObject::BINARY ? "B" : (flags & LogObject::WRITES_TO_PIPE ? "P" : "A"), NULL); - INK_MD5 md5s; - - md5s.encodeBuffer(buffer, buf_size - 1); - signature = md5s.fold(); + CryptoHash hash; + MD5Context().hash_immediate(hash, buffer, buf_size - 1); + signature = hash.fold(); ats_free(buffer); }
