Skip to content

Commit 9929f2c

Browse files
ankor2023yadij
authored andcommitted
Reduce UDS/segment name clashes across same-service instances (#2023)
Add a PID file name hash to the names of the shared memory segments and Unix Domain Sockets. Since all instances running on the same host are supposed to have unique PID files, this addition significantly reduces the probability of name clashes when running multiple Squid instances with the same service name (i.e. the same `squid -n` parameter value that defaults to "squid"). A clash may still happen if two different PID file names have the same hash or if multiple instances disable PID file management with `pid_filename none`. Clashes may also happen in environments where Squid does not even use service name for naming shared memory segments. Examples of UDS and shared memory segment names (while using default service name): /var/run/squid/squid-SLWQ-kid-1.ipc /var/run/squid/squid-SLWQ-coordinator.ipc /dev/shm/squid-SLWQ-tls_session_cache.shm /dev/shm/squid-SLWQ-transients_map_slices.shm This change is a reference point for automated CONTRIBUTORS updates.
1 parent e35bd18 commit 9929f2c

File tree

8 files changed

+89
-10
lines changed

8 files changed

+89
-10
lines changed

CONTRIBUTORS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Thank you!
5555
Andrew Tridgell
5656
5757
Andrey Shorin <[email protected]>
58-
ankor2023 <138755079+ankor2023@users.noreply.github.com>
58+
Ankor <ankor2023@gmail.com>
5959
Anonymous <[email protected]>
6060
Anonymous <[email protected]>
6161
Anonymous Pootle User

src/Instance.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "debug/Messages.h"
1212
#include "fs_io.h"
1313
#include "Instance.h"
14+
#include "md5.h"
1415
#include "parser/Tokenizer.h"
1516
#include "sbuf/Stream.h"
1617
#include "SquidConfig.h"
@@ -222,3 +223,43 @@ Instance::WriteOurPid()
222223
debugs(50, Important(23), "Created " << TheFile);
223224
}
224225

226+
/// A hash that is likely to be unique across instances running on the same host
227+
/// because such concurrent instances should use unique PID filenames.
228+
/// All instances with disabled PID file maintenance have the same hash value.
229+
/// \returns a 4-character string suitable for use in file names and similar contexts
230+
static SBuf
231+
PidFilenameHash()
232+
{
233+
uint8_t hash[SQUID_MD5_DIGEST_LENGTH];
234+
235+
SquidMD5_CTX ctx;
236+
SquidMD5Init(&ctx);
237+
const auto name = PidFilenameCalc();
238+
SquidMD5Update(&ctx, name.rawContent(), name.length());
239+
SquidMD5Final(hash, &ctx);
240+
241+
// converts raw hash byte at a given position to a filename-suitable character
242+
const auto hashAt = [&hash](const size_t idx) {
243+
const auto safeChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
244+
return safeChars[hash[idx] % strlen(safeChars)];
245+
};
246+
247+
SBuf buf;
248+
buf.appendf("%c%c%c%c", hashAt(0), hashAt(1), hashAt(2), hashAt(3));
249+
return buf;
250+
}
251+
252+
SBuf
253+
Instance::NamePrefix(const char * const head, const char * const tail)
254+
{
255+
SBuf buf(head);
256+
buf.append(service_name);
257+
buf.append("-");
258+
buf.append(PidFilenameHash());
259+
if (tail) {
260+
// TODO: Remove leading "-" from callers and explicitly add it here.
261+
buf.append(tail);
262+
}
263+
return buf;
264+
}
265+

src/Instance.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#ifndef SQUID_SRC_INSTANCE_H
1010
#define SQUID_SRC_INSTANCE_H
1111

12+
#include "sbuf/forward.h"
13+
1214
#if HAVE_SYS_TYPES_H
1315
#include <sys/types.h>
1416
#endif
@@ -30,6 +32,14 @@ void WriteOurPid();
3032
/// Throws if PID file maintenance is disabled.
3133
pid_t Other();
3234

35+
/// A service_name-derived string that is likely to be unique across all Squid
36+
/// instances concurrently running on the same host (as long as they do not
37+
/// disable PID file maintenance).
38+
/// \param head is used at the beginning of the generated name
39+
/// \param tail is used at the end of the generated name (when not nil)
40+
/// \returns a head-...tail string suitable for making file and shm segment names
41+
SBuf NamePrefix(const char *head, const char *tail = nullptr);
42+
3343
} // namespace Instance
3444

3545
#endif /* SQUID_SRC_INSTANCE_H */

src/Makefile.am

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,7 @@ tests_testRock_SOURCES = \
10331033
HttpHeaderTools.h \
10341034
HttpReply.cc \
10351035
tests/stub_HttpRequest.cc \
1036+
tests/stub_Instance.cc \
10361037
LogTags.cc \
10371038
MasterXaction.cc \
10381039
MasterXaction.h \
@@ -1203,6 +1204,7 @@ tests_testUfs_SOURCES = \
12031204
HttpHeaderTools.h \
12041205
HttpReply.cc \
12051206
tests/stub_HttpRequest.cc \
1207+
tests/stub_Instance.cc \
12061208
LogTags.cc \
12071209
MasterXaction.cc \
12081210
MasterXaction.h \
@@ -1375,6 +1377,7 @@ tests_testStore_SOURCES = \
13751377
HttpHeaderTools.h \
13761378
tests/stub_HttpReply.cc \
13771379
tests/stub_HttpRequest.cc \
1380+
tests/stub_Instance.cc \
13781381
MasterXaction.cc \
13791382
MasterXaction.h \
13801383
MemBuf.cc \
@@ -1538,6 +1541,7 @@ tests_testDiskIO_SOURCES = \
15381541
HttpHeaderTools.h \
15391542
HttpReply.cc \
15401543
tests/stub_HttpRequest.cc \
1544+
tests/stub_Instance.cc \
15411545
LogTags.cc \
15421546
MasterXaction.cc \
15431547
MasterXaction.h \
@@ -1801,6 +1805,7 @@ tests_testHttpRange_SOURCES = \
18011805
HttpReply.cc \
18021806
HttpRequest.cc \
18031807
tests/stub_HttpUpgradeProtocolAccess.cc \
1808+
tests/stub_Instance.cc \
18041809
IoStats.h \
18051810
tests/stub_IpcIoFile.cc \
18061811
LogTags.cc \
@@ -2061,6 +2066,7 @@ tests_testHttpReply_SOURCES = \
20612066
tests/testHttpReply.cc \
20622067
HttpReply.h \
20632068
tests/stub_HttpRequest.cc \
2069+
tests/stub_Instance.cc \
20642070
MasterXaction.cc \
20652071
MasterXaction.h \
20662072
MemBuf.cc \
@@ -2188,6 +2194,7 @@ tests_testHttpRequest_SOURCES = \
21882194
tests/testHttpRequest.cc \
21892195
tests/testHttpRequestMethod.cc \
21902196
tests/stub_HttpUpgradeProtocolAccess.cc \
2197+
tests/stub_Instance.cc \
21912198
IoStats.h \
21922199
tests/stub_IpcIoFile.cc \
21932200
LogTags.cc \
@@ -2485,6 +2492,7 @@ tests_testCacheManager_SOURCES = \
24852492
HttpReply.cc \
24862493
HttpRequest.cc \
24872494
tests/stub_HttpUpgradeProtocolAccess.cc \
2495+
tests/stub_Instance.cc \
24882496
IoStats.h \
24892497
tests/stub_IpcIoFile.cc \
24902498
LogTags.cc \

src/ipc/Port.cc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
#include "comm/Connection.h"
1414
#include "comm/Read.h"
1515
#include "CommCalls.h"
16+
#include "Instance.h"
1617
#include "ipc/Port.h"
1718
#include "sbuf/Stream.h"
19+
#include "sbuf/StringConvert.h"
1820
#include "tools.h"
1921
#include "util.h"
2022

@@ -52,9 +54,8 @@ bool Ipc::Port::doneAll() const
5254
String Ipc::Port::MakeAddr(const char* processLabel, int id)
5355
{
5456
assert(id >= 0);
55-
String addr = channelPathPfx;
56-
addr.append(service_name.c_str());
57-
addr.append(processLabel);
57+
String addr;
58+
addr.append(SBufToString(Instance::NamePrefix(channelPathPfx, processLabel)));
5859
addr.append('-');
5960
addr.append(xitoa(id));
6061
addr.append(".ipc");
@@ -66,9 +67,7 @@ Ipc::Port::CoordinatorAddr()
6667
{
6768
static String coordinatorAddr;
6869
if (!coordinatorAddr.size()) {
69-
coordinatorAddr= channelPathPfx;
70-
coordinatorAddr.append(service_name.c_str());
71-
coordinatorAddr.append(coordinatorAddrLabel);
70+
coordinatorAddr.append(SBufToString(Instance::NamePrefix(channelPathPfx, coordinatorAddrLabel)));
7271
coordinatorAddr.append(".ipc");
7372
}
7473
return coordinatorAddr;

src/ipc/mem/Segment.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
#include "compat/shm.h"
1414
#include "debug/Stream.h"
1515
#include "fatal.h"
16+
#include "Instance.h"
1617
#include "ipc/mem/Segment.h"
17-
#include "sbuf/SBuf.h"
18+
#include "sbuf/StringConvert.h"
1819
#include "SquidConfig.h"
1920
#include "tools.h"
2021

@@ -277,8 +278,7 @@ Ipc::Mem::Segment::GenerateName(const char *id)
277278
if (name[name.size()-1] != '/')
278279
name.append('/');
279280
} else {
280-
name.append('/');
281-
name.append(service_name.c_str());
281+
name.append(SBufToString(Instance::NamePrefix("/")));
282282
name.append('-');
283283
}
284284

src/tests/Stub.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ STUB_SOURCE = \
2222
tests/stub_HttpReply.cc \
2323
tests/stub_HttpRequest.cc \
2424
tests/stub_HttpUpgradeProtocolAccess.cc \
25+
tests/stub_Instance.cc \
2526
tests/stub_IpcIoFile.cc \
2627
tests/stub_MemBuf.cc \
2728
tests/stub_MemObject.cc \

src/tests/stub_Instance.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (C) 1996-2025 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+
#include "squid.h"
10+
#include "Instance.h"
11+
#include "sbuf/SBuf.h"
12+
13+
#define STUB_API "Instance.cc"
14+
#include "tests/STUB.h"
15+
16+
void Instance::ThrowIfAlreadyRunning() STUB
17+
void Instance::WriteOurPid() STUB
18+
pid_t Instance::Other() STUB_RETVAL({})
19+
SBuf Instance::NamePrefix(const char *, const char *) STUB_RETVAL_NOP(SBuf("squid-0"))
20+

0 commit comments

Comments
 (0)