XRootD
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)
 
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 }
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95

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:43

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 }
#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)
Definition: XrdNetSocket.cc:88
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)
XrdSysError Say

References XrdNetSocket(), XrdSysError::Emsg(), eMsg, LastError(), Open(), opts, XrdCms::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::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

References eDest, XrdSysError::Emsg(), and Sokdata_t.

Referenced by XrdNet::WSize().

+ Here is the call graph for this function:
+ 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(), 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  if (SockType == SOCK_STREAM)
290  {int tmo = flags & XRDNET_TOUT;
291  action = "connect socket to";
292  if (tmo) 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 
299 // Check for any errors and return (Close() sets SockFD to -1).
300 //
301  if (myEC)
302  {Close();
303  ErrCode = myEC;
304  if (!(flags & XRDNET_NOEMSG) && eroute)
305  eroute->Emsg("Open", ErrCode, action, epath);
306  }
307  return SockFD;
308 }
#define XRDNET_TOUT
Definition: XrdNetOpts.hh:110
#define XRDNET_NOEMSG
Definition: XrdNetOpts.hh:71
#define XRDNET_BKLG
Definition: XrdNetOpts.hh:104
#define XRDNETSOCKET_MAXBKLG
Definition: XrdNetOpts.hh:118
#define Err(p, a, b, c)
Definition: XrdNetSocket.cc:81
int unlink(const char *path)
#define SOCKLEN_t
const sockaddr * SockAddr()
SOCKLEN_t SockSize()
static const int PortInSpec
Definition: XrdNetAddr.hh:112
const char * Set(const char *hSpec, int pNum=PortInSpec)
Definition: XrdNetAddr.cc:216
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(), XrdSysError::Emsg(), Err, XrdNetAddr::PortInSpec, XrdNetAddrInfo::Protocol(), XrdNetAddr::Set(), setOpts(), setWindow(), XrdNetAddrInfo::SockAddr(), SOCKLEN_t, XrdNetAddrInfo::SockSize(), Sokdata_t, unlink(), XRDNET_BKLG, XRDNET_NOEMSG, XRDNET_SERVER, XRDNET_TOUT, XRDNET_UDPSOCKET, and XRDNETSOCKET_MAXBKLG.

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

+ 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 314 of file XrdNetSocket.cc.

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

References XrdSysError::Emsg(), XrdNetAddrInfo::Name(), XrdNetAddrInfo::SockAddr(), and XrdNetAddrInfo::SockSize().

Referenced by XrdNet::Connect().

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

◆ setOpts()

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

Definition at line 346 of file XrdNetSocket.cc.

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

References eDest, XrdSysError::Emsg(), 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 410 of file XrdNetSocket.cc.

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

References eDest, XrdSysError::Emsg(), SOCKLEN_t, and Sokdata_t.

Referenced by Open().

+ Here is the call graph for this function:
+ 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 450 of file XrdNetSocket.cc.

452 {
453  const int srchOK = S_IXUSR | S_IXGRP;
454  const int sfMask = (S_IFIFO | S_IFSOCK);
455  int rc, i, fnlen = strlen(fnbuff);
456  mode_t myMode = (mode & (S_IRWXU | S_IRWXG)) | srchOK;
457  struct stat buf;
458  char *sp = 0;
459 
460 // Copy the const char path because makePath modifies it
461 //
462  i = strlen(path);
463  if (strlcpy(fnbuff, path, 1024) >= 1024 || (i + fnlen + 1) >= 1024)
464  {Say->Emsg("createPath", "Socket path", path, "too long");
465  return 0;
466  }
467 
468 // Check if we should separate the filename from the path
469 //
470  if (!fn)
471  {if (fnbuff[i-1] == '/') fnbuff[i-1] = '\0';
472  if ((sp = rindex(fnbuff, '/'))) *sp = '\0';
473  }
474 
475 // Create the directory if it is not already there
476 //
477  if ((rc = XrdOucUtils::makePath(fnbuff, myMode)))
478  {Say->Emsg("createPath", errno, "create path", path);
479  return 0;
480  }
481 
482 // Construct full filename
483 //
484  if (sp) *sp = '/';
485  else {if (path[i-1] != '/') fnbuff[i++] = '/';
486  if (fn) strcpy(fnbuff+i, fn);
487  }
488 
489 // Check is we have already created it and whether we can access
490 //
491  if (!stat(fnbuff,&buf))
492  {if ((buf.st_mode & S_IFMT) != (mode & sfMask))
493  {Say->Emsg("createPath","Path",fnbuff,
494  (mode & S_IFSOCK) ? "exists but is not a socket"
495  : "exists but is not a pipe");
496  return 0;
497  }
498  if (access(fnbuff, W_OK))
499  {Say->Emsg("createPath", errno, "access path", fnbuff);
500  return 0;
501  }
502  } else chmod(fnbuff, mode); // This may fail on some platforms
503 
504 // All set now
505 //
506  return fnbuff;
507 }
int stat(const char *path, struct stat *buf)
int access(const char *path, int amode)
size_t strlcpy(char *dst, const char *src, size_t sz)
static int makePath(char *path, mode_t mode, bool reset=false)
Definition: XrdOucUtils.cc:917

References access(), XrdSysError::Emsg(), XrdOucUtils::makePath(), XrdCms::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 433 of file XrdNetSocket.cc.

434 {
435 
436 // Make sure we have something here
437 //
438  if (SockFD < 0) {*buff = 0; return ENOTSOCK;}
439 
440 // Format the name
441 //
442  if (!SockInfo.Format(buff, blen)) return EINVAL;
443  return 0;
444 }
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)

References XrdNetAddrInfo::Format().

Referenced by XrdCmsAdmin::Start().

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

◆ SockNum()

int XrdNetSocket::SockNum ( )
inline

Definition at line 139 of file XrdNetSocket.hh.

139 {return SockFD;}

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