XRootD
Loading...
Searching...
No Matches
XrdNetSocket Class Reference

#include <XrdNetSocket.hh>

+ Collaboration diagram for XrdNetSocket:

Public Member Functions

 XrdNetSocket (XrdSysError *erobj=0, int SockFileDesc=-1)
 
 ~XrdNetSocket ()
 
int Accept (int ms=-1)
 
void Close ()
 
int Detach ()
 
int LastError ()
 
int Open (const char *path, int port=-1, int flags=0, int sockbuffsz=0)
 
const char * Peername (const struct sockaddr **InetAddr=0, int *InetSize=0)
 
const char * SockData (XrdNetSockAddr &InetAddr)
 
int SockName (char *buff, int blen)
 
int SockNum ()
 

Static Public Member Functions

static XrdNetSocketCreate (XrdSysError *Say, const char *path, const char *fn, mode_t mode, int isudp=0)
 
static int getWindow (int fd, int &Windowsz, XrdSysError *eDest=0)
 
static int setOpts (int fd, int options, XrdSysError *eDest=0)
 
static int setWindow (int fd, int Windowsz, XrdSysError *eDest=0)
 
static char * socketPath (XrdSysError *Say, char *inbuff, const char *path, const char *fn, mode_t mode)
 

Detailed Description

Definition at line 47 of file XrdNetSocket.hh.

Constructor & Destructor Documentation

◆ XrdNetSocket()

XrdNetSocket::XrdNetSocket ( XrdSysError * erobj = 0,
int SockFileDesc = -1 )

Definition at line 88 of file XrdNetSocket.cc.

89{
90 ErrCode = 0;
91 eroute = erobj;
92 SockFD = SockFileDesc;
93}

Referenced by Create().

+ Here is the caller graph for this function:

◆ ~XrdNetSocket()

XrdNetSocket::~XrdNetSocket ( )
inline

Definition at line 59 of file XrdNetSocket.hh.

59{Close();}

References Close().

+ Here is the call graph for this function:

Member Function Documentation

◆ Accept()

int XrdNetSocket::Accept ( int ms = -1)

Definition at line 99 of file XrdNetSocket.cc.

100{
101 int retc, ClientSock;
102
103 ErrCode = 0;
104
105 // Check if a timeout was requested
106 //
107 if (timeout >= 0)
108 {struct pollfd sfd = {SockFD,
109 POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI|POLLHUP, 0};
110 do {retc = poll(&sfd, 1, timeout);}
111 while(retc < 0 && (errno == EAGAIN || errno == EINTR));
112 if (!sfd.revents) return -1;
113 }
114
115 do {ClientSock = XrdSysFD_Accept(SockFD, (struct sockaddr *)0, 0);}
116 while(ClientSock < 0 && errno == EINTR);
117
118 if (ClientSock < 0 && eroute) eroute->Emsg("Accept",errno,"accept connection");
119
120 // Return the socket number.
121 //
122 return ClientSock;
123}

References XrdSysError::Emsg().

Referenced by XrdCmsAdmin::Start(), and XrdXrootdAdmin::Start().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Close()

void XrdNetSocket::Close ( )

Definition at line 129 of file XrdNetSocket.cc.

130{
131 // Close any open file descriptor.
132 //
133 if (SockFD >= 0) {close(SockFD); SockFD=-1;}
134
135 // Reset values and return.
136 //
137 ErrCode=0;
138}
#define close(a)
Definition XrdPosix.hh:48

References close.

Referenced by ~XrdNetSocket(), and Open().

+ Here is the caller graph for this function:

◆ Create()

XrdNetSocket * XrdNetSocket::Create ( XrdSysError * Say,
const char * path,
const char * fn,
mode_t mode,
int isudp = 0 )
static

Definition at line 144 of file XrdNetSocket.cc.

146{
147 XrdNetSocket *ASock;
148 int pflags = (opts & XRDNET_FIFO ? S_IFIFO : S_IFSOCK);
149 int sflags = (opts & XRDNET_UDPSOCKET) | XRDNET_SERVER;
150 int rc = 0;
151 mode_t myMode = (mode & (S_IRWXU | S_IRWXG));
152 const char *eMsg = 0;
153 char fnbuff[1024] = {0};
154
155// Setup the path
156//
157 if (!socketPath(Say, fnbuff, path, fn, mode|pflags))
158 return (XrdNetSocket *)0;
159
160// Connect to the path
161//
162 ASock = new XrdNetSocket(Say);
163#ifndef WIN32
164 if (opts & XRDNET_FIFO)
165 {if ((ASock->SockFD = mkfifo(fnbuff, mode)) < 0 && errno != EEXIST)
166 {eMsg = "create fifo"; rc = errno;}
167 else if ((ASock->SockFD = XrdSysFD_Open(fnbuff, O_RDWR, myMode)) < 0)
168 {eMsg = "open fifo"; rc = errno;}
169 else if (opts & XRDNET_NOCLOSEX) XrdSysFD_Yield(ASock->SockFD);
170 } else if (ASock->Open(fnbuff, -1, sflags) < 0)
171 {eMsg = "create socket"; rc = ASock->LastError();}
172#else
173 if (ASock->Open(fnbuff, -1, sflags) < 0)
174 {eMsg = "create socket"; rc = ASock->LastError();}
175#endif
176
177// Return the result
178//
179 if (eMsg) {Say->Emsg("Create", rc, eMsg, fnbuff);
180 delete ASock; ASock = 0;
181 }
182 return ASock;
183}
XrdOucPup XrdCmsParser::Pup & Say
#define XRDNET_FIFO
Definition XrdNetOpts.hh:83
#define XRDNET_NOCLOSEX
Definition XrdNetOpts.hh:67
#define XRDNET_SERVER
Definition XrdNetOpts.hh:99
#define XRDNET_UDPSOCKET
Definition XrdNetOpts.hh:79
#define eMsg(x)
struct myOpts opts
XrdNetSocket(XrdSysError *erobj=0, int SockFileDesc=-1)
int Open(const char *path, int port=-1, int flags=0, int sockbuffsz=0)
static char * socketPath(XrdSysError *Say, char *inbuff, const char *path, const char *fn, mode_t mode)

References XrdNetSocket(), eMsg, LastError(), Open(), opts, Say, socketPath(), XRDNET_FIFO, XRDNET_NOCLOSEX, XRDNET_SERVER, and XRDNET_UDPSOCKET.

Referenced by XrdXrootdProtocol::Configure(), XrdCmsConfig::Configure2(), XrdOfsEvr::Init(), mainConfig(), XrdFrmXfrDaemon::Pong(), XrdBwmLogger::Start(), and XrdOfsEvs::Start().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Detach()

int XrdNetSocket::Detach ( )

Definition at line 189 of file XrdNetSocket.cc.

190{ int oldFD = SockFD;
191 SockFD = -1;
192 return oldFD;
193}

Referenced by XrdNet::Bind(), XrdNet::Bind(), XrdNet::Connect(), XrdNet::Connect(), XrdOfsEvr::Init(), main(), mainConfig(), XrdCmsAdmin::Notes(), XrdFrmXfrDaemon::Pong(), XrdBwmLogger::Start(), and XrdOfsEvs::Start().

+ Here is the caller graph for this function:

◆ getWindow()

int XrdNetSocket::getWindow ( int fd,
int & Windowsz,
XrdSysError * eDest = 0 )
static

Definition at line 199 of file XrdNetSocket.cc.

200{
201 socklen_t szb = (socklen_t)sizeof(Windowsz);
202
203 if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (Sokdata_t)&Windowsz, &szb))
204 {if (eDest) eDest->Emsg("setWindow", errno, "set socket RCVBUF");
205 return -1;
206 }
207 return 0;
208}
static XrdSysError eDest(0,"crypto_")
#define Sokdata_t
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)

References eDest, and Sokdata_t.

Referenced by XrdNet::WSize().

+ Here is the caller graph for this function:

◆ LastError()

int XrdNetSocket::LastError ( )
inline

Definition at line 107 of file XrdNetSocket.hh.

107{return ErrCode;}

Referenced by XrdNet::Bind(), XrdNet::Bind(), Create(), and main().

+ Here is the caller graph for this function:

◆ Open()

int XrdNetSocket::Open ( const char * path,
int port = -1,
int flags = 0,
int sockbuffsz = 0 )

Definition at line 214 of file XrdNetSocket.cc.

215{
216 const char *epath, *eText, *action = "configure socket";
217 char pbuff[128];
218 int myEC, backlog, SockProt;
219 int SockType = (flags & XRDNET_UDPSOCKET ? SOCK_DGRAM : SOCK_STREAM);
220 const int one = 1;
221 const SOCKLEN_t szone = (SOCKLEN_t)sizeof(one);
222
223// Supply actual port number in error messages
224//
225 if (inpath) epath = inpath;
226 else {sprintf(pbuff, "port %d", port);
227 epath = pbuff;
228 }
229
230// Make sure this object is available for a new socket
231//
232 if (SockFD >= 0) return Err(Open, EBUSY, "create socket for", epath);
233
234// Save the request flags, sometimes we need to check them from the local copy
235//
236 myEC = ErrCode = 0;
237
238// Preset out address information
239//
240 if ((eText = SockInfo.Set(inpath,(port < 0 ? XrdNetAddr::PortInSpec:port))))
241 {ErrCode = EHOSTUNREACH;
242 if (eroute)
243 {char buff[512];
244 snprintf(buff,sizeof(buff),"'%s'; %c%s",epath,tolower(*eText),eText+1);
245 eroute->Emsg("Open", "Unable to create socket for", buff);
246 }
247 return -1;
248 }
249
250// Allocate a socket descriptor of the right type
251//
252 SockProt = SockInfo.Protocol();
253 if ((SockFD = XrdSysFD_Socket(SockProt, SockType, 0)) < 0)
254 return Err(Open, errno, "create socket for", epath);
255
256// Based on the type socket, set appropriate options. For server-side Unix
257// sockets we must unlink the corresponding Unix path name or bind will fail.
258// In some OS's, this creates a problem (e.g., Solaris) since the file inode is
259// used to identify the socket and will likely change. This means that connects
260// occuring before the bind will hang up to 3 minutes and client needs to retry.
261// For non-Unix socketsr be prepared to timeout connects and try again.
262//
263 if (SockProt == PF_UNIX)
264 {setOpts(SockFD, flags | XRDNET_UDPSOCKET, eroute);
265 if (flags & XRDNET_SERVER) unlink((const char *)inpath);
266 } else {
267 setOpts(SockFD, flags, eroute);
268 if (setsockopt(SockFD,SOL_SOCKET,SO_REUSEADDR, (Sokdata_t)&one, szone)
269 && eroute) eroute->Emsg("Open",errno,"set socket REUSEADDR for",epath);
270 }
271
272// Set the window size or udp buffer size, as needed (ignore errors)
273//
274 if (windowsz) setWindow(SockFD, windowsz, eroute);
275
276// Either do a bind or a connect.
277//
278 if (flags & XRDNET_SERVER)
279 {action = "bind socket to";
280 if (bind(SockFD, SockInfo.SockAddr(), SockInfo.SockSize())) myEC = errno;
281 else if (SockType == SOCK_STREAM)
282 {action = "listen on stream";
283 if (!(backlog = flags & XRDNET_BKLG))
284 backlog = XRDNETSOCKET_MAXBKLG;
285 if (listen(SockFD, backlog)) myEC = errno;
286 }
287 if (SockProt == PF_UNIX) chmod(inpath, S_IRWXU);
288 } else {
289 int tmo = flags & XRDNET_TOUT;
290 action = "connect socket to";
291 if (SockType == SOCK_STREAM && tmo)
292 myEC = XrdNetConnect::Connect(SockFD, SockInfo.SockAddr(),
293 SockInfo.SockSize(), tmo);
294 else if (connect(SockFD,SockInfo.SockAddr(),SockInfo.SockSize()))
295 myEC = errno;
296 }
297
298// Check for any errors and return (Close() sets SockFD to -1).
299//
300 if (myEC)
301 {Close();
302 ErrCode = myEC;
303 if (!(flags & XRDNET_NOEMSG) && eroute)
304 eroute->Emsg("Open", ErrCode, action, epath);
305 }
306 return SockFD;
307}
#define XRDNET_TOUT
#define XRDNET_NOEMSG
Definition XrdNetOpts.hh:71
#define XRDNET_BKLG
#define XRDNETSOCKET_MAXBKLG
#define Err(p, a, b, c)
#define unlink(a)
Definition XrdPosix.hh:113
#define SOCKLEN_t
static const int PortInSpec
static int Connect(int fd, const struct sockaddr *name, int namelen, int tsec=-1)
static int setWindow(int fd, int Windowsz, XrdSysError *eDest=0)
static int setOpts(int fd, int options, XrdSysError *eDest=0)

References Close(), XrdNetConnect::Connect(), Err, Open(), XrdNetAddr::PortInSpec, setOpts(), setWindow(), SOCKLEN_t, Sokdata_t, unlink, XRDNET_BKLG, XRDNET_NOEMSG, XRDNET_SERVER, XRDNET_TOUT, XRDNET_UDPSOCKET, and XRDNETSOCKET_MAXBKLG.

Referenced by XrdNet::Bind(), XrdNet::Bind(), XrdNet::Connect(), XrdNet::Connect(), Create(), main(), and Open().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Peername()

const char * XrdNetSocket::Peername ( const struct sockaddr ** InetAddr = 0,
int * InetSize = 0 )

Definition at line 313 of file XrdNetSocket.cc.

315{
316 const char *errtxt, *PeerName;
317
318// Make sure we have something to look at
319//
320 if (SockFD < 0)
321 {if (eroute) eroute->Emsg("Peername",
322 "Unable to obtain peer name; socket not open");
323 return (char *)0;
324 }
325
326// Get the host name on the other side of this socket
327//
328 if (!(PeerName = SockInfo.Name(0, &errtxt)))
329 {if (eroute)
330 eroute->Emsg("Peername", "Unable to obtain peer name; ",errtxt);
331 ErrCode = ESRCH;
332 }
333
334// Return possible address, length and the name
335//
336 if (InetAddr) *InetAddr = SockInfo.SockAddr();
337 if (InetSize) *InetSize = SockInfo.SockSize();
338 return PeerName;
339}

Referenced by XrdNet::Connect().

+ Here is the caller graph for this function:

◆ setOpts()

int XrdNetSocket::setOpts ( int fd,
int options,
XrdSysError * eDest = 0 )
static

Definition at line 345 of file XrdNetSocket.cc.

346{
347 int rc = 0;
348 const int one = 1;
349#if defined(__linux__) || defined(__GNU__)
350 const int szint = sizeof(int);
351#endif
352 const SOCKLEN_t szone = (SOCKLEN_t)sizeof(one);
353 static int tcpprotid = XrdNetUtils::ProtoID("tcp");
354 static struct linger liopts = {1, XRDNETSOCKET_LINGER};
355 const SOCKLEN_t szlio = (SOCKLEN_t)sizeof(liopts);
356
357 if (opts & XRDNET_NOCLOSEX && !XrdSysFD_Yield(xfd))
358 {rc = 1;
359 if (eDest) eDest->Emsg("setOpts", errno, "set fd close on exec");
360 }
361
362 if (opts & XRDNET_UDPSOCKET) return rc;
363
364 if (!(opts & XRDNET_NOLINGER)
365 && setsockopt(xfd,SOL_SOCKET,SO_LINGER,(Sokdata_t)&liopts,szlio))
366 {rc = 1;
367 if (eDest) eDest->Emsg("setOpts", errno, "set socket LINGER");
368 }
369
371 {if (setsockopt(xfd,SOL_SOCKET,SO_KEEPALIVE,(Sokdata_t)&one,szone))
372 {rc = 1;
373 if (eDest) eDest->Emsg("setOpts", errno, "set socket KEEPALIVE");
374 }
375#if defined(__linux__) || defined(__GNU__)
376 else if (opts & XRDNET_SERVER) // Following are inherited in Linux
378 && setsockopt(xfd,SOL_TCP,TCP_KEEPIDLE,&XrdNetSocketCFG::ka_Idle,szint))
379 {rc = 1;
380 if (eDest) eDest->Emsg("setOpts", errno, "set socket KEEPIDLE");
381 }
383 && setsockopt(xfd,SOL_TCP,TCP_KEEPINTVL,&XrdNetSocketCFG::ka_Itvl,szint))
384 {rc = 1;
385 if (eDest) eDest->Emsg("setOpts", errno, "set socket KEEPINTVL");
386 }
388 && setsockopt(xfd,SOL_TCP,TCP_KEEPCNT, &XrdNetSocketCFG::ka_Icnt,szint))
389 {rc = 1;
390 if (eDest) eDest->Emsg("setOpts", errno, "set socket KEEPCNT");
391 }
392 }
393#endif
394 }
395
396 if (!(opts & XRDNET_DELAY)
397 && setsockopt(xfd, tcpprotid, TCP_NODELAY, (Sokdata_t)&one,szone))
398 {rc = 1;
399 if (eDest) eDest->Emsg("setOpts", errno, "set socket NODELAY");
400 }
401
402 return rc;
403}
#define XRDNET_KEEPALIVE
Definition XrdNetOpts.hh:63
#define XRDNET_NOLINGER
Definition XrdNetOpts.hh:75
#define XRDNET_DELAY
Definition XrdNetOpts.hh:59
#define XRDNETSOCKET_LINGER
static int ProtoID(const char *pName)

References eDest, XrdNetSocketCFG::ka_Icnt, XrdNetSocketCFG::ka_Idle, XrdNetSocketCFG::ka_Itvl, opts, XrdNetUtils::ProtoID(), SOCKLEN_t, Sokdata_t, XRDNET_DELAY, XRDNET_KEEPALIVE, XRDNET_NOCLOSEX, XRDNET_NOLINGER, XRDNET_SERVER, XRDNET_UDPSOCKET, and XRDNETSOCKET_LINGER.

Referenced by XrdInet::BindSD(), Open(), XrdCmsAdmin::Relay(), and XrdCmsAdmin::Start().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setWindow()

int XrdNetSocket::setWindow ( int fd,
int Windowsz,
XrdSysError * eDest = 0 )
static

Definition at line 409 of file XrdNetSocket.cc.

410{
411 int rc = 0;
412 const SOCKLEN_t szwb = (SOCKLEN_t)sizeof(Windowsz);
413
414 if (setsockopt(xfd, SOL_SOCKET, SO_SNDBUF,
415 (Sokdata_t)&Windowsz, szwb))
416 {rc = 1;
417 if (eDest) eDest->Emsg("setWindow", errno, "set socket SNDBUF");
418 }
419
420 if (setsockopt(xfd, SOL_SOCKET, SO_RCVBUF,
421 (Sokdata_t)&Windowsz, szwb))
422 {rc = 1;
423 if (eDest) eDest->Emsg("setWindow", errno, "set socket RCVBUF");
424 }
425 return rc;
426}

References eDest, SOCKLEN_t, and Sokdata_t.

Referenced by Open().

+ Here is the caller graph for this function:

◆ SockData()

const char * XrdNetSocket::SockData ( XrdNetSockAddr & InetAddr)

Definition at line 432 of file XrdNetSocket.cc.

433{
434 const char *errtxt, *Name;
435
436// Make sure we have something to look at
437//
438 if (SockFD < 0)
439 {if (eroute) eroute->Emsg("SockInfo",
440 "Unable to obtain socket info; socket not open");
441 return (const char *)0;
442 }
443
444// Return possible address, length and the name
445//
446 const XrdNetSockAddr *netSA = SockInfo.NetAddr();
447 if (!netSA)
448 {if (eroute)
449 {eroute->Emsg("SockInfo", "Unable to obtain socker info; "
450 "not an network socket.");
451 ErrCode = EOPNOTSUPP;
452 return (const char *)0;
453 }
454 }
455 memcpy(&InetAddr, netSA, sizeof(XrdNetSockAddr));
456
457// Get the host name on the other side of this socket
458//
459 if (!(Name = SockInfo.Name(0, &errtxt)))
460 {if (eroute)
461 eroute->Emsg("SockInfo", "Unable to obtain socker info; ",errtxt);
462 ErrCode = ESRCH;
463 return (const char *)0;
464 }
465
466// All done
467//
468 return Name;
469}

Referenced by XrdNet::Connect().

+ Here is the caller graph for this function:

◆ socketPath()

char * XrdNetSocket::socketPath ( XrdSysError * Say,
char * inbuff,
const char * path,
const char * fn,
mode_t mode )
static

Definition at line 492 of file XrdNetSocket.cc.

494{
495 const int srchOK = S_IXUSR | S_IXGRP;
496 const int sfMask = (S_IFIFO | S_IFSOCK);
497 int rc, i, fnlen = strlen(fnbuff);
498 mode_t myMode = (mode & (S_IRWXU | S_IRWXG)) | srchOK;
499 struct stat buf;
500 char *sp = 0;
501
502// Copy the const char path because makePath modifies it
503//
504 i = strlen(path);
505 if (strlcpy(fnbuff, path, 1024) >= 1024 || (i + fnlen + 1) >= 1024)
506 {Say->Emsg("createPath", "Socket path", path, "too long");
507 return 0;
508 }
509
510// Check if we should separate the filename from the path
511//
512 if (!fn)
513 {if (fnbuff[i-1] == '/') fnbuff[i-1] = '\0';
514 if ((sp = rindex(fnbuff, '/'))) *sp = '\0';
515 }
516
517// Create the directory if it is not already there
518//
519 if ((rc = XrdOucUtils::makePath(fnbuff, myMode)))
520 {Say->Emsg("createPath", errno, "create path", path);
521 return 0;
522 }
523
524// Construct full filename
525//
526 if (sp) *sp = '/';
527 else {if (path[i-1] != '/') fnbuff[i++] = '/';
528 if (fn) strcpy(fnbuff+i, fn);
529 }
530
531// Check is we have already created it and whether we can access
532//
533 if (!stat(fnbuff,&buf))
534 {if ((buf.st_mode & S_IFMT) != (mode & sfMask))
535 {Say->Emsg("createPath","Path",fnbuff,
536 (mode & S_IFSOCK) ? "exists but is not a socket"
537 : "exists but is not a pipe");
538 return 0;
539 }
540 if (access(fnbuff, W_OK))
541 {Say->Emsg("createPath", errno, "access path", fnbuff);
542 return 0;
543 }
544 } else chmod(fnbuff, mode); // This may fail on some platforms
545
546// All set now
547//
548 return fnbuff;
549}
#define access(a, b)
Definition XrdPosix.hh:44
#define stat(a, b)
Definition XrdPosix.hh:101
size_t strlcpy(char *dst, const char *src, size_t sz)
static int makePath(char *path, mode_t mode, bool reset=false)

References access, XrdOucUtils::makePath(), Say, stat, and strlcpy().

Referenced by Create(), and XrdCmsSupervisor::Init().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SockName()

int XrdNetSocket::SockName ( char * buff,
int blen )

Definition at line 475 of file XrdNetSocket.cc.

476{
477
478// Make sure we have something here
479//
480 if (SockFD < 0) {*buff = 0; return ENOTSOCK;}
481
482// Format the name
483//
484 if (!SockInfo.Format(buff, blen)) return EINVAL;
485 return 0;
486}

Referenced by XrdCmsAdmin::Start().

+ Here is the caller graph for this function:

◆ SockNum()

int XrdNetSocket::SockNum ( )
inline

Definition at line 145 of file XrdNetSocket.hh.

145{return SockFD;}

The documentation for this class was generated from the following files: