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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors