]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/TypedMsgHdr.cc
Boilerplate: update copyright blurbs on Squid helpers
[thirdparty/squid.git] / src / ipc / TypedMsgHdr.cc
CommitLineData
98d9bd29 1/*
98d9bd29
AR
2 * DEBUG: section 54 Interprocess Communication
3 *
4 */
5
f7f3304a 6#include "squid.h"
a67d2b2e 7#include "base/TextException.h"
98d9bd29 8#include "ipc/TypedMsgHdr.h"
5bed43d6 9#include "tools.h"
98d9bd29 10
074d6a40 11#include <cstring>
3d41e53a 12
98d9bd29
AR
13Ipc::TypedMsgHdr::TypedMsgHdr()
14{
e297be13 15 memset(this, 0, sizeof(*this));
5667a628 16 sync();
98d9bd29
AR
17}
18
19Ipc::TypedMsgHdr::TypedMsgHdr(const TypedMsgHdr &tmh)
20{
41d00cd3 21 memcpy(this, &tmh, sizeof(*this));
5667a628 22 sync();
98d9bd29
AR
23}
24
25Ipc::TypedMsgHdr &Ipc::TypedMsgHdr::operator =(const TypedMsgHdr &tmh)
26{
5667a628 27 if (this != &tmh) { // skip assignment to self
41d00cd3 28 memcpy(this, &tmh, sizeof(*this));
5667a628
AR
29 sync();
30 }
31 return *this;
98d9bd29
AR
32}
33
34// update msghdr and ios pointers based on msghdr counters
35void Ipc::TypedMsgHdr::sync()
36{
5667a628
AR
37 if (msg_name) { // we have a name
38 msg_name = &name;
39 } else {
40 Must(!msg_namelen && !msg_name);
41 }
42
43 if (msg_iov) { // we have a data component
44 Must(msg_iovlen == 1);
45 msg_iov = ios;
46 ios[0].iov_base = &data;
47 Must(ios[0].iov_len == sizeof(data));
48 } else {
49 Must(!msg_iovlen && !msg_iov);
50 }
51
52 if (msg_control) { // we have a control component
53 Must(msg_controllen > 0);
54 msg_control = &ctrl;
55 } else {
56 Must(!msg_controllen && !msg_control);
57 }
8822ebee 58 offset = 0;
98d9bd29
AR
59}
60
98d9bd29
AR
61int
62Ipc::TypedMsgHdr::type() const
63{
5667a628
AR
64 Must(msg_iovlen == 1);
65 return data.type_;
98d9bd29
AR
66}
67
68void
69Ipc::TypedMsgHdr::address(const struct sockaddr_un& addr)
70{
5667a628
AR
71 allocName();
72 name = addr;
98d9bd29
AR
73 msg_name = &name;
74 msg_namelen = SUN_LEN(&name);
75}
76
77void
8822ebee 78Ipc::TypedMsgHdr::checkType(int destType) const
98d9bd29 79{
5667a628 80 Must(type() == destType);
98d9bd29
AR
81}
82
83void
8822ebee 84Ipc::TypedMsgHdr::setType(int aType)
98d9bd29 85{
8822ebee
AR
86 if (data.type_) {
87 Must(data.type_ == aType);
88 } else {
89 allocData();
90 data.type_ = aType;
91 }
92}
93
94int
95Ipc::TypedMsgHdr::getInt() const
96{
97 int n = 0;
98 getPod(n);
99 return n;
100}
101
102void
103Ipc::TypedMsgHdr::putInt(const int n)
104{
105 putPod(n);
106}
107
108void
109Ipc::TypedMsgHdr::getString(String &s) const
110{
111 const int length = getInt();
112 Must(length >= 0);
113 // String uses memcpy uncoditionally; TODO: SBuf eliminates this check
114 if (!length) {
115 s.clean();
116 return;
117 }
118
119 Must(length <= maxSize);
120 // TODO: use SBuf.reserve() instead of a temporary buffer
f867ba6b 121 char buf[maxSize];
8822ebee
AR
122 getRaw(&buf, length);
123 s.limitInit(buf, length);
124}
125
126void
127Ipc::TypedMsgHdr::putString(const String &s)
128{
129 Must(s.psize() <= maxSize);
130 putInt(s.psize());
131 putRaw(s.rawBuf(), s.psize());
132}
133
134void
9dca980d 135Ipc::TypedMsgHdr::getFixed(void *rawBuf, size_t rawSize) const
8822ebee
AR
136{
137 // no need to load size because it is constant
9dca980d 138 getRaw(rawBuf, rawSize);
8822ebee
AR
139}
140
141void
9dca980d 142Ipc::TypedMsgHdr::putFixed(const void *rawBuf, size_t rawSize)
8822ebee
AR
143{
144 // no need to store size because it is constant
9dca980d 145 putRaw(rawBuf, rawSize);
8822ebee
AR
146}
147
148/// low-level loading of exactly size bytes of raw data
149void
9dca980d 150Ipc::TypedMsgHdr::getRaw(void *rawBuf, size_t rawSize) const
8822ebee 151{
9dca980d
AJ
152 if (rawSize > 0) {
153 Must(rawSize <= data.size - offset);
154 memcpy(rawBuf, data.raw + offset, rawSize);
155 offset += rawSize;
8822ebee
AR
156 }
157}
158
159/// low-level storage of exactly size bytes of raw data
160void
9dca980d 161Ipc::TypedMsgHdr::putRaw(const void *rawBuf, size_t rawSize)
8822ebee 162{
9dca980d
AJ
163 if (rawSize > 0) {
164 Must(rawSize <= sizeof(data.raw) - data.size);
165 memcpy(data.raw + data.size, rawBuf, rawSize);
166 data.size += rawSize;
8822ebee 167 }
98d9bd29
AR
168}
169
9b440559
CT
170bool
171Ipc::TypedMsgHdr::hasFd() const
172{
097f803c
A
173 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
174 return cmsg &&
175 cmsg->cmsg_level == SOL_SOCKET &&
176 cmsg->cmsg_type == SCM_RIGHTS;
9b440559
CT
177}
178
98d9bd29
AR
179void
180Ipc::TypedMsgHdr::putFd(int fd)
181{
5667a628 182 Must(fd >= 0);
9b440559 183 Must(!hasFd());
5667a628 184 allocControl();
98d9bd29 185
5667a628 186 const int fdCount = 1;
98d9bd29 187
5667a628
AR
188 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
189 cmsg->cmsg_level = SOL_SOCKET;
190 cmsg->cmsg_type = SCM_RIGHTS;
191 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
98d9bd29
AR
192
193 int *fdStore = reinterpret_cast<int*>(CMSG_DATA(cmsg));
41d00cd3 194 memcpy(fdStore, &fd, fdCount * sizeof(int));
98d9bd29 195 msg_controllen = cmsg->cmsg_len;
9b440559
CT
196
197 Must(hasFd());
98d9bd29
AR
198}
199
200int
201Ipc::TypedMsgHdr::getFd() const
202{
5667a628 203 Must(msg_control && msg_controllen);
9b440559 204 Must(hasFd());
98d9bd29 205
5667a628
AR
206 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
207 Must(cmsg->cmsg_level == SOL_SOCKET);
208 Must(cmsg->cmsg_type == SCM_RIGHTS);
98d9bd29 209
5667a628 210 const int fdCount = 1;
98d9bd29 211 const int *fdStore = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
5667a628 212 int fd = -1;
41d00cd3 213 memcpy(&fd, fdStore, fdCount * sizeof(int));
5667a628 214 return fd;
98d9bd29
AR
215}
216
217void
218Ipc::TypedMsgHdr::prepForReading()
219{
e297be13 220 memset(this, 0, sizeof(*this));
5667a628
AR
221 allocName();
222 allocData();
223 allocControl();
98d9bd29
AR
224}
225
226/// initialize io vector with one io record
227void
228Ipc::TypedMsgHdr::allocData()
229{
5667a628
AR
230 Must(!msg_iovlen && !msg_iov);
231 msg_iovlen = 1;
232 msg_iov = ios;
233 ios[0].iov_base = &data;
234 ios[0].iov_len = sizeof(data);
235 data.type_ = 0;
236 data.size = 0;
98d9bd29
AR
237}
238
239void
240Ipc::TypedMsgHdr::allocName()
241{
5667a628 242 Must(!msg_name && !msg_namelen);
98d9bd29
AR
243 msg_name = &name;
244 msg_namelen = sizeof(name); // is that the right size?
245}
246
247void
248Ipc::TypedMsgHdr::allocControl()
249{
5667a628
AR
250 Must(!msg_control && !msg_controllen);
251 msg_control = &ctrl;
252 msg_controllen = sizeof(ctrl);
98d9bd29 253}