]> git.ipfire.org Git - thirdparty/squid.git/blob - src/store_key_md5.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / store_key_md5.cc
1 /*
2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 /* DEBUG: section 20 Storage Manager MD5 Cache Keys */
10
11 #include "squid.h"
12 #include "HttpRequest.h"
13 #include "md5.h"
14 #include "store_key_md5.h"
15 #include "URL.h"
16
17 static cache_key null_key[SQUID_MD5_DIGEST_LENGTH];
18
19 const char *
20 storeKeyText(const cache_key *key)
21 {
22 if (!key)
23 return "[null_store_key]";
24
25 static char buf[SQUID_MD5_DIGEST_LENGTH * 2+1];
26 int i;
27
28 for (i = 0; i < SQUID_MD5_DIGEST_LENGTH; ++i)
29 snprintf(&buf[i*2],sizeof(buf) - i*2, "%02X", *(key + i));
30
31 return buf;
32 }
33
34 const cache_key *
35 storeKeyScan(const char *buf)
36 {
37 static unsigned char digest[SQUID_MD5_DIGEST_LENGTH];
38 int i;
39 int j = 0;
40 char t[3];
41
42 for (i = 0; i < SQUID_MD5_DIGEST_LENGTH; ++i) {
43 t[0] = *(buf + (j++));
44 t[1] = *(buf + (j++));
45 t[2] = '\0';
46 *(digest + i) = (unsigned char) strtol(t, NULL, 16);
47 }
48
49 return digest;
50 }
51
52 int
53 storeKeyHashCmp(const void *a, const void *b)
54 {
55 const unsigned char *A = (const unsigned char *)a;
56 const unsigned char *B = (const unsigned char *)b;
57 int i;
58
59 for (i = 0; i < SQUID_MD5_DIGEST_LENGTH; ++i) {
60 if (A[i] < B[i])
61 return -1;
62
63 if (A[i] > B[i])
64 return 1;
65 }
66
67 return 0;
68 }
69
70 unsigned int
71 storeKeyHashHash(const void *key, unsigned int n)
72 {
73 /* note, n must be a power of 2! */
74 const unsigned char *digest = (const unsigned char *)key;
75 unsigned int i = digest[0]
76 | digest[1] << 8
77 | digest[2] << 16
78 | digest[3] << 24;
79 return (i & (--n));
80 }
81
82 const cache_key *
83 storeKeyPrivate()
84 {
85 // only the count field is required
86 // others just simplify searching for keys in a multi-process cache.log
87 static struct {
88 uint64_t count;
89 pid_t pid;
90 int32_t kid;
91 } key = { 0, getpid(), KidIdentifier };
92 assert(sizeof(key) == SQUID_MD5_DIGEST_LENGTH);
93 ++key.count;
94 return reinterpret_cast<cache_key*>(&key);
95 }
96
97 const cache_key *
98 storeKeyPublic(const char *url, const HttpRequestMethod& method, const KeyScope keyScope)
99 {
100 static cache_key digest[SQUID_MD5_DIGEST_LENGTH];
101 unsigned char m = (unsigned char) method.id();
102 SquidMD5_CTX M;
103 SquidMD5Init(&M);
104 SquidMD5Update(&M, &m, sizeof(m));
105 SquidMD5Update(&M, (unsigned char *) url, strlen(url));
106 if (keyScope)
107 SquidMD5Update(&M, &keyScope, sizeof(keyScope));
108 SquidMD5Final(digest, &M);
109 return digest;
110 }
111
112 const cache_key *
113 storeKeyPublicByRequest(HttpRequest * request, const KeyScope keyScope)
114 {
115 return storeKeyPublicByRequestMethod(request, request->method, keyScope);
116 }
117
118 const cache_key *
119 storeKeyPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method, const KeyScope keyScope)
120 {
121 static cache_key digest[SQUID_MD5_DIGEST_LENGTH];
122 unsigned char m = (unsigned char) method.id();
123 const SBuf url = request->storeId(); /* returns the right storeID\URL for the MD5 calc */
124 SquidMD5_CTX M;
125 SquidMD5Init(&M);
126 SquidMD5Update(&M, &m, sizeof(m));
127 SquidMD5Update(&M, (unsigned char *) url.rawContent(), url.length());
128 if (keyScope)
129 SquidMD5Update(&M, &keyScope, sizeof(keyScope));
130
131 if (!request->vary_headers.isEmpty()) {
132 SquidMD5Update(&M, request->vary_headers.rawContent(), request->vary_headers.length());
133 debugs(20, 3, "updating public key by vary headers: " << request->vary_headers << " for: " << url);
134 }
135
136 SquidMD5Final(digest, &M);
137
138 return digest;
139 }
140
141 cache_key *
142 storeKeyDup(const cache_key * key)
143 {
144 cache_key *dup = (cache_key *)memAllocate(MEM_MD5_DIGEST);
145 memcpy(dup, key, SQUID_MD5_DIGEST_LENGTH);
146 return dup;
147 }
148
149 cache_key *
150 storeKeyCopy(cache_key * dst, const cache_key * src)
151 {
152 memcpy(dst, src, SQUID_MD5_DIGEST_LENGTH);
153 return dst;
154 }
155
156 void
157 storeKeyFree(const cache_key * key)
158 {
159 memFree((void *) key, MEM_MD5_DIGEST);
160 }
161
162 int
163 storeKeyHashBuckets(int nbuckets)
164 {
165 int n = 0x2000;
166
167 while (n < nbuckets)
168 n <<= 1;
169
170 return n;
171 }
172
173 int
174 storeKeyNull(const cache_key * key)
175 {
176 if (memcmp(key, null_key, SQUID_MD5_DIGEST_LENGTH) == 0)
177 return 1;
178 else
179 return 0;
180 }
181
182 void
183 storeKeyInit(void)
184 {
185 memset(null_key, '\0', SQUID_MD5_DIGEST_LENGTH);
186 }
187