TypedMsgHdr.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 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 54 Interprocess Communication */
10
11#include "squid.h"
12#include "base/TextException.h"
13#include "ipc/TypedMsgHdr.h"
14#include "SquidString.h"
15#include "tools.h"
16
17#include <cstring>
18
20{
21 clear();
22 sync();
23}
24
26{
27 clear();
28 operator =(tmh);
29}
30
32{
33 if (this != &tmh) { // skip assignment to self
34 memcpy(static_cast<msghdr*>(this), static_cast<const msghdr*>(&tmh), sizeof(msghdr));
35 name = tmh.name;
36 memcpy(&ios, &tmh.ios, sizeof(ios));
37 data = tmh.data;
38 ctrl = tmh.ctrl;
39 offset = tmh.offset;
40 sync();
41 }
42 return *this;
43}
44
45void
47{
48 // may be called from the constructor, with object fields uninitialized
49 memset(static_cast<msghdr*>(this), 0, sizeof(msghdr));
50 memset(&name, 0, sizeof(name));
51 memset(&ios, 0, sizeof(ios));
52 data = DataBuffer();
53 ctrl = CtrlBuffer();
54 offset = 0;
55}
56
57// update msghdr and ios pointers based on msghdr counters
59{
60 if (msg_name) { // we have a name
61 msg_name = &name;
62 } else {
63 Must(!msg_namelen && !msg_name);
64 }
65
66 if (msg_iov) { // we have a data component
67 Must(msg_iovlen == 1);
68 msg_iov = ios;
69 ios[0].iov_base = &data;
70 Must(ios[0].iov_len == sizeof(data));
71 } else {
72 Must(!msg_iovlen && !msg_iov);
73 }
74
75 if (msg_control) { // we have a control component
76 Must(msg_controllen > 0);
77 msg_control = &ctrl;
78 } else {
79 Must(!msg_controllen && !msg_control);
80 }
81 offset = 0;
82}
83
84void
86{
87 allocName();
88 name = addr;
89 msg_name = &name;
90 msg_namelen = SUN_LEN(&name);
91}
92
93void
94Ipc::TypedMsgHdr::checkType(int destType) const
95{
96 Must(rawType() == destType);
97}
98
99void
101{
102 if (data.type_) {
103 Must(data.type_ == aType);
104 } else {
105 allocData();
106 data.type_ = aType;
107 }
108}
109
110int
112{
113 int n = 0;
114 getPod(n);
115 return n;
116}
117
118void
120{
121 putPod(n);
122}
123
124void
126{
127 const int length = getInt();
128 Must(length >= 0);
129 // String uses memcpy uncoditionally; TODO: SBuf eliminates this check
130 if (!length) {
131 s.clean();
132 return;
133 }
134
135 Must(length <= maxSize);
136 // TODO: use SBuf.reserve() instead of a temporary buffer
137 char buf[maxSize];
138 getRaw(&buf, length);
139 s.assign(buf, length);
140}
141
142void
144{
145 Must(s.psize() <= maxSize);
146 putInt(s.psize());
147 putRaw(s.rawBuf(), s.psize());
148}
149
150void
151Ipc::TypedMsgHdr::getFixed(void *rawBuf, size_t rawSize) const
152{
153 // no need to load size because it is constant
154 getRaw(rawBuf, rawSize);
155}
156
157void
158Ipc::TypedMsgHdr::putFixed(const void *rawBuf, size_t rawSize)
159{
160 // no need to store size because it is constant
161 putRaw(rawBuf, rawSize);
162}
163
165void
166Ipc::TypedMsgHdr::getRaw(void *rawBuf, size_t rawSize) const
167{
168 if (rawSize > 0) {
169 Must(rawSize <= data.size - offset);
170 memcpy(rawBuf, data.raw + offset, rawSize);
171 offset += rawSize;
172 }
173}
174
176void
177Ipc::TypedMsgHdr::putRaw(const void *rawBuf, size_t rawSize)
178{
179 if (rawSize > 0) {
180 Must(rawSize <= sizeof(data.raw) - data.size);
181 memcpy(data.raw + data.size, rawBuf, rawSize);
182 data.size += rawSize;
183 }
184}
185
186bool
188{
189 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
190 return cmsg &&
191 cmsg->cmsg_level == SOL_SOCKET &&
192 cmsg->cmsg_type == SCM_RIGHTS;
193}
194
195void
197{
198 Must(fd >= 0);
199 Must(!hasFd());
200 allocControl();
201
202 const int fdCount = 1;
203
204 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
205 cmsg->cmsg_level = SOL_SOCKET;
206 cmsg->cmsg_type = SCM_RIGHTS;
207 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
208
209 int *fdStore = reinterpret_cast<int*>(SQUID_CMSG_DATA(cmsg));
210 memcpy(fdStore, &fd, fdCount * sizeof(int));
211 msg_controllen = cmsg->cmsg_len;
212
213 Must(hasFd());
214}
215
216int
218{
219 Must(msg_control && msg_controllen);
220 Must(hasFd());
221
222 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
223 Must(cmsg->cmsg_level == SOL_SOCKET);
224 Must(cmsg->cmsg_type == SCM_RIGHTS);
225
226 const int fdCount = 1;
227 const int *fdStore = reinterpret_cast<const int*>(SQUID_CMSG_DATA(cmsg));
228 int fd = -1;
229 memcpy(&fd, fdStore, fdCount * sizeof(int));
230 return fd;
231}
232
233void
235{
236 clear();
237 // no sync() like other clear() calls because the
238 // alloc*() below "sync()" the parts they allocate.
239 allocName();
240 allocData();
241 allocControl();
242}
243
245void
247{
248 Must(!msg_iovlen && !msg_iov);
249 msg_iovlen = 1;
250 msg_iov = ios;
251 ios[0].iov_base = &data;
252 ios[0].iov_len = sizeof(data);
253 data.type_ = 0;
254 data.size = 0;
255}
256
257void
259{
260 Must(!msg_name && !msg_namelen);
261 msg_name = &name;
262 msg_namelen = sizeof(name); // is that the right size?
263}
264
265void
267{
268 Must(!msg_control && !msg_controllen);
269 msg_control = &ctrl;
270 msg_controllen = sizeof(ctrl);
271}
272
#define Must(condition)
Definition: TextException.h:75
struct msghdr with a known type, fixed-size I/O and control buffers
Definition: TypedMsgHdr.h:35
struct Ipc::TypedMsgHdr::CtrlBuffer ctrl
same as .msg_control
void getRaw(void *raw, size_t size) const
low-level loading of exactly size bytes of raw data
Definition: TypedMsgHdr.cc:166
int getFd() const
returns stored descriptor
Definition: TypedMsgHdr.cc:217
unsigned int offset
data offset for the next get/put*() to start with
Definition: TypedMsgHdr.h:111
void putRaw(const void *raw, size_t size)
low-level storage of exactly size bytes of raw data
Definition: TypedMsgHdr.cc:177
void putString(const String &s)
store variable-length string
Definition: TypedMsgHdr.cc:143
TypedMsgHdr & operator=(const TypedMsgHdr &tmh)
Definition: TypedMsgHdr.cc:31
void putFd(int aFd)
stores descriptor
Definition: TypedMsgHdr.cc:196
void getFixed(void *raw, size_t size) const
always load size bytes
Definition: TypedMsgHdr.cc:151
struct Ipc::TypedMsgHdr::DataBuffer data
same as .msg_iov[0].iov_base
void putInt(int n)
store an integer
Definition: TypedMsgHdr.cc:119
void getString(String &s) const
load variable-length string
Definition: TypedMsgHdr.cc:125
bool hasFd() const
whether the message has a descriptor stored
Definition: TypedMsgHdr.cc:187
struct iovec ios[1]
same as .msg_iov[]
Definition: TypedMsgHdr.h:93
struct sockaddr_un name
same as .msg_name
Definition: TypedMsgHdr.h:91
void allocData()
initialize io vector with one io record
Definition: TypedMsgHdr.cc:246
void checkType(int aType) const
Definition: TypedMsgHdr.cc:94
void putFixed(const void *raw, size_t size)
always store size bytes
Definition: TypedMsgHdr.cc:158
void prepForReading()
reset and provide all buffers
Definition: TypedMsgHdr.cc:234
void setType(int aType)
sets message type; use MessageType enum
Definition: TypedMsgHdr.cc:100
int getInt() const
load an integer
Definition: TypedMsgHdr.cc:111
void address(const struct sockaddr_un &addr)
sets [dest.] address
Definition: TypedMsgHdr.cc:85
int psize() const
Definition: SquidString.h:77
void clean()
Definition: String.cc:103
void assign(const char *str, int len)
Definition: String.cc:78
char const * rawBuf() const
Definition: SquidString.h:86
#define CMSG_LEN(len)
Definition: cmsg.h:77
#define CMSG_FIRSTHDR(mhdr)
Definition: cmsg.h:59
#define SCM_RIGHTS
Definition: cmsg.h:118
#define SUN_LEN(ptr)
Definition: cmsg.h:113
#define SQUID_CMSG_DATA(cmsg)
Definition: cmsg.h:51
Definition: cmsg.h:35
int cmsg_type
Definition: cmsg.h:38
int cmsg_level
Definition: cmsg.h:37
unsigned int cmsg_len
Definition: cmsg.h:36
Definition: cmsg.h:88

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors