XRootD
Loading...
Searching...
No Matches
XrdNetMsg.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d N e t M s g . 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 <poll.h>
33
34#include "XrdNet/XrdNet.hh"
35#include "XrdNet/XrdNetMsg.hh"
36#include "XrdNet/XrdNetOpts.hh"
37#include "XrdSys/XrdSysError.hh"
39
40/******************************************************************************/
41/* C o n s t r u c t o r */
42/******************************************************************************/
43
44XrdNetMsg::XrdNetMsg(XrdSysError *erp, const char *dest, bool *aOK)
45{
46 XrdNet myNet(erp);
47 bool aok = true;
48
49 eDest = erp; FD = -1; destOK = 0;
50 if (dest)
51 {const char *eText = dfltDest.Set(dest);
52 if (!eText) destOK = 1;
53 else {eDest->Emsg("Msg", "Default", dest, "is unreachable");
54 aok = false;
55 }
56 }
57
58 if ((FD = myNet.Relay(dest)) < 0)
59 {eDest->Emsg("Msg", "Unable to create UDP msg socket.");
60 aok = false;
61 }
62
63 if (aOK) *aOK = aok;
64}
65
66/******************************************************************************/
67/* S e n d */
68/******************************************************************************/
69
70int XrdNetMsg::Send(const char *Buff, int Blen, const char *dest, int tmo)
71{
72 XrdNetAddr *theDest;
73 int retc;
74
75 if (!Blen && !(Blen = strlen(Buff))) return 0;
76
77 if (!dest)
78 {if (!destOK)
79 {eDest->Emsg("Msg", "Destination not specified."); return -1;}
80 theDest = &dfltDest;
81 }
82 else if (specDest.Set(dest))
83 {eDest->Emsg("Msg", dest, "is unreachable"); return -1;}
84 else theDest = &specDest;
85
86 if (tmo >= 0 && !OK2Send(tmo, dest)) return 1;
87
88 do {retc = sendto(FD, (Sokdata_t)Buff, Blen, 0,
89 theDest->SockAddr(), theDest->SockSize());}
90 while (retc < 0 && errno == EINTR);
91
92 return (retc < 0 ? retErr(errno, theDest) : 0);
93}
94
95/******************************************************************************/
96
97int XrdNetMsg::Send(const char *dest, const XrdNetSockAddr &netSA,
98 const char *Buff, int Blen, int tmo)
99{
100 int aSize, retc;
101
102 if (!Blen && !(Blen = strlen(Buff))) return 0;
103
104 if (netSA.Addr.sa_family == AF_INET) aSize = sizeof(netSA.v4);
105 else if (netSA.Addr.sa_family == AF_INET6) aSize = sizeof(netSA.v6);
106 else return -1;
107
108 if (tmo >= 0 && !OK2Send(tmo, dest)) return 1;
109
110 do {retc = sendto(FD, (Sokdata_t)Buff, Blen, 0, &netSA.Addr, aSize);}
111 while (retc < 0 && errno == EINTR);
112
113 if (retc >= 0) return 1;
114 return (EWOULDBLOCK == errno || EAGAIN == errno ? 1 : -1);
115}
116
117/******************************************************************************/
118
119int XrdNetMsg::Send(const struct iovec iov[], int iovcnt,
120 const char *dest, int tmo)
121{
122 char buff[4096], *bp = buff;
123 int i, dsz = sizeof(buff);
124
125 if (tmo >= 0 && !OK2Send(tmo, dest)) return 1;
126
127 for (i = 0; i < iovcnt; i++)
128 {dsz -= iov[i].iov_len;
129 if (dsz < 0) return retErr(EMSGSIZE, dest);
130 memcpy((void *)bp,(const void *)iov[i].iov_base,iov[i].iov_len);
131 bp += iov[i].iov_len;
132 }
133
134 return Send(buff, (int)(bp-buff), dest, -1);
135}
136
137/******************************************************************************/
138/* P r i v a t e M e t h o d s */
139/******************************************************************************/
140/******************************************************************************/
141/* O K 2 S e n d */
142/******************************************************************************/
143
144int XrdNetMsg::OK2Send(int timeout, const char *dest)
145{
146 struct pollfd polltab = {FD, POLLOUT|POLLWRNORM, 0};
147 int retc;
148
149 do {retc = poll(&polltab, 1, timeout);} while(retc < 0 && errno == EINTR);
150
151 if (retc == 0 || !(polltab.revents & (POLLOUT | POLLWRNORM)))
152 eDest->Emsg("Msg", "UDP link to", dest, "is blocked.");
153 else if (retc < 0)
154 eDest->Emsg("Msg",errno,"poll", dest);
155 else return 1;
156 return 0;
157}
158
159/******************************************************************************/
160/* r e t E r r */
161/******************************************************************************/
162
163int XrdNetMsg::retErr(int ecode, const char *theDest)
164{
165 if (!theDest)
166 {if (!destOK)
167 {eDest->Emsg("Msg", "Destination not specified."); return -1;}
168 theDest = dfltDest.Name("unknown");
169 }
170 eDest->Emsg("Msg", ecode, "send to", theDest);
171 return (EWOULDBLOCK == ecode || EAGAIN == ecode ? 1 : -1);
172}
173
174int XrdNetMsg::retErr(int ecode, XrdNetAddr *theDest)
175{
176 return retErr(ecode, theDest->Name("unknown"));
177}
struct sockaddr_in6 v6
struct sockaddr Addr
struct sockaddr_in v4
#define Sokdata_t
const sockaddr * SockAddr()
SOCKLEN_t SockSize()
const char * Name(const char *eName=0, const char **eText=0)
const char * Set(const char *hSpec, int pNum=PortInSpec)
int retErr(int ecode, const char *theDest)
Definition XrdNetMsg.cc:163
XrdNetAddr specDest
Definition XrdNetMsg.hh:139
int Send(const char *buff, int blen=0, const char *dest=0, int tmo=-1)
Definition XrdNetMsg.cc:70
XrdNetAddr dfltDest
Definition XrdNetMsg.hh:138
XrdSysError * eDest
Definition XrdNetMsg.hh:137
int OK2Send(int timeout, const char *dest)
Definition XrdNetMsg.cc:144
XrdNetMsg(XrdSysError *erp, const char *dest=0, bool *aOK=0)
Definition XrdNetMsg.cc:44
int Relay(XrdNetPeer &Peer, const char *dest, int opts=0)
Definition XrdNet.cc:310
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)