TypedMsgHdr.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2018 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 
45 void
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 
84 int
86 {
87  Must(msg_iovlen == 1);
88  return data.type_;
89 }
90 
91 void
93 {
94  allocName();
95  name = addr;
96  msg_name = &name;
97  msg_namelen = SUN_LEN(&name);
98 }
99 
100 void
101 Ipc::TypedMsgHdr::checkType(int destType) const
102 {
103  Must(type() == destType);
104 }
105 
106 void
108 {
109  if (data.type_) {
110  Must(data.type_ == aType);
111  } else {
112  allocData();
113  data.type_ = aType;
114  }
115 }
116 
117 int
119 {
120  int n = 0;
121  getPod(n);
122  return n;
123 }
124 
125 void
127 {
128  putPod(n);
129 }
130 
131 void
133 {
134  const int length = getInt();
135  Must(length >= 0);
136  // String uses memcpy uncoditionally; TODO: SBuf eliminates this check
137  if (!length) {
138  s.clean();
139  return;
140  }
141 
142  Must(length <= maxSize);
143  // TODO: use SBuf.reserve() instead of a temporary buffer
144  char buf[maxSize];
145  getRaw(&buf, length);
146  s.limitInit(buf, length);
147 }
148 
149 void
151 {
152  Must(s.psize() <= maxSize);
153  putInt(s.psize());
154  putRaw(s.rawBuf(), s.psize());
155 }
156 
157 void
158 Ipc::TypedMsgHdr::getFixed(void *rawBuf, size_t rawSize) const
159 {
160  // no need to load size because it is constant
161  getRaw(rawBuf, rawSize);
162 }
163 
164 void
165 Ipc::TypedMsgHdr::putFixed(const void *rawBuf, size_t rawSize)
166 {
167  // no need to store size because it is constant
168  putRaw(rawBuf, rawSize);
169 }
170 
172 void
173 Ipc::TypedMsgHdr::getRaw(void *rawBuf, size_t rawSize) const
174 {
175  if (rawSize > 0) {
176  Must(rawSize <= data.size - offset);
177  memcpy(rawBuf, data.raw + offset, rawSize);
178  offset += rawSize;
179  }
180 }
181 
183 void
184 Ipc::TypedMsgHdr::putRaw(const void *rawBuf, size_t rawSize)
185 {
186  if (rawSize > 0) {
187  Must(rawSize <= sizeof(data.raw) - data.size);
188  memcpy(data.raw + data.size, rawBuf, rawSize);
189  data.size += rawSize;
190  }
191 }
192 
193 bool
195 {
196  struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
197  return cmsg &&
198  cmsg->cmsg_level == SOL_SOCKET &&
199  cmsg->cmsg_type == SCM_RIGHTS;
200 }
201 
202 void
204 {
205  Must(fd >= 0);
206  Must(!hasFd());
207  allocControl();
208 
209  const int fdCount = 1;
210 
211  struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
212  cmsg->cmsg_level = SOL_SOCKET;
213  cmsg->cmsg_type = SCM_RIGHTS;
214  cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
215 
216  int *fdStore = reinterpret_cast<int*>(SQUID_CMSG_DATA(cmsg));
217  memcpy(fdStore, &fd, fdCount * sizeof(int));
218  msg_controllen = cmsg->cmsg_len;
219 
220  Must(hasFd());
221 }
222 
223 int
225 {
226  Must(msg_control && msg_controllen);
227  Must(hasFd());
228 
229  struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
230  Must(cmsg->cmsg_level == SOL_SOCKET);
231  Must(cmsg->cmsg_type == SCM_RIGHTS);
232 
233  const int fdCount = 1;
234  const int *fdStore = reinterpret_cast<const int*>(SQUID_CMSG_DATA(cmsg));
235  int fd = -1;
236  memcpy(&fd, fdStore, fdCount * sizeof(int));
237  return fd;
238 }
239 
240 void
242 {
243  clear();
244  // no sync() like other clear() calls because the
245  // alloc*() below "sync()" the parts they allocate.
246  allocName();
247  allocData();
248  allocControl();
249 }
250 
252 void
254 {
255  Must(!msg_iovlen && !msg_iov);
256  msg_iovlen = 1;
257  msg_iov = ios;
258  ios[0].iov_base = &data;
259  ios[0].iov_len = sizeof(data);
260  data.type_ = 0;
261  data.size = 0;
262 }
263 
264 void
266 {
267  Must(!msg_name && !msg_namelen);
268  msg_name = &name;
269  msg_namelen = sizeof(name); // is that the right size?
270 }
271 
272 void
274 {
275  Must(!msg_control && !msg_controllen);
276  msg_control = &ctrl;
277  msg_controllen = sizeof(ctrl);
278 }
279 
void limitInit(const char *str, int len)
Definition: String.cc:94
int cmsg_level
Definition: cmsg.h:37
int cmsg_type
Definition: cmsg.h:38
void prepForReading()
reset and provide all buffers
Definition: TypedMsgHdr.cc:241
int type
Definition: errorpage.cc:78
void putInt(int n)
store an integer
Definition: TypedMsgHdr.cc:126
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
#define SQUID_CMSG_DATA(cmsg)
Definition: cmsg.h:51
unsigned int offset
data offset for the next get/put*() to start with
Definition: TypedMsgHdr.h:108
#define CMSG_LEN(len)
Definition: cmsg.h:77
void getFixed(void *raw, size_t size) const
always load size bytes
Definition: TypedMsgHdr.cc:158
int psize() const
Definition: SquidString.h:76
struct sockaddr_un name
same as .msg_name
Definition: TypedMsgHdr.h:88
bool hasFd() const
whether the message has a descriptor stored
Definition: TypedMsgHdr.cc:194
struct iovec ios[1]
same as .msg_iov[]
Definition: TypedMsgHdr.h:90
void const char HLPCB void * data
Definition: stub_helper.cc:16
char const * rawBuf() const
Definition: SquidString.h:85
Definition: cmsg.h:35
void * addr
Definition: membanger.c:46
struct Ipc::TypedMsgHdr::CtrlBuffer ctrl
same as .msg_control
int getInt() const
load an integer
Definition: TypedMsgHdr.cc:118
void const char * buf
Definition: stub_helper.cc:16
void address(const struct sockaddr_un &addr)
sets [dest.] address
Definition: TypedMsgHdr.cc:92
void putFd(int aFd)
stores descriptor
Definition: TypedMsgHdr.cc:203
void putString(const String &s)
store variable-length string
Definition: TypedMsgHdr.cc:150
void allocData()
initialize io vector with one io record
Definition: TypedMsgHdr.cc:253
struct msghdr with a known type, fixed-size I/O and control buffers
Definition: TypedMsgHdr.h:31
void checkType(int aType) const
throws if stored type is not aType
Definition: TypedMsgHdr.cc:101
Definition: cmsg.h:88
int type() const
returns stored type or zero if none
Definition: TypedMsgHdr.cc:85
TypedMsgHdr & operator=(const TypedMsgHdr &tmh)
Definition: TypedMsgHdr.cc:31
#define CMSG_FIRSTHDR(mhdr)
Definition: cmsg.h:59
void getString(String &s) const
load variable-length string
Definition: TypedMsgHdr.cc:132
void getRaw(void *raw, size_t size) const
low-level loading of exactly size bytes of raw data
Definition: TypedMsgHdr.cc:173
void clean()
Definition: String.cc:125
int getFd() const
returns stored descriptor
Definition: TypedMsgHdr.cc:224
void putRaw(const void *raw, size_t size)
low-level storage of exactly size bytes of raw data
Definition: TypedMsgHdr.cc:184
void setType(int aType)
sets message type; use MessageType enum
Definition: TypedMsgHdr.cc:107
#define SUN_LEN(ptr)
Definition: cmsg.h:113
void putFixed(const void *raw, size_t size)
always store size bytes
Definition: TypedMsgHdr.cc:165
struct Ipc::TypedMsgHdr::DataBuffer data
same as .msg_iov[0].iov_base
unsigned int cmsg_len
Definition: cmsg.h:36
#define SCM_RIGHTS
Definition: cmsg.h:118

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors