30 #include <netinet/in.h>
34 #include <sys/types.h>
39 #define TRACELINK Link
49 const char *XrdXrootdResponse::TraceID =
"Response";
58 const char *sName[] = {
"final ",
"partial ",
"progress "};
72 {
if (Bridge->
Send(
kXR_ok, 0, 0, 0) >= 0)
return 0;
73 return Link->
setEtext(
"send failure");
79 if (Link->
Send((
char *)&Resp,
sizeof(Resp)) < 0)
80 return Link->
setEtext(
"send failure");
90 TRACES(RSP,
"sending OK: " <<msg);
92 RespIO[1].iov_base = (caddr_t)msg;
93 RespIO[1].iov_len = strlen(msg)+1;
96 {
if (Bridge->
Send(
kXR_ok,&RespIO[1],1,RespIO[1].iov_len) >= 0)
return 0;
97 return Link->
setEtext(
"send failure");
101 Resp.
dlen =
static_cast<kXR_int32>(htonl(RespIO[1].iov_len));
103 if (Link->
Send(RespIO, 2,
sizeof(Resp) + RespIO[1].iov_len) < 0)
104 return Link->
setEtext(
"send failure");
113 TRACES(RSP,
"sending " <<dlen <<
" data bytes; status=" <<rcode);
115 RespIO[1].iov_base = (caddr_t)data;
116 RespIO[1].iov_len = dlen;
119 {
if (Bridge->
Send(rcode, &RespIO[1], 1, dlen) >= 0)
return 0;
120 return Link->
setEtext(
"send failure");
126 if (Link->
Send(RespIO, 2,
sizeof(Resp) + dlen) < 0)
127 return Link->
setEtext(
"send failure");
134 struct iovec *IOResp,
int iornum,
int iolen)
138 if (iolen < 0)
for (i = 1; i < iornum; i++) dlen += IOResp[i].iov_len;
140 TRACES(RSP,
"sending " <<dlen <<
" data bytes; status=" <<rcode);
143 {
if (Bridge->
Send(rcode, &IOResp[1], iornum-1, dlen) >= 0)
return 0;
144 return Link->
setEtext(
"send failure");
147 IOResp[0].iov_base = RespIO[0].iov_base;
148 IOResp[0].iov_len = RespIO[0].iov_len;
152 if (Link->
Send(IOResp, iornum,
sizeof(Resp) + dlen) < 0)
153 return Link->
setEtext(
"send failure");
160 const char *data,
int dsz)
165 RespIO[1].iov_base = (caddr_t)(&xbuf);
166 RespIO[1].iov_len =
sizeof(xbuf);
167 RespIO[2].iov_base = (caddr_t)data;
168 RespIO[2].iov_len = dlen = (dsz < 0 ? strlen(data) : dsz);
170 TRACES(RSP,
"sending " <<(
sizeof(xbuf)+dlen) <<
" data bytes; status=" <<rcode);
173 {
if (Bridge->
Send(rcode, &RespIO[1], 2, dlen) >= 0)
return 0;
174 return Link->
setEtext(
"send failure");
178 Resp.
dlen =
static_cast<kXR_int32>(htonl((dlen+
sizeof(xbuf))));
180 if (Link->
Send(RespIO, 3,
sizeof(Resp) + dlen +
sizeof(xbuf)) < 0)
181 return Link->
setEtext(
"send failure");
191 TRACES(RSP,
"sending " <<dlen <<
" data bytes");
193 RespIO[1].iov_base = (caddr_t)data;
194 RespIO[1].iov_len = dlen;
197 {
if (Bridge->
Send(
kXR_ok, &RespIO[1], 1, dlen) >= 0)
return 0;
198 return Link->
setEtext(
"send failure");
204 if (Link->
Send(RespIO, 2,
sizeof(Resp) + dlen) < 0)
205 return Link->
setEtext(
"send failure");
216 if (iolen < 0)
for (
int i = 1; i < iornum; i++) dlen += IOResp[i].iov_len;
218 TRACES(RSP,
"sending " <<dlen <<
" data bytes; status=0");
222 {
if (Bridge->
Send(
kXR_ok, &IOResp[1], iornum-1, dlen) >= 0)
return 0;
223 return Link->
setEtext(
"send failure");
226 IOResp[0].iov_base = RespIO[0].iov_base;
227 IOResp[0].iov_len = RespIO[0].iov_len;
231 if (Link->
Send(IOResp, iornum,
sizeof(Resp) + dlen) < 0)
232 return Link->
setEtext(
"send failure");
243 TRACES(
EMSG,
"sending err " <<ecode <<
": " <<msg);
245 RespIO[1].iov_base = (
char *)&erc;
246 RespIO[1].iov_len =
sizeof(erc);
247 RespIO[2].iov_base = (caddr_t)msg;
248 RespIO[2].iov_len = strlen(msg)+1;
249 dlen =
sizeof(erc) + RespIO[2].iov_len;
252 {
if (Bridge->
Send(
kXR_error, &RespIO[1], 2, dlen) >= 0)
return 0;
253 return Link->
setEtext(
"send failure");
259 if (Link->
Send(RespIO, 3,
sizeof(Resp) + dlen) < 0)
260 return Link->
setEtext(
"send failure");
271 TRACES(RSP,
"sendfile " <<dlen <<
" data bytes");
274 {
if (Bridge->
Send(offset, dlen, fdnum) >= 0)
return 0;
275 return Link->
setEtext(
"send failure");
285 myVec[0].buffer = (
char *)&Resp;
286 myVec[0].
sendsz =
sizeof(Resp);
288 myVec[1].offset =
static_cast<off_t
>(offset);
290 myVec[1].
fdnum = fdnum;
294 if (Link->
Send(myVec, 2) < 0)
295 return Link->
setEtext(
"sendfile failure");
305 TRACES(RSP,
"sendfile " <<dlen <<
" data bytes");
308 {
if (Bridge->
Send(sfvec, sfvnum, dlen) >= 0)
return 0;
309 return Link->
setEtext(
"send failure");
316 sfvec[0].buffer = (
char *)&Resp;
317 sfvec[0].
sendsz =
sizeof(Resp);
322 if (Link->
Send(sfvec, sfvnum) < 0)
323 return Link->
setEtext(
"sendfile failure");
334 if (Link->
Send((
char *)&srs, srsComplete(srs, iLen)) < 0)
335 return Link->
setEtext(
"send failure");
342 void *data,
int dlen)
348 if (!dlen) rc = Link->
Send((
char *)&srs, srsComplete(srs, iLen));
349 else {
struct iovec srsIOV[2];
350 srsIOV[0].iov_base = &srs;
351 srsIOV[0].iov_len = srsComplete(srs, iLen, dlen);
352 srsIOV[1].iov_base = (caddr_t)data;
353 srsIOV[1].iov_len = dlen;
354 rc = Link->
Send(srsIOV, 2, srsIOV[0].iov_len + dlen);
359 if (rc < 0)
return Link->
setEtext(
"send failure");
366 struct iovec *IOResp,
int iornum,
int iolen)
372 if (iolen < 0)
for (
int i = 1; i < iornum; i++) dlen += IOResp[i].iov_len;
377 int rspLen = srsComplete(srs, iLen, dlen);
381 IOResp[0].iov_base = &srs;
382 IOResp[0].iov_len = rspLen;
386 if (Link->
Send(IOResp, iornum, rspLen + dlen) < 0)
387 return Link->
setEtext(
"send failure");
395 struct iovec *IOResp,
411 static const int sfxLen =
sizeof(asynResp) -
sizeof(asynResp.atnHdr);
414 unsigned char theSID[2];
415 int theFD, rc, ioxlen = iolen;
416 unsigned int theInst;
420 asynResp.atnHdr.streamid[0] =
'\0';
421 asynResp.atnHdr.streamid[1] =
'\0';
422 asynResp.atnHdr.status = Xattn;
423 asynResp.act = Xarsp;
428 IOResp[0].iov_base = (
char *)&asynResp;
429 IOResp[0].iov_len =
sizeof(asynResp);
433 asynResp.theHdr.status =
static_cast<kXR_unt16>(htons(Status));
437 asynResp.theHdr.dlen =
static_cast<kXR_int32>(htonl(iolen));
439 asynResp.atnHdr.dlen =
static_cast<kXR_int32>(htonl(iolen));
444 ReqID.
getID(theSID, theFD, theInst);
453 &IOResp[1], iornum-1, ioxlen);
454 else {asynResp.theHdr.streamid[0] = theSID[0];
455 asynResp.theHdr.streamid[1] = theSID[1];
456 rc = Link->
Send(IOResp, iornum, iolen);
460 return (rc < 0 ? -1 : 0);
471 static char hv[] =
"0123456789abcdef";
480 for (i = 0; i < (int)
sizeof(Resp.
streamid); i++)
481 {*outbuff++ = hv[(stream[i] >> 4) & 0x0f];
482 *outbuff++ = hv[ stream[i] & 0x0f];
484 *outbuff++ =
' '; *outbuff =
'\0';
495 static const int csSZ =
sizeof(
kXR_unt32);
498 const unsigned char *body;
504 <<iLen <<
" info and " <<dlen <<
" data bytes");
511 srs.
hdr.
dlen = htonl(bdSZ+iLen);
521 body = ((
const unsigned char *)&srs.
bdy.
crc32c)+csSZ;
struct ServerResponseBody_Status bdy
struct ServerResponseHeader hdr
uint32_t crc32c(uint32_t crc, void const *buf, size_t len)
XrdSysTrace XrdXrootdTrace
static XrdLink * fd2link(int fd)
int setEtext(const char *text)
bool isInstance(unsigned int inst) const
int Send(const char *buff, int blen)
static uint32_t Calc32C(const void *data, size_t count, uint32_t prevcs=0)
unsigned long long getID()
int Send(int rcode, const struct iovec *ioVec, int ioNum, int ioLen)
Handle request data response.
static int Attn(XrdLink *lP, short *theSID, int rcode, const struct iovec *ioVec, int ioNum, int ioLen)
Handle attention response (i.e. async response)
int fdnum
File descriptor for data.
int sendsz
Length of data at offset.