40 #include <netinet/in.h>
41 #include <netinet/tcp.h>
42 #include <sys/types.h>
43 #include <sys/socket.h>
51 #include <sys/types.h>
54 #include "XrdSys/XrdWin32.hh"
81 #define Err(p,a,b,c) (ErrCode = (eroute ? eroute->Emsg(#p, a, b, c) : ErrCode),-1)
82 #define ErrM(p,a,b,c) (ErrCode = (eroute ? eroute->Emsg(#p, a, b, c) : ErrCode),-1)
92 SockFD = SockFileDesc;
101 int retc, ClientSock;
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;
115 do {ClientSock = XrdSysFD_Accept(SockFD, (
struct sockaddr *)0, 0);}
116 while(ClientSock < 0 && errno == EINTR);
118 if (ClientSock < 0 && eroute) eroute->
Emsg(
"Accept",errno,
"accept connection");
133 if (SockFD >= 0) {
close(SockFD); SockFD=-1;}
145 const char *fn, mode_t mode,
int opts)
151 mode_t myMode = (mode & (S_IRWXU | S_IRWXG));
152 const char *
eMsg = 0;
153 char fnbuff[1024] = {0};
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;}
170 }
else if (ASock->
Open(fnbuff, -1, sflags) < 0)
173 if (ASock->
Open(fnbuff, -1, sflags) < 0)
180 delete ASock; ASock = 0;
190 {
int oldFD = SockFD;
201 socklen_t szb = (socklen_t)
sizeof(Windowsz);
203 if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (
Sokdata_t)&Windowsz, &szb))
216 const char *epath, *eText, *action =
"configure socket";
218 int myEC, backlog, SockProt;
225 if (inpath) epath = inpath;
226 else {sprintf(pbuff,
"port %d", port);
232 if (SockFD >= 0)
return Err(
Open, EBUSY,
"create socket for", epath);
241 {ErrCode = EHOSTUNREACH;
244 snprintf(buff,
sizeof(buff),
"'%s'; %c%s",epath,tolower(*eText),eText+1);
245 eroute->
Emsg(
"Open",
"Unable to create socket for", buff);
253 if ((SockFD = XrdSysFD_Socket(SockProt, SockType, 0)) < 0)
254 return Err(
Open, errno,
"create socket for", epath);
263 if (SockProt == PF_UNIX)
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);
274 if (windowsz)
setWindow(SockFD, windowsz, eroute);
279 {action =
"bind socket to";
281 else if (SockType == SOCK_STREAM)
282 {action =
"listen on stream";
285 if (listen(SockFD, backlog)) myEC = errno;
287 if (SockProt == PF_UNIX) chmod(inpath, S_IRWXU);
289 if (SockType == SOCK_STREAM)
291 action =
"connect socket to";
305 eroute->
Emsg(
"Open", ErrCode, action, epath);
317 const char *errtxt, *PeerName;
322 {
if (eroute) eroute->
Emsg(
"Peername",
323 "Unable to obtain peer name; socket not open");
329 if (!(PeerName = SockInfo.
Name(0, &errtxt)))
331 eroute->
Emsg(
"Peername",
"Unable to obtain peer name; ",errtxt);
337 if (InetAddr) *InetAddr = SockInfo.
SockAddr();
338 if (InetSize) *InetSize = SockInfo.
SockSize();
350 #if defined(__linux__) || defined(__GNU__)
351 const int szint =
sizeof(int);
366 && setsockopt(xfd,SOL_SOCKET,SO_LINGER,(
Sokdata_t)&liopts,szlio))
372 {
if (setsockopt(xfd,SOL_SOCKET,SO_KEEPALIVE,(
Sokdata_t)&one,szone))
376 #if defined(__linux__) || defined(__GNU__)
398 && setsockopt(xfd, tcpprotid, TCP_NODELAY, (
Sokdata_t)&one,szone))
415 if (setsockopt(xfd, SOL_SOCKET, SO_SNDBUF,
421 if (setsockopt(xfd, SOL_SOCKET, SO_RCVBUF,
438 if (SockFD < 0) {*buff = 0;
return ENOTSOCK;}
442 if (!SockInfo.
Format(buff, blen))
return EINVAL;
451 const char *path,
const char *fn, mode_t mode)
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;
463 if (
strlcpy(fnbuff, path, 1024) >= 1024 || (i + fnlen + 1) >= 1024)
464 {
Say->
Emsg(
"createPath",
"Socket path", path,
"too long");
471 {
if (fnbuff[i-1] ==
'/') fnbuff[i-1] =
'\0';
472 if ((sp = rindex(fnbuff,
'/'))) *sp =
'\0';
478 {
Say->
Emsg(
"createPath", errno,
"create path", path);
485 else {
if (path[i-1] !=
'/') fnbuff[i++] =
'/';
486 if (fn) strcpy(fnbuff+i, fn);
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");
499 {
Say->
Emsg(
"createPath", errno,
"access path", fnbuff);
502 }
else chmod(fnbuff, mode);
static XrdSysError eDest(0,"crypto_")
#define XRDNETSOCKET_MAXBKLG
#define XRDNETSOCKET_LINGER
int stat(const char *path, struct stat *buf)
int unlink(const char *path)
int access(const char *path, int amode)
const sockaddr * SockAddr()
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
const char * Name(const char *eName=0, const char **eText=0)
static const int PortInSpec
const char * Set(const char *hSpec, int pNum=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)
int SockName(char *buff, int blen)
XrdNetSocket(XrdSysError *erobj=0, int SockFileDesc=-1)
int Open(const char *path, int port=-1, int flags=0, int sockbuffsz=0)
static int setOpts(int fd, int options, XrdSysError *eDest=0)
const char * Peername(const struct sockaddr **InetAddr=0, int *InetSize=0)
static char * socketPath(XrdSysError *Say, char *inbuff, const char *path, const char *fn, mode_t mode)
static int getWindow(int fd, int &Windowsz, XrdSysError *eDest=0)
static XrdNetSocket * Create(XrdSysError *Say, const char *path, const char *fn, mode_t mode, int isudp=0)
static int ProtoID(const char *pName)
static int makePath(char *path, mode_t mode, bool reset=false)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)