XRootD
Loading...
Searching...
No Matches
XrdOucPup.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O u c P u p . c c */
4/* */
5/* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#include <cerrno>
32#include <sys/uio.h>
33#include <netinet/in.h>
34#include <cinttypes>
35#include <cstdio>
36#include <cstring>
37
38#ifdef WIN32
39#include <direct.h>
40#include "XrdSys/XrdWin32.hh"
41#endif
42
43#include "XrdOuc/XrdOucPup.hh"
44#include "XrdSys/XrdSysError.hh"
47
48/******************************************************************************/
49/* P a c k */
50/******************************************************************************/
51
52int XrdOucPup::Pack(struct iovec **iovP,
53 const char *data,
54 unsigned short &buff)
55{
56 unsigned short dlen;
57 struct iovec *vP = *iovP;
58
59// Pack the data as "<short len><char>" if data is present or "<short 0>" o/w.
60// When data is present, the null byte is always included.
61//
62 vP->iov_base = (char *)&buff; vP->iov_len = sizeof(buff); vP++;
63
64 if (data)
65 {dlen = static_cast<unsigned short>(strlen(data)+1);
66 buff = htons(dlen);
67 vP->iov_base = (char *)data; vP->iov_len = dlen; vP++;
68 } else {buff = 0; dlen = 0;}
69
70 *iovP = vP;
71 return dlen+sizeof(buff);
72}
73
74/******************************************************************************/
75
76int XrdOucPup::Pack(struct iovec **iovP,
77 const char *data,
78 unsigned short &buff,
79 int dlen)
80{
81 struct iovec *vP = *iovP;
82
83 vP->iov_base = (char *)&buff; vP->iov_len = sizeof(buff); vP++;
84
85 if (data)
86 {buff = htons(static_cast<unsigned short>(dlen));
87 vP->iov_base = (char *)data; vP->iov_len = dlen; vP++;
88 } else {buff = 0; dlen = 0;}
89
90 *iovP = vP;
91 return dlen+sizeof(buff);
92}
93
94/******************************************************************************/
95
96int XrdOucPup::Pack(char **buff,
97 const char *data,
98 int dlen)
99{
100 char *bp = *buff;
101 unsigned short xlen;
102
103 if (data)
104 {if (dlen < 0) dlen = strlen(data)+1;
105 xlen = htons(static_cast<unsigned short>(dlen));
106 memcpy(bp, &xlen, sizeof(xlen)); bp += sizeof(xlen);
107 memcpy(bp, data, dlen);
108 bp += dlen;
109 } else {*bp++ = '\0'; *bp++ = '\0'; dlen = 0;}
110
111 *buff = bp;
112 return dlen+sizeof(xlen);
113}
114
115/******************************************************************************/
116
117int XrdOucPup::Pack(char **buff,
118 unsigned int data)
119{
120 unsigned int netData = htonl(data);
121 char *bp = *buff;
122
123 if (netData & PT_Mask)
124 {*bp = static_cast<char>(PT_int);
125 memcpy(bp+1, &netData, sizeof(netData));
126 *buff = bp + sizeof(netData)+1;
127 return sizeof(netData)+1;
128 }
129 (*(char *)&netData) |= PT_int | PT_Inline;
130 memcpy(bp, &netData, sizeof(netData));
131 *buff = bp + sizeof(netData);
132 return sizeof(netData);
133}
134
135/******************************************************************************/
136
137int XrdOucPup::Pack(struct iovec *iovP, struct iovec *iovE, XrdOucPupArgs *pup,
138 char *base, char *Work)
139{
140 static char Nil[] = {PT_char, '\0'};
141 static const int Sz16 = sizeof(short) + 1;
142 static const int Sz32 = sizeof(int) + 1;
143 static const int Sz64 = sizeof(long long) + 1;
144 struct iovec *vP = iovP;
145 XrdOucPupArgs *pP = pup;
146 char *wP = Work;
147 int Dtype, dlen = 0, TotLen = 0;
148
149 unsigned long long n64;
150 unsigned int n32;
151 unsigned short n16;
152
153 union {unsigned long long *B64;
154 unsigned int *B32;
155 unsigned short *B16;
156 char **B08;} Base;
157
158 Dtype = pP->Dtype;
159 do {Base.B08 = (char **)(base + pP->Doffs);
160 //std::cerr <<"arg " <<pP-pup <<" type " <<Dtype <<' '
161 // <<(Names->NList[pP->Name] ? Names->NList[pP->Name] : "?") <<std::endl;
162 switch(Dtype)
163 {case PT_char:
164/* Null Pointer */ if (!*Base.B08) {vP->iov_base = Nil; vP->iov_len = 2;
165 vP++; TotLen += 2; break;
166 }
167 dlen = (pP->Dlen < 0 ? strlen(*Base.B08)+1 : pP->Dlen);
168/* Full String */ if (dlen > MaxLen)
169 return eMsg("string too long packing", int(pP-pup), pP);
170 if (vP >= iovE)
171 return eMsg("too many args packing", int(pP-pup), pP);
172 n16 = htons(static_cast<unsigned short>(dlen));
173 vP->iov_base = wP; vP->iov_len = sizeof(n16); vP++;
174 memcpy(wP, &n16, sizeof(n16)); wP += sizeof(n16);
175 vP->iov_base = *Base.B08; vP->iov_len = dlen; vP++;
176 TotLen += dlen + sizeof(n16);
177 break;
178
179 case PT_short:
180 n16 = htons(*Base.B16);
181 *wP = static_cast<char>(PT_short);
182 memcpy(wP+1, &n16, sizeof(n16));
183 vP->iov_base = wP; vP->iov_len = Sz16; vP++;
184 wP += Sz16; TotLen += Sz16; dlen = sizeof(n16);
185 break;
186
187 case PT_int:
188 n32 = htonl(*Base.B32);
189 *wP = static_cast<char>(PT_int);
190 memcpy(wP+1, &n32, sizeof(n32));
191 vP->iov_base = wP; vP->iov_len = Sz32; vP++;
192 wP += Sz32; TotLen += Sz32; dlen = sizeof(n32);
193 break;
194
195 case PT_longlong:
196 h2nll(*Base.B64, n64);
197 *wP = static_cast<char>(PT_longlong);
198 memcpy(wP+1, &n64, sizeof(n64));
199 vP->iov_base = wP; vP->iov_len = Sz64; vP++;
200 wP += Sz64; TotLen += Sz64; dlen = sizeof(n64);
201 break;
202
203 case PT_special: break;
204
205 case PT_Fence: break;
206 case PT_Ignore: break;
207
208 case PT_MandS:
209 case PT_Mark:
210 *Base.B08 = (char *)vP;
211 if (pP->Dtype == PT_Mark) break;
212 vP++;
213 break;
214
215 case PT_Skip:
216 vP++;
217 break;
218
219 case PT_Datlen:
220 *Base.B32 = dlen;
221 break;
222
223 case PT_Totlen:
224 *Base.B32 = TotLen;
225 break;
226
227 case PT_EndFill:
228 *Base.B16 = htons(static_cast<unsigned short>(TotLen));
229 return static_cast<int>(vP-iovP);
230
231 case PT_End:
232 return static_cast<int>(vP-iovP);
233
234 default: {}
235 }
236 pP++;
237 Dtype = pP->Dtype;
238 } while(vP < iovE || (vP==iovE && Dtype != PT_Skip && (Dtype & PT_MaskD)));
239
240// We over-ran the iovec array
241//
242 return eMsg("arg list too long packing", int(pP-pup), pup);
243}
244
245/******************************************************************************/
246/* U n p a c k */
247/******************************************************************************/
248
249
250int XrdOucPup::Unpack( char **buff,
251 const char *bend,
252 char **data,
253 int &dlen)
254{
255 unsigned short temp;
256 char *bnxt = *buff;
257
258// Grab the length but make sure it's within bounds
259//
260 if ((bnxt = bnxt+sizeof(temp)) > bend) return 0;
261 memcpy(&temp, *buff, sizeof(temp));
262 dlen = static_cast<int>(ntohs(temp));
263
264// Now grab the data
265//
266 if (dlen) {*data = (char *)bnxt; bnxt += dlen;}
267 else *data = 0;
268 *buff = bnxt;
269 return (bnxt <= bend);
270}
271
272/******************************************************************************/
273
274int XrdOucPup::Unpack(const char *buff, const char *bend,
275 XrdOucPupArgs *pup, char *base)
276{
277 const char *bp = buff, *dp;
278 XrdOucPupArgs *uP = pup;
279 int dlen = 0, Dtype, Aok = 0, Done = 0;
280 union {unsigned long long b64;
281 unsigned int b32;
282 unsigned short b16;
283 unsigned char b08;} Temp;
284
285 union {unsigned long long *B64;
286 unsigned int *B32;
287 unsigned short *B16;
288 char **B08;} Base;
289
290
291 while(!Done)
292 {Base.B08 = (char **)(base+uP->Doffs);
293 if (uP->Dtype & PT_MaskD)
294 {switch(uP->Dtype)
295 {case PT_Fence: Aok = 1; break;
296 case PT_Datlen: *Base.B32 = dlen; break;
297 case PT_End:
298 case PT_EndFill: Done = 1; uP--; break;
299 default: {}
300 }
301 uP++; continue;
302 }
303 if (bp+2 > bend)
304 {if (bp == bend && Aok) {Done = 1; uP--; break;}
305 return eMsg("buffer overrun unpacking", int(uP-pup), uP);
306 }
307 if (uP->Dtype == PT_char && !(*bp & PT_short))
308 {memcpy(&Temp.b16, bp, sizeof(unsigned short));
309 dlen = static_cast<int>(ntohs(Temp.b16));
310 bp += sizeof(unsigned short);
311 if (dlen)
312 if (bp+dlen > bend)
313 return eMsg("buffer overrun unpacking", int(uP-pup), uP);
314 else *Base.B08 = (char *)bp;
315 else if (!Aok) break;
316 else *Base.B08 = 0;
317 } else {
318 Dtype = static_cast<int>(*bp & PT_MaskT);
319 if ((unsigned char)Dtype != uP->Dtype)
320 return eMsg("arg/data mismatch unpacking", int(uP-pup), uP);
321 if (!(dlen = (*bp & PT_MaskB)>>3)) dlen = sizeof(unsigned short);
322 dp = (*bp & PT_Inline ? bp : bp+1);
323 if (dp+dlen > bend)
324 return eMsg("buffer overrun unpacking", int(uP-pup), uP);
325 memcpy(&Temp.b64, dp, dlen);
326 if (bp == dp) Temp.b08 &= PT_MaskD;
327 else bp++;
328 switch(Dtype)
329 {case PT_short: *Base.B16 = ntohs(Temp.b16); break;
330
331 case PT_int: *Base.B32 = ntohl(Temp.b32); break;
332
333 case PT_longlong: *Base.B64 = ntohll(Temp.b64); break;
334
335 default: {}
336 }
337 }
338 uP++; bp += dlen;
339 };
340
341// Make sure we are not missing any items
342//
343 if (Aok || uP->Dtype == PT_End || uP->Dtype == PT_EndFill)
344 return static_cast<int>(uP-pup);
345 return eMsg("missing arg unpacking", int(uP-pup), uP);
346}
347
348/******************************************************************************/
349/* e M s g */
350/******************************************************************************/
351
352int XrdOucPup::eMsg(const char *etxt, int ino, XrdOucPupArgs *pup)
353{
354 const char *dtn;
355 char buff[1024];
356
357// Check if we can print an error message
358//
359 if (!eDest) return 0;
360
361// Get type name
362//
363 switch(pup->Dtype)
364 {case PT_char: dtn = "char"; break;
365 case PT_short: dtn = "short"; break;
366 case PT_int: dtn = "int"; break;
367 case PT_longlong: dtn = "long long"; break;
368 case PT_special: dtn = "special"; break;
369 default: dtn = ""; break;
370 };
371
372// Format the message
373//
374 sprintf(buff, "%s arg %d: %s.", dtn, ino,
375 (!Names||pup->Name >= Names->NLnum ? "?" : Names->NList[pup->Name]));
376
377 eDest->Emsg("Pup", etxt, buff);
378 return 0;
379}
static XrdSysError eDest(0,"crypto_")
unsigned char Name
Definition XrdOucPup.hh:73
@ PT_Totlen
Definition XrdOucPup.hh:52
@ PT_MandS
Definition XrdOucPup.hh:49
@ PT_special
Definition XrdOucPup.hh:61
@ PT_short
Definition XrdOucPup.hh:58
@ PT_MaskD
Definition XrdOucPup.hh:67
@ PT_Datlen
Definition XrdOucPup.hh:51
@ PT_Fence
Definition XrdOucPup.hh:50
@ PT_int
Definition XrdOucPup.hh:59
@ PT_Mask
Definition XrdOucPup.hh:66
@ PT_EndFill
Definition XrdOucPup.hh:54
@ PT_MaskT
Definition XrdOucPup.hh:65
@ PT_Skip
Definition XrdOucPup.hh:48
@ PT_MaskB
Definition XrdOucPup.hh:64
@ PT_Inline
Definition XrdOucPup.hh:63
@ PT_char
Definition XrdOucPup.hh:57
@ PT_longlong
Definition XrdOucPup.hh:60
@ PT_Mark
Definition XrdOucPup.hh:47
@ PT_Ignore
Definition XrdOucPup.hh:46
@ PT_End
Definition XrdOucPup.hh:53
unsigned char Dtype
Definition XrdOucPup.hh:74
#define eMsg(x)
static const int MaxLen
Definition XrdOucPup.hh:102
static int Unpack(char **buff, const char *bend, char **data, int &dlen)
Definition XrdOucPup.cc:250
static int Pack(struct iovec **, const char *, unsigned short &buff)
Definition XrdOucPup.cc:52