XrdXrootdResponse.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                  X r d X r o o t d R e s p o n s e . c c                   */
00004 /*                                                                            */
00005 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*       All Rights Reserved. See XrdInfo.cc for complete License Terms       */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //      $Id: XrdXrootdResponse.cc 24468 2008-06-22 16:47:03Z ganis $
00012 
00013 const char *XrdXrootdResponseCVSID = "$Id: XrdXrootdResponse.cc 24468 2008-06-22 16:47:03Z ganis $";
00014  
00015 #include <sys/types.h>
00016 #include <netinet/in.h>
00017 #include <inttypes.h>
00018 #include <string.h>
00019 
00020 #include "Xrd/XrdLink.hh"
00021 #include "XrdXrootd/XrdXrootdResponse.hh"
00022 #include "XrdXrootd/XrdXrootdTrace.hh"
00023   
00024 /******************************************************************************/
00025 /*                               G l o b a l s                                */
00026 /******************************************************************************/
00027   
00028 extern XrdOucTrace *XrdXrootdTrace;
00029 
00030 const char *XrdXrootdResponse::TraceID = "Response";
00031 
00032 /******************************************************************************/
00033 /*                         L o c a l   D e f i n e s                          */
00034 /******************************************************************************/
00035 
00036 #define TRACELINK Link
00037   
00038 /******************************************************************************/
00039 /*                                  P u s h                                   */
00040 /******************************************************************************/
00041 
00042 int XrdXrootdResponse::Push(void *data, int dlen)
00043 {
00044     kXR_int32 DLen = static_cast<kXR_int32>(htonl(dlen));
00045     RespIO[1].iov_base = (caddr_t)&DLen;
00046     RespIO[1].iov_len  = sizeof(dlen);
00047     RespIO[2].iov_base = (caddr_t)data;
00048     RespIO[2].iov_len  = dlen;
00049 
00050     TRACES(RSP, "pushing " <<dlen <<" data bytes");
00051 
00052     if (Link->Send(&RespIO[1], 2, sizeof(kXR_int32) + dlen) < 0)
00053        return Link->setEtext("send failure");
00054     return 0;
00055 }
00056 
00057 int XrdXrootdResponse::Push()
00058 {
00059     static int null = 0;
00060     TRACES(RSP, "pushing " <<sizeof(kXR_int32) <<" data bytes");
00061     if (Link->Send((char *)&null, sizeof(kXR_int32)) < 0)
00062        return Link->setEtext("send failure");
00063     return 0;
00064 }
00065 
00066 /******************************************************************************/
00067 /*                                  S e n d                                   */
00068 /******************************************************************************/
00069 
00070 int XrdXrootdResponse::Send()
00071 {
00072 
00073     Resp.status = static_cast<kXR_unt16>(htons(kXR_ok));
00074     Resp.dlen   = 0;
00075     TRACES(RSP, "sending OK");
00076 
00077     if (Link->Send((char *)&Resp, sizeof(Resp)) < 0)
00078        return Link->setEtext("send failure");
00079     return 0;
00080 }
00081 
00082 /******************************************************************************/
00083 
00084 int XrdXrootdResponse::Send(const char *msg)
00085 {
00086 
00087     Resp.status        = static_cast<kXR_unt16>(htons(kXR_ok));
00088     RespIO[1].iov_base = (caddr_t)msg;
00089     RespIO[1].iov_len  = strlen(msg)+1;
00090     Resp.dlen          = static_cast<kXR_int32>(htonl(RespIO[1].iov_len));
00091     TRACES(RSP, "sending OK: " <<msg);
00092 
00093     if (Link->Send(RespIO, 2, sizeof(Resp) + RespIO[1].iov_len) < 0)
00094        return Link->setEtext("send failure");
00095     return 0;
00096 }
00097 
00098 /******************************************************************************/
00099 
00100 int XrdXrootdResponse::Send(XResponseType rcode, void *data, int dlen)
00101 {
00102 
00103     Resp.status        = static_cast<kXR_unt16>(htons(rcode));
00104     RespIO[1].iov_base = (caddr_t)data;
00105     RespIO[1].iov_len  = dlen;
00106     Resp.dlen          = static_cast<kXR_int32>(htonl(dlen));
00107     TRACES(RSP, "sending " <<dlen <<" data bytes; status=" <<rcode);
00108 
00109     if (Link->Send(RespIO, 2, sizeof(Resp) + dlen) < 0)
00110        return Link->setEtext("send failure");
00111     return 0;
00112 }
00113 
00114 /******************************************************************************/
00115 
00116 int XrdXrootdResponse::Send(XResponseType rcode, int info, const char *data)
00117 {
00118     kXR_int32 xbuf = static_cast<kXR_int32>(htonl(info));
00119     int dlen;
00120 
00121     Resp.status        = static_cast<kXR_unt16>(htons(rcode));
00122     RespIO[1].iov_base = (caddr_t)(&xbuf);
00123     RespIO[1].iov_len  = sizeof(xbuf);
00124     RespIO[2].iov_base = (caddr_t)data;
00125     RespIO[2].iov_len  = dlen = strlen(data);
00126     Resp.dlen          = static_cast<kXR_int32>(htonl((dlen+sizeof(xbuf))));
00127 
00128     TRACES(RSP, "sending " <<dlen <<" data bytes; status=" <<rcode);
00129 
00130     if (Link->Send(RespIO, 3, sizeof(Resp) + dlen) < 0)
00131        return Link->setEtext("send failure");
00132     return 0;
00133 }
00134 
00135 /******************************************************************************/
00136 
00137 int XrdXrootdResponse::Send(void *data, int dlen)
00138 {
00139 
00140     Resp.status        = static_cast<kXR_unt16>(htons(kXR_ok));
00141     RespIO[1].iov_base = (caddr_t)data;
00142     RespIO[1].iov_len  = dlen;
00143     Resp.dlen          = static_cast<kXR_int32>(htonl(dlen));
00144     TRACES(RSP, "sending " <<dlen <<" data bytes; status=0");
00145 
00146     if (Link->Send(RespIO, 2, sizeof(Resp) + dlen) < 0)
00147        return Link->setEtext("send failure");
00148     return 0;
00149 }
00150 
00151 /******************************************************************************/
00152 
00153 int XrdXrootdResponse::Send(struct iovec *IOResp, int iornum, int iolen)
00154 {
00155     int i, dlen = 0;
00156 
00157     if (iolen < 0) for (i = 1; i < iornum; i++) dlen += IOResp[i].iov_len;
00158        else dlen = iolen;
00159 
00160     Resp.status        = static_cast<kXR_unt16>(htons(kXR_ok));
00161     IOResp[0].iov_base = RespIO[0].iov_base;
00162     IOResp[0].iov_len  = RespIO[0].iov_len;
00163     Resp.dlen          = static_cast<kXR_int32>(htonl(dlen));
00164     TRACES(RSP, "sending " <<dlen <<" data bytes; status=0");
00165 
00166     if (Link->Send(IOResp, iornum, sizeof(Resp) + dlen) < 0)
00167        return Link->setEtext("send failure");
00168     return 0;
00169 }
00170 
00171 /******************************************************************************/
00172 
00173 int XrdXrootdResponse::Send(XErrorCode ecode, const char *msg)
00174 {
00175     int dlen;
00176     kXR_int32 erc = static_cast<kXR_int32>(htonl(ecode));
00177 
00178     Resp.status        = static_cast<kXR_unt16>(htons(kXR_error));
00179     RespIO[1].iov_base = (char *)&erc;
00180     RespIO[1].iov_len  = sizeof(erc);
00181     RespIO[2].iov_base = (caddr_t)msg;
00182     RespIO[2].iov_len  = strlen(msg)+1;
00183                 dlen   = sizeof(erc) + RespIO[2].iov_len;
00184     Resp.dlen          = static_cast<kXR_int32>(htonl(dlen));
00185     TRACES(EMSG, "sending err " <<ecode <<": " <<msg);
00186 
00187     if (Link->Send(RespIO, 3, sizeof(Resp) + dlen) < 0)
00188        return Link->setEtext("send failure");
00189     return 0;
00190 }
00191  
00192 /******************************************************************************/
00193 
00194 int XrdXrootdResponse::Send(int fdnum, long long offset, int dlen)
00195 {
00196    struct XrdLink::sfVec myVec[2];
00197 
00198 // We are only called should sendfile be enabled for this response
00199 //
00200    Resp.status = static_cast<kXR_unt16>(htons(kXR_ok));
00201    Resp.dlen   = static_cast<kXR_int32>(htonl(dlen));
00202 
00203 // Fill out the sendfile vector
00204 //
00205    myVec[0].buffer = (char *)&Resp;
00206    myVec[0].sendsz = sizeof(Resp);
00207    myVec[0].fdnum  = -1;
00208    myVec[1].offset = static_cast<off_t>(offset);
00209    myVec[1].sendsz = dlen;
00210    myVec[1].fdnum  = fdnum;
00211 
00212 // Send off the request
00213 //
00214     TRACES(RSP, "sendfile " <<dlen <<" data bytes; status=0");
00215     if (Link->Send(myVec, 2) < 0)
00216        return Link->setEtext("sendfile failure");
00217     return 0;
00218 }
00219 
00220 /******************************************************************************/
00221 
00222 int XrdXrootdResponse::Send(XrdXrootdReqID &ReqID, 
00223                             XResponseType   Status,
00224                             struct iovec   *IOResp, 
00225                             int             iornum, 
00226                             int             iolen)
00227 {
00228    static const kXR_unt16 Xattn = static_cast<kXR_unt16>(htons(kXR_attn));
00229    static const kXR_int32 Xarsp = static_cast<kXR_int32>(htonl(kXR_asynresp));
00230 
00231 // We would have used struct ServerResponseBody_Attn_asynresp but the silly
00232 // imbedded 4096 char array causes grief when computing lengths.
00233 //
00234    struct {ServerResponseHeader atnHdr;
00235            kXR_int32            act;
00236            kXR_int32            rsvd;  // Same as char[4]
00237            ServerResponseHeader theHdr;
00238           } asynResp;
00239 
00240    static const int sfxLen = sizeof(asynResp) - sizeof(asynResp.atnHdr);
00241 
00242    XrdLink           *Link;
00243    unsigned char      theSID[2];
00244    int                theFD, rc;
00245    unsigned int       theInst;
00246 
00247 // Fill out the header with constant information
00248 //
00249    asynResp.atnHdr.streamid[0] = '\0';
00250    asynResp.atnHdr.streamid[1] = '\0';
00251    asynResp.atnHdr.status      = Xattn;
00252    asynResp.act                = Xarsp;
00253    asynResp.rsvd               = 0;
00254 
00255 // Complete the io vector to send this response
00256 //
00257    IOResp[0].iov_base = (char *)&asynResp;
00258    IOResp[0].iov_len  = sizeof(asynResp);           // 0
00259 
00260 // Insert the status code
00261 //
00262     asynResp.theHdr.status = static_cast<kXR_unt16>(htons(Status));
00263 
00264 // We now insert the length of the delayed response and the full response
00265 //
00266    asynResp.theHdr.dlen = static_cast<kXR_int32>(htonl(iolen));
00267    iolen += sfxLen;
00268    asynResp.atnHdr.dlen = static_cast<kXR_int32>(htonl(iolen));
00269    iolen += sizeof(ServerResponseHeader);
00270 
00271 // Decode the destination
00272 //
00273    ReqID.getID(theSID, theFD, theInst);
00274 
00275 // Map the destination to an endpoint, and send the response
00276 //
00277    if ((Link = XrdLink::fd2link(theFD, theInst)))
00278       {Link->setRef(1);
00279        if (Link->isInstance(theInst))
00280           {asynResp.theHdr.streamid[0] = theSID[0];
00281            asynResp.theHdr.streamid[1] = theSID[1];
00282            rc = Link->Send(IOResp, iornum, iolen);
00283           } else rc = -1;
00284        Link->setRef(-1);
00285        return (rc < 0 ? -1 : 0);
00286       }
00287    return -1;
00288 }
00289   
00290 /******************************************************************************/
00291 /*                                   S e t                                    */
00292 /******************************************************************************/
00293 
00294 void XrdXrootdResponse::Set(unsigned char *stream)
00295 {
00296    static char hv[] = "0123456789abcdef";
00297    char *outbuff;
00298    int i;
00299 
00300    Resp.streamid[0] = stream[0];
00301    Resp.streamid[1] = stream[1];
00302 
00303    if (TRACING((TRACE_REQ|TRACE_RSP)))
00304       {outbuff = trsid;
00305        for (i = 0; i < (int)sizeof(Resp.streamid); i++)
00306            {*outbuff++ = hv[(stream[i] >> 4) & 0x0f];
00307             *outbuff++ = hv[ stream[i]       & 0x0f];
00308             }
00309        *outbuff++ = ' '; *outbuff = '\0';
00310       }
00311 }

Generated on Tue Jul 5 14:47:04 2011 for ROOT_528-00b_version by  doxygen 1.5.1