XrdNetMsg.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                          X r d N e t M s g . c c                           */
00004 /*                                                                            */
00005 /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdNetMsg.cc 35287 2010-09-14 21:19:35Z ganis $
00012 
00013 const char *XrdNetMsgCVSID = "$Id: XrdNetMsg.cc 35287 2010-09-14 21:19:35Z ganis $";
00014 
00015 #include <sys/poll.h>
00016 
00017 #include "XrdNet/XrdNet.hh"
00018 #include "XrdNet/XrdNetDNS.hh"
00019 #include "XrdNet/XrdNetMsg.hh"
00020 #include "XrdNet/XrdNetOpts.hh"
00021 #include "XrdNet/XrdNetPeer.hh"
00022 #include "XrdNet/XrdNetSocket.hh"
00023 #include "XrdSys/XrdSysError.hh"
00024 #include "XrdSys/XrdSysPlatform.hh"
00025 
00026 /******************************************************************************/
00027 /*                           C o n s t r u c t o r                            */
00028 /******************************************************************************/
00029   
00030 XrdNetMsg::XrdNetMsg(XrdSysError *erp, const char *dest)
00031 {
00032    XrdNet     myNet(erp);
00033    XrdNetPeer Peer;
00034 
00035    eDest = erp; DestHN = 0; DestIP = 0; DestSZ = 0; FD = -1;
00036    if (dest)
00037       {if (XrdNetSocket::socketAddr(erp, dest, &DestIP, DestSZ))
00038           eDest->Emsg("Msg", "Default", dest, "is unreachable");
00039           else DestHN = strdup(dest);
00040       }
00041 
00042     if (!myNet.Relay(Peer, dest, XRDNET_SENDONLY))
00043        eDest->Emsg("Msg", "Unable top create UDP msg socket.");
00044        else FD = Peer.fd;
00045 }
00046 
00047 /******************************************************************************/
00048 /*                                  S e n d                                   */
00049 /******************************************************************************/
00050   
00051 int XrdNetMsg::Send(const char *Buff, int Blen, const char *dest, int tmo)
00052 {
00053    int retc, eCode, dL, doFree = 0;
00054    struct sockaddr *dP;
00055 
00056    if (!Blen && !(Blen = strlen(Buff))) return  0;
00057 
00058    if (!dest)
00059        {if (!DestHN)
00060            {eDest->Emsg("Msg", "Destination not specified."); return -1;}
00061         dP = DestIP; dL = DestSZ; dest = DestHN;
00062        }
00063       else if (XrdNetSocket::socketAddr(eDest, dest, &dP, dL))
00064               {eDest->Emsg("Msg", dest, "is unreachable");    return -1;}
00065               else doFree = 1;
00066 
00067    if (tmo >= 0 && !OK2Send(tmo, dest)) {if (doFree) free(dP); return 1;}
00068 
00069    do {retc = sendto(FD, (Sokdata_t)Buff, Blen, 0, dP, dL);}
00070        while (retc < 0 && errno == EINTR);
00071 
00072    if (retc < 0) eCode = errno;
00073    if (doFree) free(dP);
00074    if (retc < 0) return retErr(errno, dest);
00075    return 0;
00076 }
00077 
00078 /******************************************************************************/
00079 
00080 int XrdNetMsg::Send(const struct iovec iov[], int iovcnt, 
00081                     const char  *dest,        int tmo)
00082 {
00083    char buff[4096], *bp = buff;
00084    int i, dsz = sizeof(buff);
00085 
00086    if (tmo >= 0 && !OK2Send(tmo, dest)) return 1;
00087 
00088    for (i = 0; i < iovcnt; i++)
00089        {dsz -= iov[i].iov_len;
00090         if (dsz < 0) return retErr(EMSGSIZE, dest);
00091         memcpy((void *)bp,(const void *)iov[i].iov_base,iov[i].iov_len);
00092         bp += iov[i].iov_len;
00093        }
00094 
00095    return Send(buff, (int)(bp-buff), dest, -1);
00096 }
00097   
00098 /******************************************************************************/
00099 /*                       P r i v a t e   M e t h o d s                        */
00100 /******************************************************************************/
00101 /******************************************************************************/
00102 /*                               O K 2 S e n d                                */
00103 /******************************************************************************/
00104   
00105 int XrdNetMsg::OK2Send(int timeout, const char *dest)
00106 {
00107    struct pollfd polltab = {FD, POLLOUT|POLLWRNORM, 0};
00108    int retc;
00109 
00110    do {retc = poll(&polltab, 1, timeout);} while(retc < 0 && errno == EINTR);
00111 
00112    if (retc == 0 || !(polltab.revents & (POLLOUT | POLLWRNORM)))
00113       eDest->Emsg("Msg", "UDP link to", dest, "is blocked.");
00114       else if (retc < 0)
00115               eDest->Emsg("Msg",errno,"poll", dest);
00116               else return 1;
00117    return 0;
00118 }
00119   
00120 /******************************************************************************/
00121 /*                                r e t E r r                                 */
00122 /******************************************************************************/
00123   
00124 int XrdNetMsg::retErr(int ecode, const char *dest)
00125 {
00126    eDest->Emsg("Msg", ecode, "send to", dest);
00127    return (EWOULDBLOCK == ecode || EAGAIN == ecode ? 1 : -1);
00128 }

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