File indexing completed on 2025-01-18 10:14:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 #include <ctype.h>
0073 #ifdef XTHREADS
0074 #include <X11/Xthreads.h>
0075 #endif
0076
0077 #ifndef WIN32
0078
0079 #if defined(TCPCONN) || defined(UNIXCONN)
0080 #include <sys/socket.h>
0081 #include <netinet/in.h>
0082 #include <arpa/inet.h>
0083 #endif
0084
0085 #if defined(TCPCONN) || defined(UNIXCONN)
0086 #define X_INCLUDE_NETDB_H
0087 #define XOS_USE_NO_LOCKING
0088 #include <X11/Xos_r.h>
0089 #endif
0090
0091 #ifdef UNIXCONN
0092 #ifndef X_NO_SYS_UN
0093 #include <sys/un.h>
0094 #endif
0095 #include <sys/stat.h>
0096 #endif
0097
0098
0099 #ifndef NO_TCP_H
0100 #if defined(linux) || defined(__GLIBC__)
0101 #include <sys/param.h>
0102 #endif
0103 #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
0104 #include <sys/param.h>
0105 #include <machine/endian.h>
0106 #endif
0107 #include <netinet/tcp.h>
0108 #endif
0109
0110 #include <sys/ioctl.h>
0111 #if defined(SVR4) || defined(__SVR4)
0112 #include <sys/filio.h>
0113 #endif
0114
0115 #include <unistd.h>
0116
0117 #else
0118
0119 #include <X11/Xwinsock.h>
0120 #include <X11/Xwindows.h>
0121 #include <X11/Xw32defs.h>
0122 #undef close
0123 #define close closesocket
0124 #define ECONNREFUSED WSAECONNREFUSED
0125 #define EADDRINUSE WSAEADDRINUSE
0126 #define EPROTOTYPE WSAEPROTOTYPE
0127 #undef EWOULDBLOCK
0128 #define EWOULDBLOCK WSAEWOULDBLOCK
0129 #define EINPROGRESS WSAEINPROGRESS
0130 #undef EINTR
0131 #define EINTR WSAEINTR
0132 #define X_INCLUDE_NETDB_H
0133 #define XOS_USE_MTSAFE_NETDBAPI
0134 #include <X11/Xos_r.h>
0135 #endif
0136
0137 #if defined(SO_DONTLINGER) && defined(SO_LINGER)
0138 #undef SO_DONTLINGER
0139 #endif
0140
0141
0142 #define SocketInitOnce()
0143
0144 #ifdef __linux__
0145 #define HAVE_ABSTRACT_SOCKETS
0146 #endif
0147
0148 #define MIN_BACKLOG 128
0149 #ifdef SOMAXCONN
0150 #if SOMAXCONN > MIN_BACKLOG
0151 #define BACKLOG SOMAXCONN
0152 #endif
0153 #endif
0154 #ifndef BACKLOG
0155 #define BACKLOG MIN_BACKLOG
0156 #endif
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 typedef struct _Sockettrans2dev {
0167 const char *transname;
0168 int family;
0169 int devcotsname;
0170 int devcltsname;
0171 int protocol;
0172 } Sockettrans2dev;
0173
0174 static Sockettrans2dev Sockettrans2devtab[] = {
0175 #ifdef TCPCONN
0176 {"inet",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
0177 #if !defined(IPv6) || !defined(AF_INET6)
0178 {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
0179 #else
0180 {"tcp",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0},
0181 {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
0182 {"inet6",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0},
0183 #endif
0184 #endif
0185 #ifdef UNIXCONN
0186 {"unix",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
0187 #if !defined(LOCALCONN)
0188 {"local",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
0189 #endif
0190 #endif
0191 };
0192
0193 #define NUMSOCKETFAMILIES (sizeof(Sockettrans2devtab)/sizeof(Sockettrans2dev))
0194
0195 #ifdef TCPCONN
0196 static int TRANS(SocketINETClose) (XtransConnInfo ciptr);
0197 #endif
0198
0199 #if (defined(TCPCONN) && defined(TRANS_SERVER)) || defined(TRANS_REOPEN) || \
0200 !defined(IPv6)
0201 static int
0202 is_numeric (const char *str)
0203 {
0204 int i;
0205
0206 for (i = 0; i < (int) strlen (str); i++)
0207 if (!isdigit (str[i]))
0208 return (0);
0209
0210 return (1);
0211 }
0212 #endif
0213
0214 #ifdef UNIXCONN
0215
0216
0217 #if defined(X11_t)
0218 #define UNIX_PATH "/tmp/.X11-unix/X"
0219 #define UNIX_DIR "/tmp/.X11-unix"
0220 #endif
0221 #if defined(XIM_t)
0222 #define UNIX_PATH "/tmp/.XIM-unix/XIM"
0223 #define UNIX_DIR "/tmp/.XIM-unix"
0224 #endif
0225 #if defined(FS_t) || defined(FONT_t)
0226 #define UNIX_PATH "/tmp/.font-unix/fs"
0227 #define UNIX_DIR "/tmp/.font-unix"
0228 #endif
0229 #if defined(ICE_t)
0230 #define UNIX_PATH "/tmp/.ICE-unix/"
0231 #define UNIX_DIR "/tmp/.ICE-unix"
0232 #endif
0233
0234
0235 #endif
0236
0237 #define PORTBUFSIZE 32
0238
0239 #ifndef MAXHOSTNAMELEN
0240 #define MAXHOSTNAMELEN 255
0241 #endif
0242
0243 #if defined HAVE_SOCKLEN_T || (defined(IPv6) && defined(AF_INET6))
0244 # define SOCKLEN_T socklen_t
0245 #elif defined(SVR4) || defined(__SVR4)
0246 # define SOCKLEN_T size_t
0247 #else
0248 # define SOCKLEN_T int
0249 #endif
0250
0251
0252
0253
0254
0255 static int
0256 TRANS(SocketSelectFamily) (int first, const char *family)
0257
0258 {
0259 int i;
0260
0261 prmsg (3,"SocketSelectFamily(%s)\n", family);
0262
0263 for (i = first + 1; i < (int)NUMSOCKETFAMILIES; i++)
0264 {
0265 if (!strcmp (family, Sockettrans2devtab[i].transname))
0266 return i;
0267 }
0268
0269 return (first == -1 ? -2 : -1);
0270 }
0271
0272
0273
0274
0275
0276
0277
0278 static int
0279 TRANS(SocketINETGetAddr) (XtransConnInfo ciptr)
0280
0281 {
0282 #if defined(IPv6) && defined(AF_INET6)
0283 struct sockaddr_storage socknamev6;
0284 #else
0285 struct sockaddr_in socknamev4;
0286 #endif
0287 void *socknamePtr;
0288 SOCKLEN_T namelen;
0289
0290 prmsg (3,"SocketINETGetAddr(%p)\n", ciptr);
0291
0292 #if defined(IPv6) && defined(AF_INET6)
0293 namelen = sizeof(socknamev6);
0294 socknamePtr = &socknamev6;
0295 #else
0296 namelen = sizeof(socknamev4);
0297 socknamePtr = &socknamev4;
0298 #endif
0299
0300 bzero(socknamePtr, namelen);
0301
0302 if (getsockname (ciptr->fd,(struct sockaddr *) socknamePtr,
0303 (void *)&namelen) < 0)
0304 {
0305 #ifdef WIN32
0306 errno = WSAGetLastError();
0307 #endif
0308 prmsg (1,"SocketINETGetAddr: getsockname() failed: %d\n",
0309 EGET());
0310 return -1;
0311 }
0312
0313
0314
0315
0316
0317 if ((ciptr->addr = malloc (namelen)) == NULL)
0318 {
0319 prmsg (1,
0320 "SocketINETGetAddr: Can't allocate space for the addr\n");
0321 return -1;
0322 }
0323
0324 #if defined(IPv6) && defined(AF_INET6)
0325 ciptr->family = ((struct sockaddr *)socknamePtr)->sa_family;
0326 #else
0327 ciptr->family = socknamev4.sin_family;
0328 #endif
0329 ciptr->addrlen = namelen;
0330 memcpy (ciptr->addr, socknamePtr, ciptr->addrlen);
0331
0332 return 0;
0333 }
0334
0335
0336
0337
0338
0339
0340
0341 static int
0342 TRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr)
0343
0344 {
0345 #if defined(IPv6) && defined(AF_INET6)
0346 struct sockaddr_storage socknamev6;
0347 #endif
0348 struct sockaddr_in socknamev4;
0349 void *socknamePtr;
0350 SOCKLEN_T namelen;
0351
0352 #if defined(IPv6) && defined(AF_INET6)
0353 if (ciptr->family == AF_INET6)
0354 {
0355 namelen = sizeof(socknamev6);
0356 socknamePtr = &socknamev6;
0357 }
0358 else
0359 #endif
0360 {
0361 namelen = sizeof(socknamev4);
0362 socknamePtr = &socknamev4;
0363 }
0364
0365 bzero(socknamePtr, namelen);
0366
0367 prmsg (3,"SocketINETGetPeerAddr(%p)\n", ciptr);
0368
0369 if (getpeername (ciptr->fd, (struct sockaddr *) socknamePtr,
0370 (void *)&namelen) < 0)
0371 {
0372 #ifdef WIN32
0373 errno = WSAGetLastError();
0374 #endif
0375 prmsg (1,"SocketINETGetPeerAddr: getpeername() failed: %d\n",
0376 EGET());
0377 return -1;
0378 }
0379
0380
0381
0382
0383
0384 if ((ciptr->peeraddr = malloc (namelen)) == NULL)
0385 {
0386 prmsg (1,
0387 "SocketINETGetPeerAddr: Can't allocate space for the addr\n");
0388 return -1;
0389 }
0390
0391 ciptr->peeraddrlen = namelen;
0392 memcpy (ciptr->peeraddr, socknamePtr, ciptr->peeraddrlen);
0393
0394 return 0;
0395 }
0396
0397
0398 static XtransConnInfo
0399 TRANS(SocketOpen) (int i, int type)
0400
0401 {
0402 XtransConnInfo ciptr;
0403
0404 prmsg (3,"SocketOpen(%d,%d)\n", i, type);
0405
0406 if ((ciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL)
0407 {
0408 prmsg (1, "SocketOpen: malloc failed\n");
0409 return NULL;
0410 }
0411
0412 ciptr->fd = socket(Sockettrans2devtab[i].family, type,
0413 Sockettrans2devtab[i].protocol);
0414
0415 #ifndef WIN32
0416 #if (defined(X11_t) && !defined(USE_POLL)) || defined(FS_t) || defined(FONT_t)
0417 if (ciptr->fd >= sysconf(_SC_OPEN_MAX))
0418 {
0419 prmsg (2, "SocketOpen: socket() returned out of range fd %d\n",
0420 ciptr->fd);
0421 close (ciptr->fd);
0422 ciptr->fd = -1;
0423 }
0424 #endif
0425 #endif
0426
0427 if (ciptr->fd < 0) {
0428 #ifdef WIN32
0429 errno = WSAGetLastError();
0430 #endif
0431 prmsg (2, "SocketOpen: socket() failed for %s\n",
0432 Sockettrans2devtab[i].transname);
0433
0434 free (ciptr);
0435 return NULL;
0436 }
0437
0438 #ifdef TCP_NODELAY
0439 if (Sockettrans2devtab[i].family == AF_INET
0440 #if defined(IPv6) && defined(AF_INET6)
0441 || Sockettrans2devtab[i].family == AF_INET6
0442 #endif
0443 )
0444 {
0445
0446
0447
0448
0449 int tmp = 1;
0450 setsockopt (ciptr->fd, IPPROTO_TCP, TCP_NODELAY,
0451 (char *) &tmp, sizeof (int));
0452 }
0453 #endif
0454
0455
0456
0457
0458
0459
0460 #ifdef SO_SNDBUF
0461 if (Sockettrans2devtab[i].family == AF_UNIX)
0462 {
0463 SOCKLEN_T len = sizeof (int);
0464 int val;
0465
0466 if (getsockopt (ciptr->fd, SOL_SOCKET, SO_SNDBUF,
0467 (char *) &val, &len) == 0 && val < 64 * 1024)
0468 {
0469 val = 64 * 1024;
0470 setsockopt (ciptr->fd, SOL_SOCKET, SO_SNDBUF,
0471 (char *) &val, sizeof (int));
0472 }
0473 }
0474 #endif
0475
0476 return ciptr;
0477 }
0478
0479
0480 #ifdef TRANS_REOPEN
0481
0482 static XtransConnInfo
0483 TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, const char *port)
0484
0485 {
0486 XtransConnInfo ciptr;
0487 int portlen;
0488 struct sockaddr *addr;
0489 size_t addrlen;
0490
0491 prmsg (3,"SocketReopen(%d,%d,%s)\n", type, fd, port);
0492
0493 if (port == NULL) {
0494 prmsg (1, "SocketReopen: port was null!\n");
0495 return NULL;
0496 }
0497
0498 portlen = strlen(port) + 1;
0499 #ifdef SOCK_MAXADDRLEN
0500 if (portlen < 0 || portlen > (SOCK_MAXADDRLEN + 2)) {
0501 prmsg (1, "SocketReopen: invalid portlen %d\n", portlen);
0502 return NULL;
0503 }
0504 if (portlen < 14) portlen = 14;
0505 #else
0506 if (portlen < 0 || portlen > 14) {
0507 prmsg (1, "SocketReopen: invalid portlen %d\n", portlen);
0508 return NULL;
0509 }
0510 #endif
0511
0512 if ((ciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL)
0513 {
0514 prmsg (1, "SocketReopen: malloc(ciptr) failed\n");
0515 return NULL;
0516 }
0517
0518 ciptr->fd = fd;
0519
0520 addrlen = portlen + offsetof(struct sockaddr, sa_data);
0521 if ((addr = calloc (1, addrlen)) == NULL) {
0522 prmsg (1, "SocketReopen: malloc(addr) failed\n");
0523 free (ciptr);
0524 return NULL;
0525 }
0526 ciptr->addr = (char *) addr;
0527 ciptr->addrlen = addrlen;
0528
0529 if ((ciptr->peeraddr = calloc (1, addrlen)) == NULL) {
0530 prmsg (1, "SocketReopen: malloc(portaddr) failed\n");
0531 free (addr);
0532 free (ciptr);
0533 return NULL;
0534 }
0535 ciptr->peeraddrlen = addrlen;
0536
0537
0538 ciptr->flags = TRANS_LOCAL | TRANS_NOUNLINK;
0539 #ifdef BSD44SOCKETS
0540 addr->sa_len = addrlen;
0541 #endif
0542 addr->sa_family = AF_UNIX;
0543 #if defined(HAVE_STRLCPY) || defined(HAS_STRLCPY)
0544 strlcpy(addr->sa_data, port, portlen);
0545 #else
0546 strncpy(addr->sa_data, port, portlen);
0547 #endif
0548 ciptr->family = AF_UNIX;
0549 memcpy(ciptr->peeraddr, ciptr->addr, addrlen);
0550 ciptr->port = rindex(addr->sa_data, ':');
0551 if (ciptr->port == NULL) {
0552 if (is_numeric(addr->sa_data)) {
0553 ciptr->port = addr->sa_data;
0554 }
0555 } else if (ciptr->port[0] == ':') {
0556 ciptr->port++;
0557 }
0558
0559 return ciptr;
0560 }
0561
0562 #endif
0563
0564
0565
0566
0567
0568
0569 #ifdef TRANS_CLIENT
0570
0571 static XtransConnInfo
0572 TRANS(SocketOpenCOTSClientBase) (const char *transname, const char *protocol,
0573 const char *host, const char *port, int previndex)
0574 {
0575 XtransConnInfo ciptr;
0576 int i = previndex;
0577
0578 prmsg (2, "SocketOpenCOTSClient(%s,%s,%s)\n",
0579 protocol, host, port);
0580
0581 SocketInitOnce();
0582
0583 while ((i = TRANS(SocketSelectFamily) (i, transname)) >= 0) {
0584 if ((ciptr = TRANS(SocketOpen) (
0585 i, Sockettrans2devtab[i].devcotsname)) != NULL) {
0586
0587
0588 ciptr->index = i;
0589 break;
0590 }
0591 }
0592 if (i < 0) {
0593 if (i == -1)
0594 prmsg (1,"SocketOpenCOTSClient: Unable to open socket for %s\n",
0595 transname);
0596 else
0597 prmsg (1,"SocketOpenCOTSClient: Unable to determine socket type for %s\n",
0598 transname);
0599 return NULL;
0600 }
0601
0602 return ciptr;
0603 }
0604
0605 static XtransConnInfo
0606 TRANS(SocketOpenCOTSClient) (Xtransport *thistrans, const char *protocol,
0607 const char *host, const char *port)
0608 {
0609 return TRANS(SocketOpenCOTSClientBase)(
0610 thistrans->TransName, protocol, host, port, -1);
0611 }
0612
0613
0614 #endif
0615
0616
0617 #ifdef TRANS_SERVER
0618
0619 static XtransConnInfo
0620 TRANS(SocketOpenCOTSServer) (Xtransport *thistrans, const char *protocol,
0621 const char *host, const char *port)
0622
0623 {
0624 XtransConnInfo ciptr;
0625 int i = -1;
0626
0627 prmsg (2,"SocketOpenCOTSServer(%s,%s,%s)\n", protocol, host, port);
0628
0629 SocketInitOnce();
0630
0631 while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
0632 if ((ciptr = TRANS(SocketOpen) (
0633 i, Sockettrans2devtab[i].devcotsname)) != NULL)
0634 break;
0635 }
0636 if (i < 0) {
0637 if (i == -1) {
0638 if (errno == EAFNOSUPPORT) {
0639 thistrans->flags |= TRANS_NOLISTEN;
0640 prmsg (1,"SocketOpenCOTSServer: Socket for %s unsupported on this system.\n",
0641 thistrans->TransName);
0642 } else {
0643 prmsg (1,"SocketOpenCOTSServer: Unable to open socket for %s\n",
0644 thistrans->TransName);
0645 }
0646 } else {
0647 prmsg (1,"SocketOpenCOTSServer: Unable to determine socket type for %s\n",
0648 thistrans->TransName);
0649 }
0650 return NULL;
0651 }
0652
0653
0654
0655
0656
0657 #ifdef SO_REUSEADDR
0658
0659
0660
0661
0662
0663 if (Sockettrans2devtab[i].family == AF_INET
0664 #if defined(IPv6) && defined(AF_INET6)
0665 || Sockettrans2devtab[i].family == AF_INET6
0666 #endif
0667 )
0668 {
0669 int one = 1;
0670 setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR,
0671 (char *) &one, sizeof (int));
0672 }
0673 #endif
0674 #ifdef IPV6_V6ONLY
0675 if (Sockettrans2devtab[i].family == AF_INET6)
0676 {
0677 int one = 1;
0678 setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int));
0679 }
0680 #endif
0681
0682
0683 ciptr->index = i;
0684
0685 return ciptr;
0686 }
0687
0688 #endif
0689
0690
0691 #ifdef TRANS_REOPEN
0692
0693 static XtransConnInfo
0694 TRANS(SocketReopenCOTSServer) (Xtransport *thistrans, int fd, const char *port)
0695
0696 {
0697 XtransConnInfo ciptr;
0698 int i = -1;
0699
0700 prmsg (2,
0701 "SocketReopenCOTSServer(%d, %s)\n", fd, port);
0702
0703 SocketInitOnce();
0704
0705 while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
0706 if ((ciptr = TRANS(SocketReopen) (
0707 i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL)
0708 break;
0709 }
0710 if (i < 0) {
0711 if (i == -1)
0712 prmsg (1,"SocketReopenCOTSServer: Unable to open socket for %s\n",
0713 thistrans->TransName);
0714 else
0715 prmsg (1,"SocketReopenCOTSServer: Unable to determine socket type for %s\n",
0716 thistrans->TransName);
0717 return NULL;
0718 }
0719
0720
0721
0722 ciptr->index = i;
0723
0724 return ciptr;
0725 }
0726
0727 #endif
0728
0729
0730 static int
0731 TRANS(SocketSetOption) (XtransConnInfo ciptr, int option, int arg)
0732
0733 {
0734 prmsg (2,"SocketSetOption(%d,%d,%d)\n", ciptr->fd, option, arg);
0735
0736 return -1;
0737 }
0738
0739 #ifdef UNIXCONN
0740 static int
0741 set_sun_path(const char *port, const char *upath, char *path, int abstract)
0742 {
0743 struct sockaddr_un s;
0744 ssize_t maxlen = sizeof(s.sun_path) - 1;
0745 const char *at = "";
0746
0747 if (!port || !*port || !path)
0748 return -1;
0749
0750 #ifdef HAVE_ABSTRACT_SOCKETS
0751 if (port[0] == '@')
0752 upath = "";
0753 else if (abstract)
0754 at = "@";
0755 #endif
0756
0757 if (*port == '/')
0758 upath = "";
0759
0760 if ((ssize_t)(strlen(at) + strlen(upath) + strlen(port)) > maxlen)
0761 return -1;
0762 snprintf(path, sizeof(s.sun_path), "%s%s%s", at, upath, port);
0763 return 0;
0764 }
0765 #endif
0766
0767 #ifdef TRANS_SERVER
0768
0769 static int
0770 TRANS(SocketCreateListener) (XtransConnInfo ciptr,
0771 struct sockaddr *sockname,
0772 int socknamelen, unsigned int flags)
0773
0774 {
0775 SOCKLEN_T namelen = socknamelen;
0776 int fd = ciptr->fd;
0777 int retry;
0778
0779 prmsg (3, "SocketCreateListener(%p,%d)\n", ciptr, fd);
0780
0781 if (Sockettrans2devtab[ciptr->index].family == AF_INET
0782 #if defined(IPv6) && defined(AF_INET6)
0783 || Sockettrans2devtab[ciptr->index].family == AF_INET6
0784 #endif
0785 )
0786 retry = 20;
0787 else
0788 retry = 0;
0789
0790 while (bind (fd, sockname, namelen) < 0)
0791 {
0792 if (errno == EADDRINUSE) {
0793 if (flags & ADDR_IN_USE_ALLOWED)
0794 break;
0795 else
0796 return TRANS_ADDR_IN_USE;
0797 }
0798
0799 if (retry-- == 0) {
0800 prmsg (1, "SocketCreateListener: failed to bind listener\n");
0801 close (fd);
0802 return TRANS_CREATE_LISTENER_FAILED;
0803 }
0804 #ifdef SO_REUSEADDR
0805 sleep (1);
0806 #else
0807 sleep (10);
0808 #endif
0809 }
0810
0811 if (Sockettrans2devtab[ciptr->index].family == AF_INET
0812 #if defined(IPv6) && defined(AF_INET6)
0813 || Sockettrans2devtab[ciptr->index].family == AF_INET6
0814 #endif
0815 ) {
0816 #ifdef SO_DONTLINGER
0817 setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);
0818 #else
0819 #ifdef SO_LINGER
0820 {
0821 static int linger[2] = { 0, 0 };
0822 setsockopt (fd, SOL_SOCKET, SO_LINGER,
0823 (char *) linger, sizeof (linger));
0824 }
0825 #endif
0826 #endif
0827 }
0828
0829 if (listen (fd, BACKLOG) < 0)
0830 {
0831 prmsg (1, "SocketCreateListener: listen() failed\n");
0832 close (fd);
0833 return TRANS_CREATE_LISTENER_FAILED;
0834 }
0835
0836
0837
0838 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
0839
0840 return 0;
0841 }
0842
0843 #ifdef TCPCONN
0844 static int
0845 TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, const char *port,
0846 unsigned int flags)
0847
0848 {
0849 #if defined(IPv6) && defined(AF_INET6)
0850 struct sockaddr_storage sockname;
0851 #else
0852 struct sockaddr_in sockname;
0853 #endif
0854 unsigned short sport;
0855 SOCKLEN_T namelen = sizeof(sockname);
0856 int status;
0857 long tmpport;
0858 #ifdef XTHREADS_NEEDS_BYNAMEPARAMS
0859 _Xgetservbynameparams sparams;
0860 #endif
0861 struct servent *servp;
0862
0863 #ifdef X11_t
0864 char portbuf[PORTBUFSIZE];
0865 #endif
0866
0867 prmsg (2, "SocketINETCreateListener(%s)\n", port);
0868
0869 #ifdef X11_t
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879 if (is_numeric (port))
0880 {
0881
0882 tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
0883 snprintf (portbuf, sizeof(portbuf), "%lu", tmpport);
0884 port = portbuf;
0885 }
0886 #endif
0887
0888 if (port && *port)
0889 {
0890
0891
0892 if (!is_numeric (port))
0893 {
0894 if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL)
0895 {
0896 prmsg (1,
0897 "SocketINETCreateListener: Unable to get service for %s\n",
0898 port);
0899 return TRANS_CREATE_LISTENER_FAILED;
0900 }
0901
0902 sport = servp->s_port;
0903 }
0904 else
0905 {
0906 tmpport = strtol (port, (char**)NULL, 10);
0907
0908
0909
0910
0911
0912
0913 if (tmpport < 1024 || tmpport > USHRT_MAX)
0914 return TRANS_CREATE_LISTENER_FAILED;
0915
0916 sport = (unsigned short) tmpport;
0917 }
0918 }
0919 else
0920 sport = 0;
0921
0922 bzero(&sockname, sizeof(sockname));
0923 #if defined(IPv6) && defined(AF_INET6)
0924 if (Sockettrans2devtab[ciptr->index].family == AF_INET) {
0925 namelen = sizeof (struct sockaddr_in);
0926 #ifdef BSD44SOCKETS
0927 ((struct sockaddr_in *)&sockname)->sin_len = namelen;
0928 #endif
0929 ((struct sockaddr_in *)&sockname)->sin_family = AF_INET;
0930 ((struct sockaddr_in *)&sockname)->sin_port = htons(sport);
0931 ((struct sockaddr_in *)&sockname)->sin_addr.s_addr = htonl(INADDR_ANY);
0932 } else {
0933 namelen = sizeof (struct sockaddr_in6);
0934 #ifdef SIN6_LEN
0935 ((struct sockaddr_in6 *)&sockname)->sin6_len = sizeof(sockname);
0936 #endif
0937 ((struct sockaddr_in6 *)&sockname)->sin6_family = AF_INET6;
0938 ((struct sockaddr_in6 *)&sockname)->sin6_port = htons(sport);
0939 ((struct sockaddr_in6 *)&sockname)->sin6_addr = in6addr_any;
0940 }
0941 #else
0942 #ifdef BSD44SOCKETS
0943 sockname.sin_len = sizeof (sockname);
0944 #endif
0945 sockname.sin_family = AF_INET;
0946 sockname.sin_port = htons (sport);
0947 sockname.sin_addr.s_addr = htonl (INADDR_ANY);
0948 #endif
0949
0950 if ((status = TRANS(SocketCreateListener) (ciptr,
0951 (struct sockaddr *) &sockname, namelen, flags)) < 0)
0952 {
0953 prmsg (1,
0954 "SocketINETCreateListener: ...SocketCreateListener() failed\n");
0955 return status;
0956 }
0957
0958 if (TRANS(SocketINETGetAddr) (ciptr) < 0)
0959 {
0960 prmsg (1,
0961 "SocketINETCreateListener: ...SocketINETGetAddr() failed\n");
0962 return TRANS_CREATE_LISTENER_FAILED;
0963 }
0964
0965 return 0;
0966 }
0967
0968 #endif
0969
0970
0971 #ifdef UNIXCONN
0972
0973 static int
0974 TRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, const char *port,
0975 unsigned int flags)
0976
0977 {
0978 struct sockaddr_un sockname;
0979 int namelen;
0980 int oldUmask;
0981 int status;
0982 unsigned int mode;
0983 char tmpport[108];
0984
0985 int abstract = 0;
0986 #ifdef HAVE_ABSTRACT_SOCKETS
0987 abstract = ciptr->transptr->flags & TRANS_ABSTRACT;
0988 #endif
0989
0990 prmsg (2, "SocketUNIXCreateListener(%s)\n",
0991 port ? port : "NULL");
0992
0993
0994
0995 oldUmask = umask (0);
0996
0997 #ifdef UNIX_DIR
0998 #ifdef HAS_STICKY_DIR_BIT
0999 mode = 01777;
1000 #else
1001 mode = 0777;
1002 #endif
1003 if (!abstract && trans_mkdir(UNIX_DIR, mode) == -1) {
1004 prmsg (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n",
1005 UNIX_DIR, errno);
1006 (void) umask (oldUmask);
1007 return TRANS_CREATE_LISTENER_FAILED;
1008 }
1009 #endif
1010
1011 memset(&sockname, 0, sizeof(sockname));
1012 sockname.sun_family = AF_UNIX;
1013
1014 if (!(port && *port)) {
1015 snprintf (tmpport, sizeof(tmpport), "%s%ld", UNIX_PATH, (long)getpid());
1016 port = tmpport;
1017 }
1018 if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) {
1019 prmsg (1, "SocketUNIXCreateListener: path too long\n");
1020 return TRANS_CREATE_LISTENER_FAILED;
1021 }
1022
1023 #if defined(BSD44SOCKETS)
1024 sockname.sun_len = strlen(sockname.sun_path);
1025 #endif
1026
1027 #if defined(BSD44SOCKETS) || defined(SUN_LEN)
1028 namelen = SUN_LEN(&sockname);
1029 #else
1030 namelen = strlen(sockname.sun_path) + offsetof(struct sockaddr_un, sun_path);
1031 #endif
1032
1033 if (abstract) {
1034 sockname.sun_path[0] = '\0';
1035 namelen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&sockname.sun_path[1]);
1036 }
1037 else
1038 unlink (sockname.sun_path);
1039
1040 if ((status = TRANS(SocketCreateListener) (ciptr,
1041 (struct sockaddr *) &sockname, namelen, flags)) < 0)
1042 {
1043 prmsg (1,
1044 "SocketUNIXCreateListener: ...SocketCreateListener() failed\n");
1045 (void) umask (oldUmask);
1046 return status;
1047 }
1048
1049
1050
1051
1052
1053
1054
1055
1056 namelen = sizeof (sockname);
1057
1058 if ((ciptr->addr = malloc (namelen)) == NULL)
1059 {
1060 prmsg (1,
1061 "SocketUNIXCreateListener: Can't allocate space for the addr\n");
1062 (void) umask (oldUmask);
1063 return TRANS_CREATE_LISTENER_FAILED;
1064 }
1065
1066 if (abstract)
1067 sockname.sun_path[0] = '@';
1068
1069 ciptr->family = sockname.sun_family;
1070 ciptr->addrlen = namelen;
1071 memcpy (ciptr->addr, &sockname, ciptr->addrlen);
1072
1073 (void) umask (oldUmask);
1074
1075 return 0;
1076 }
1077
1078
1079 static int
1080 TRANS(SocketUNIXResetListener) (XtransConnInfo ciptr)
1081
1082 {
1083
1084
1085
1086
1087 struct sockaddr_un *unsock = (struct sockaddr_un *) ciptr->addr;
1088 struct stat statb;
1089 int status = TRANS_RESET_NOOP;
1090 unsigned int mode;
1091 int abstract = 0;
1092 #ifdef HAVE_ABSTRACT_SOCKETS
1093 abstract = ciptr->transptr->flags & TRANS_ABSTRACT;
1094 #endif
1095
1096 prmsg (3, "SocketUNIXResetListener(%p,%d)\n", ciptr, ciptr->fd);
1097
1098 if (!abstract && (
1099 stat (unsock->sun_path, &statb) == -1 ||
1100 ((statb.st_mode & S_IFMT) !=
1101 #if !defined(S_IFSOCK)
1102 S_IFIFO
1103 #else
1104 S_IFSOCK
1105 #endif
1106 )))
1107 {
1108 int oldUmask = umask (0);
1109
1110 #ifdef UNIX_DIR
1111 #ifdef HAS_STICKY_DIR_BIT
1112 mode = 01777;
1113 #else
1114 mode = 0777;
1115 #endif
1116 if (trans_mkdir(UNIX_DIR, mode) == -1) {
1117 prmsg (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n",
1118 UNIX_DIR, errno);
1119 (void) umask (oldUmask);
1120 return TRANS_RESET_FAILURE;
1121 }
1122 #endif
1123
1124 close (ciptr->fd);
1125 unlink (unsock->sun_path);
1126
1127 if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
1128 {
1129 TRANS(FreeConnInfo) (ciptr);
1130 (void) umask (oldUmask);
1131 return TRANS_RESET_FAILURE;
1132 }
1133
1134 if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0)
1135 {
1136 close (ciptr->fd);
1137 TRANS(FreeConnInfo) (ciptr);
1138 return TRANS_RESET_FAILURE;
1139 }
1140
1141 if (listen (ciptr->fd, BACKLOG) < 0)
1142 {
1143 close (ciptr->fd);
1144 TRANS(FreeConnInfo) (ciptr);
1145 (void) umask (oldUmask);
1146 return TRANS_RESET_FAILURE;
1147 }
1148
1149 umask (oldUmask);
1150
1151 status = TRANS_RESET_NEW_FD;
1152 }
1153
1154 return status;
1155 }
1156
1157 #endif
1158
1159
1160 #ifdef TCPCONN
1161
1162 static XtransConnInfo
1163 TRANS(SocketINETAccept) (XtransConnInfo ciptr, int *status)
1164
1165 {
1166 XtransConnInfo newciptr;
1167 struct sockaddr_in sockname;
1168 SOCKLEN_T namelen = sizeof(sockname);
1169
1170 prmsg (2, "SocketINETAccept(%p,%d)\n", ciptr, ciptr->fd);
1171
1172 if ((newciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL)
1173 {
1174 prmsg (1, "SocketINETAccept: malloc failed\n");
1175 *status = TRANS_ACCEPT_BAD_MALLOC;
1176 return NULL;
1177 }
1178
1179 if ((newciptr->fd = accept (ciptr->fd,
1180 (struct sockaddr *) &sockname, (void *)&namelen)) < 0)
1181 {
1182 #ifdef WIN32
1183 errno = WSAGetLastError();
1184 #endif
1185 prmsg (1, "SocketINETAccept: accept() failed\n");
1186 free (newciptr);
1187 *status = TRANS_ACCEPT_FAILED;
1188 return NULL;
1189 }
1190
1191 #ifdef TCP_NODELAY
1192 {
1193
1194
1195
1196
1197 int tmp = 1;
1198 setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY,
1199 (char *) &tmp, sizeof (int));
1200 }
1201 #endif
1202
1203
1204
1205
1206
1207
1208 if (TRANS(SocketINETGetAddr) (newciptr) < 0)
1209 {
1210 prmsg (1,
1211 "SocketINETAccept: ...SocketINETGetAddr() failed:\n");
1212 close (newciptr->fd);
1213 free (newciptr);
1214 *status = TRANS_ACCEPT_MISC_ERROR;
1215 return NULL;
1216 }
1217
1218 if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0)
1219 {
1220 prmsg (1,
1221 "SocketINETAccept: ...SocketINETGetPeerAddr() failed:\n");
1222 close (newciptr->fd);
1223 if (newciptr->addr) free (newciptr->addr);
1224 free (newciptr);
1225 *status = TRANS_ACCEPT_MISC_ERROR;
1226 return NULL;
1227 }
1228
1229 *status = 0;
1230
1231 return newciptr;
1232 }
1233
1234 #endif
1235
1236
1237 #ifdef UNIXCONN
1238 static XtransConnInfo
1239 TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status)
1240
1241 {
1242 XtransConnInfo newciptr;
1243 struct sockaddr_un sockname;
1244 SOCKLEN_T namelen = sizeof sockname;
1245
1246 prmsg (2, "SocketUNIXAccept(%p,%d)\n", ciptr, ciptr->fd);
1247
1248 if ((newciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL)
1249 {
1250 prmsg (1, "SocketUNIXAccept: malloc() failed\n");
1251 *status = TRANS_ACCEPT_BAD_MALLOC;
1252 return NULL;
1253 }
1254
1255 if ((newciptr->fd = accept (ciptr->fd,
1256 (struct sockaddr *) &sockname, (void *)&namelen)) < 0)
1257 {
1258 prmsg (1, "SocketUNIXAccept: accept() failed\n");
1259 free (newciptr);
1260 *status = TRANS_ACCEPT_FAILED;
1261 return NULL;
1262 }
1263
1264 ciptr->addrlen = namelen;
1265
1266
1267
1268
1269
1270 if ((newciptr->addr = malloc (ciptr->addrlen)) == NULL)
1271 {
1272 prmsg (1,
1273 "SocketUNIXAccept: Can't allocate space for the addr\n");
1274 close (newciptr->fd);
1275 free (newciptr);
1276 *status = TRANS_ACCEPT_BAD_MALLOC;
1277 return NULL;
1278 }
1279
1280
1281
1282
1283
1284
1285 newciptr->addrlen = ciptr->addrlen;
1286 memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen);
1287
1288 if ((newciptr->peeraddr = malloc (ciptr->addrlen)) == NULL)
1289 {
1290 prmsg (1,
1291 "SocketUNIXAccept: Can't allocate space for the addr\n");
1292 close (newciptr->fd);
1293 if (newciptr->addr) free (newciptr->addr);
1294 free (newciptr);
1295 *status = TRANS_ACCEPT_BAD_MALLOC;
1296 return NULL;
1297 }
1298
1299 newciptr->peeraddrlen = ciptr->addrlen;
1300 memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen);
1301
1302 newciptr->family = AF_UNIX;
1303
1304 *status = 0;
1305
1306 return newciptr;
1307 }
1308
1309 #endif
1310
1311 #endif
1312
1313
1314 #ifdef TRANS_CLIENT
1315
1316 #ifdef TCPCONN
1317
1318 #if defined(IPv6) && defined(AF_INET6)
1319 struct addrlist {
1320 struct addrinfo * addr;
1321 struct addrinfo * firstaddr;
1322 char port[PORTBUFSIZE];
1323 char host[MAXHOSTNAMELEN];
1324 };
1325 static struct addrlist *addrlist = NULL;
1326 #endif
1327
1328
1329 static int
1330 TRANS(SocketINETConnect) (XtransConnInfo ciptr,
1331 const char *host, const char *port)
1332
1333 {
1334 struct sockaddr * socketaddr = NULL;
1335 int socketaddrlen = 0;
1336 int res;
1337 #if defined(IPv6) && defined(AF_INET6)
1338 struct addrinfo hints;
1339 char ntopbuf[INET6_ADDRSTRLEN];
1340 int resetonce = 0;
1341 #else
1342 struct sockaddr_in sockname;
1343 struct hostent *hostp;
1344 struct servent *servp;
1345 unsigned long tmpaddr;
1346 #endif
1347 #ifdef XTHREADS_NEEDS_BYNAMEPARAMS
1348 _Xgethostbynameparams hparams;
1349 _Xgetservbynameparams sparams;
1350 #endif
1351 #ifdef X11_t
1352 char portbuf[PORTBUFSIZE];
1353 #endif
1354
1355 char hostnamebuf[256];
1356
1357 prmsg (2,"SocketINETConnect(%d,%s,%s)\n", ciptr->fd, host, port);
1358
1359 if (!host)
1360 {
1361 hostnamebuf[0] = '\0';
1362 (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
1363 host = hostnamebuf;
1364 }
1365
1366 #ifdef X11_t
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376 if (is_numeric (port))
1377 {
1378 long tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
1379 snprintf (portbuf, sizeof(portbuf), "%lu", tmpport);
1380 port = portbuf;
1381 }
1382 #endif
1383
1384 #if defined(IPv6) && defined(AF_INET6)
1385 {
1386 if (addrlist != NULL) {
1387 if (strcmp(host,addrlist->host) || strcmp(port,addrlist->port)) {
1388 if (addrlist->firstaddr)
1389 freeaddrinfo(addrlist->firstaddr);
1390 addrlist->firstaddr = NULL;
1391 }
1392 } else {
1393 addrlist = malloc(sizeof(struct addrlist));
1394 if (addrlist == NULL) {
1395 prmsg (1, "SocketINETConnect() can't allocate memory "
1396 "for addrlist: %s\n", strerror(errno));
1397 return TRANS_CONNECT_FAILED;
1398 }
1399 addrlist->firstaddr = NULL;
1400 }
1401
1402 if (addrlist->firstaddr == NULL) {
1403 strncpy(addrlist->port, port, sizeof(addrlist->port));
1404 addrlist->port[sizeof(addrlist->port) - 1] = '\0';
1405 strncpy(addrlist->host, host, sizeof(addrlist->host));
1406 addrlist->host[sizeof(addrlist->host) - 1] = '\0';
1407
1408 bzero(&hints,sizeof(hints));
1409 hints.ai_socktype = Sockettrans2devtab[ciptr->index].devcotsname;
1410
1411 res = getaddrinfo(host,port,&hints,&addrlist->firstaddr);
1412 if (res != 0) {
1413 prmsg (1, "SocketINETConnect() can't get address "
1414 "for %s:%s: %s\n", host, port, gai_strerror(res));
1415 ESET(EINVAL);
1416 return TRANS_CONNECT_FAILED;
1417 }
1418 for (res = 0, addrlist->addr = addrlist->firstaddr;
1419 addrlist->addr ; res++) {
1420 addrlist->addr = addrlist->addr->ai_next;
1421 }
1422 prmsg(4,"Got New Address list with %d addresses\n", res);
1423 res = 0;
1424 addrlist->addr = NULL;
1425 }
1426
1427 while (socketaddr == NULL) {
1428 if (addrlist->addr == NULL) {
1429 if (resetonce) {
1430
1431 prmsg (1, "SocketINETConnect() no usable address "
1432 "for %s:%s\n", host, port);
1433 return TRANS_CONNECT_FAILED;
1434 } else {
1435
1436 resetonce = 1;
1437 addrlist->addr = addrlist->firstaddr;
1438 }
1439 }
1440
1441 socketaddr = addrlist->addr->ai_addr;
1442 socketaddrlen = addrlist->addr->ai_addrlen;
1443
1444 if (addrlist->addr->ai_family == AF_INET) {
1445 struct sockaddr_in *sin = (struct sockaddr_in *) socketaddr;
1446
1447 prmsg (4,"SocketINETConnect() sockname.sin_addr = %s\n",
1448 inet_ntop(addrlist->addr->ai_family,&sin->sin_addr,
1449 ntopbuf,sizeof(ntopbuf)));
1450
1451 prmsg (4,"SocketINETConnect() sockname.sin_port = %d\n",
1452 ntohs(sin->sin_port));
1453
1454 if (Sockettrans2devtab[ciptr->index].family == AF_INET6) {
1455 if (strcmp(Sockettrans2devtab[ciptr->index].transname,
1456 "tcp") == 0) {
1457 XtransConnInfo newciptr;
1458
1459
1460
1461
1462
1463
1464
1465 TRANS(SocketINETClose)(ciptr);
1466 newciptr = TRANS(SocketOpenCOTSClientBase)(
1467 "tcp", "tcp", host, port, ciptr->index);
1468 if (newciptr)
1469 ciptr->fd = newciptr->fd;
1470 if (!newciptr ||
1471 Sockettrans2devtab[newciptr->index].family !=
1472 AF_INET) {
1473 socketaddr = NULL;
1474 prmsg (4,"SocketINETConnect() Cannot get IPv4 "
1475 " socketfor IPv4 address\n");
1476 }
1477 if (newciptr)
1478 free(newciptr);
1479 } else {
1480 socketaddr = NULL;
1481 prmsg (4,"SocketINETConnect Skipping IPv4 address\n");
1482 }
1483 }
1484 } else if (addrlist->addr->ai_family == AF_INET6) {
1485 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) socketaddr;
1486
1487 prmsg (4,"SocketINETConnect() sockname.sin6_addr = %s\n",
1488 inet_ntop(addrlist->addr->ai_family,
1489 &sin6->sin6_addr,ntopbuf,sizeof(ntopbuf)));
1490 prmsg (4,"SocketINETConnect() sockname.sin6_port = %d\n",
1491 ntohs(sin6->sin6_port));
1492
1493 if (Sockettrans2devtab[ciptr->index].family == AF_INET) {
1494 if (strcmp(Sockettrans2devtab[ciptr->index].transname,
1495 "tcp") == 0) {
1496 XtransConnInfo newciptr;
1497
1498
1499
1500
1501 TRANS(SocketINETClose)(ciptr);
1502 newciptr = TRANS(SocketOpenCOTSClientBase)(
1503 "tcp", "tcp", host, port, -1);
1504 if (newciptr)
1505 ciptr->fd = newciptr->fd;
1506 if (!newciptr ||
1507 Sockettrans2devtab[newciptr->index].family !=
1508 AF_INET6) {
1509 socketaddr = NULL;
1510 prmsg (4,"SocketINETConnect() Cannot get IPv6 "
1511 "socket for IPv6 address\n");
1512 }
1513 if (newciptr)
1514 free(newciptr);
1515 }
1516 else
1517 {
1518 socketaddr = NULL;
1519 prmsg (4,"SocketINETConnect() Skipping IPv6 address\n");
1520 }
1521 }
1522 } else {
1523 socketaddr = NULL;
1524 }
1525 if (socketaddr == NULL) {
1526 addrlist->addr = addrlist->addr->ai_next;
1527 }
1528 }
1529 }
1530 #else
1531 {
1532
1533
1534
1535
1536 #ifdef BSD44SOCKETS
1537 sockname.sin_len = sizeof (struct sockaddr_in);
1538 #endif
1539 sockname.sin_family = AF_INET;
1540
1541
1542
1543
1544
1545 #ifndef INADDR_NONE
1546 #define INADDR_NONE ((in_addr_t) 0xffffffff)
1547 #endif
1548
1549
1550
1551 if (isascii (host[0]) && isdigit (host[0])) {
1552 tmpaddr = inet_addr (host);
1553 } else {
1554 tmpaddr = INADDR_NONE;
1555 }
1556
1557 prmsg (4,"SocketINETConnect() inet_addr(%s) = %lx\n", host, tmpaddr);
1558
1559 if (tmpaddr == INADDR_NONE) {
1560 if ((hostp = _XGethostbyname(host,hparams)) == NULL) {
1561 prmsg (1,"SocketINETConnect: Can't get address for %s\n",
1562 host);
1563 ESET(EINVAL);
1564 return TRANS_CONNECT_FAILED;
1565 }
1566 if (hostp->h_addrtype != AF_INET) {
1567 prmsg (1,"SocketINETConnect: not INET host%s\n", host);
1568 ESET(EPROTOTYPE);
1569 return TRANS_CONNECT_FAILED;
1570 }
1571
1572 memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr,
1573 sizeof (sockname.sin_addr));
1574
1575 } else {
1576 sockname.sin_addr.s_addr = tmpaddr;
1577 }
1578
1579
1580
1581
1582
1583
1584
1585 if (!is_numeric (port)) {
1586 if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) {
1587 prmsg (1,"SocketINETConnect: can't get service for %s\n",
1588 port);
1589 return TRANS_CONNECT_FAILED;
1590 }
1591 sockname.sin_port = htons (servp->s_port);
1592 } else {
1593 long tmpport = strtol (port, (char**)NULL, 10);
1594 if (tmpport < 1024 || tmpport > USHRT_MAX)
1595 return TRANS_CONNECT_FAILED;
1596 sockname.sin_port = htons (((unsigned short) tmpport));
1597 }
1598
1599 prmsg (4,"SocketINETConnect: sockname.sin_port = %d\n",
1600 ntohs(sockname.sin_port));
1601 socketaddr = (struct sockaddr *) &sockname;
1602 socketaddrlen = sizeof(sockname);
1603 }
1604 #endif
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617 {
1618 int tmp = 1;
1619 setsockopt (ciptr->fd, SOL_SOCKET, SO_KEEPALIVE,
1620 (char *) &tmp, sizeof (int));
1621 }
1622
1623
1624
1625
1626
1627 if (connect (ciptr->fd, socketaddr, socketaddrlen ) < 0)
1628 {
1629 #ifdef WIN32
1630 int olderrno = WSAGetLastError();
1631 #else
1632 int olderrno = errno;
1633 #endif
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653 if (olderrno == ECONNREFUSED || olderrno == EINTR
1654 #if defined(IPv6) && defined(AF_INET6)
1655 || (((addrlist->addr->ai_next != NULL) ||
1656 (addrlist->addr != addrlist->firstaddr)) &&
1657 (olderrno == ENETUNREACH || olderrno == EAFNOSUPPORT ||
1658 olderrno == EADDRNOTAVAIL || olderrno == ETIMEDOUT
1659 #if defined(EHOSTDOWN)
1660 || olderrno == EHOSTDOWN
1661 #endif
1662 ))
1663 #endif
1664 )
1665 res = TRANS_TRY_CONNECT_AGAIN;
1666 else if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS)
1667 res = TRANS_IN_PROGRESS;
1668 else
1669 {
1670 prmsg (2,"SocketINETConnect: Can't connect: errno = %d\n",
1671 olderrno);
1672
1673 res = TRANS_CONNECT_FAILED;
1674 }
1675 } else {
1676 res = 0;
1677
1678
1679
1680
1681
1682
1683 if (TRANS(SocketINETGetAddr) (ciptr) < 0)
1684 {
1685 prmsg (1,
1686 "SocketINETConnect: ...SocketINETGetAddr() failed:\n");
1687 res = TRANS_CONNECT_FAILED;
1688 }
1689
1690 else if (TRANS(SocketINETGetPeerAddr) (ciptr) < 0)
1691 {
1692 prmsg (1,
1693 "SocketINETConnect: ...SocketINETGetPeerAddr() failed:\n");
1694 res = TRANS_CONNECT_FAILED;
1695 }
1696 }
1697
1698 #if defined(IPv6) && defined(AF_INET6)
1699 if (res != 0) {
1700 addrlist->addr = addrlist->addr->ai_next;
1701 }
1702 #endif
1703
1704 return res;
1705 }
1706
1707 #endif
1708
1709
1710
1711 #ifdef UNIXCONN
1712
1713
1714
1715
1716
1717 static int
1718 UnixHostReallyLocal (const char *host)
1719
1720 {
1721 char hostnamebuf[256];
1722
1723 TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
1724
1725 if (strcmp (hostnamebuf, host) == 0)
1726 {
1727 return (1);
1728 } else {
1729 #if defined(IPv6) && defined(AF_INET6)
1730 struct addrinfo *localhostaddr;
1731 struct addrinfo *otherhostaddr;
1732 struct addrinfo *i, *j;
1733 int equiv = 0;
1734
1735 if (getaddrinfo(hostnamebuf, NULL, NULL, &localhostaddr) != 0)
1736 return 0;
1737 if (getaddrinfo(host, NULL, NULL, &otherhostaddr) != 0) {
1738 freeaddrinfo(localhostaddr);
1739 return 0;
1740 }
1741
1742 for (i = localhostaddr; i != NULL && equiv == 0; i = i->ai_next) {
1743 for (j = otherhostaddr; j != NULL && equiv == 0; j = j->ai_next) {
1744 if (i->ai_family == j->ai_family) {
1745 if (i->ai_family == AF_INET) {
1746 struct sockaddr_in *sinA
1747 = (struct sockaddr_in *) i->ai_addr;
1748 struct sockaddr_in *sinB
1749 = (struct sockaddr_in *) j->ai_addr;
1750 struct in_addr *A = &sinA->sin_addr;
1751 struct in_addr *B = &sinB->sin_addr;
1752
1753 if (memcmp(A,B,sizeof(struct in_addr)) == 0) {
1754 equiv = 1;
1755 }
1756 } else if (i->ai_family == AF_INET6) {
1757 struct sockaddr_in6 *sinA
1758 = (struct sockaddr_in6 *) i->ai_addr;
1759 struct sockaddr_in6 *sinB
1760 = (struct sockaddr_in6 *) j->ai_addr;
1761 struct in6_addr *A = &sinA->sin6_addr;
1762 struct in6_addr *B = &sinB->sin6_addr;
1763
1764 if (memcmp(A,B,sizeof(struct in6_addr)) == 0) {
1765 equiv = 1;
1766 }
1767 }
1768 }
1769 }
1770 }
1771
1772 freeaddrinfo(localhostaddr);
1773 freeaddrinfo(otherhostaddr);
1774 return equiv;
1775 #else
1776
1777
1778
1779
1780
1781
1782
1783 char specified_local_addr_list[10][4];
1784 int scount, equiv, i, j;
1785 #ifdef XTHREADS_NEEDS_BYNAMEPARAMS
1786 _Xgethostbynameparams hparams;
1787 #endif
1788 struct hostent *hostp;
1789
1790 if ((hostp = _XGethostbyname (host,hparams)) == NULL)
1791 return (0);
1792
1793 scount = 0;
1794 while (hostp->h_addr_list[scount] && scount <= 8)
1795 {
1796
1797
1798
1799
1800
1801 specified_local_addr_list[scount][0] =
1802 hostp->h_addr_list[scount][0];
1803 specified_local_addr_list[scount][1] =
1804 hostp->h_addr_list[scount][1];
1805 specified_local_addr_list[scount][2] =
1806 hostp->h_addr_list[scount][2];
1807 specified_local_addr_list[scount][3] =
1808 hostp->h_addr_list[scount][3];
1809 scount++;
1810 }
1811 if ((hostp = _XGethostbyname (hostnamebuf,hparams)) == NULL)
1812 return (0);
1813
1814 equiv = 0;
1815 i = 0;
1816
1817 while (i < scount && !equiv)
1818 {
1819 j = 0;
1820
1821 while (hostp->h_addr_list[j])
1822 {
1823 if ((specified_local_addr_list[i][0] ==
1824 hostp->h_addr_list[j][0]) &&
1825 (specified_local_addr_list[i][1] ==
1826 hostp->h_addr_list[j][1]) &&
1827 (specified_local_addr_list[i][2] ==
1828 hostp->h_addr_list[j][2]) &&
1829 (specified_local_addr_list[i][3] ==
1830 hostp->h_addr_list[j][3]))
1831 {
1832
1833
1834 equiv = 1;
1835 break;
1836 }
1837
1838 j++;
1839 }
1840
1841 i++;
1842 }
1843 return (equiv);
1844 #endif
1845 }
1846 }
1847
1848 static int
1849 TRANS(SocketUNIXConnect) (XtransConnInfo ciptr,
1850 const char *host, const char *port)
1851
1852 {
1853 struct sockaddr_un sockname;
1854 SOCKLEN_T namelen;
1855
1856 prmsg (2,"SocketUNIXConnect(%d,%s,%s)\n", ciptr->fd, host, port);
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866 if (host && *host && host[0]!='/' && strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host))
1867 {
1868 prmsg (1,
1869 "SocketUNIXConnect: Cannot connect to non-local host %s\n",
1870 host);
1871 return TRANS_CONNECT_FAILED;
1872 }
1873
1874
1875
1876
1877
1878
1879 if (!port || !*port)
1880 {
1881 prmsg (1,"SocketUNIXConnect: Missing port specification\n");
1882 return TRANS_CONNECT_FAILED;
1883 }
1884
1885
1886
1887
1888
1889 sockname.sun_family = AF_UNIX;
1890
1891 if (set_sun_path(port, UNIX_PATH, sockname.sun_path, 0) != 0) {
1892 prmsg (1, "SocketUNIXConnect: path too long\n");
1893 return TRANS_CONNECT_FAILED;
1894 }
1895
1896 #if defined(BSD44SOCKETS)
1897 sockname.sun_len = strlen (sockname.sun_path);
1898 #endif
1899
1900 #if defined(BSD44SOCKETS) || defined(SUN_LEN)
1901 namelen = SUN_LEN (&sockname);
1902 #else
1903 namelen = strlen (sockname.sun_path) + offsetof(struct sockaddr_un, sun_path);
1904 #endif
1905
1906
1907
1908
1909
1910
1911 if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0)
1912 {
1913 int olderrno = errno;
1914 int connected = 0;
1915
1916 if (!connected)
1917 {
1918 errno = olderrno;
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936 if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS)
1937 return TRANS_IN_PROGRESS;
1938 else if (olderrno == EINTR)
1939 return TRANS_TRY_CONNECT_AGAIN;
1940 else {
1941 prmsg (2,"SocketUNIXConnect: Can't connect: errno = %d\n",
1942 EGET());
1943
1944 return TRANS_CONNECT_FAILED;
1945 }
1946 }
1947 }
1948
1949
1950
1951
1952
1953
1954 if ((ciptr->addr = malloc(namelen)) == NULL ||
1955 (ciptr->peeraddr = malloc(namelen)) == NULL)
1956 {
1957 prmsg (1,
1958 "SocketUNIXCreateListener: Can't allocate space for the addr\n");
1959 return TRANS_CONNECT_FAILED;
1960 }
1961
1962 ciptr->family = AF_UNIX;
1963 ciptr->addrlen = namelen;
1964 ciptr->peeraddrlen = namelen;
1965 memcpy (ciptr->addr, &sockname, ciptr->addrlen);
1966 memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
1967
1968 return 0;
1969 }
1970
1971 #endif
1972
1973 #endif
1974
1975
1976 static int
1977 TRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
1978
1979 {
1980 prmsg (2,"SocketBytesReadable(%p,%d,%p)\n",
1981 ciptr, ciptr->fd, pend);
1982 #ifdef WIN32
1983 {
1984 int ret = ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
1985 if (ret == SOCKET_ERROR) errno = WSAGetLastError();
1986 return ret;
1987 }
1988 #else
1989 return ioctl (ciptr->fd, FIONREAD, (char *) pend);
1990 #endif
1991 }
1992
1993 #if XTRANS_SEND_FDS
1994
1995 static void
1996 appendFd(struct _XtransConnFd **prev, int fd, int do_close)
1997 {
1998 struct _XtransConnFd *cf, *new;
1999
2000 new = malloc (sizeof (struct _XtransConnFd));
2001 if (!new) {
2002
2003 close(fd);
2004 return;
2005 }
2006 new->next = 0;
2007 new->fd = fd;
2008 new->do_close = do_close;
2009
2010 for (; (cf = *prev); prev = &(cf->next));
2011 *prev = new;
2012 }
2013
2014 static int
2015 removeFd(struct _XtransConnFd **prev)
2016 {
2017 struct _XtransConnFd *cf;
2018 int fd;
2019
2020 if ((cf = *prev)) {
2021 *prev = cf->next;
2022 fd = cf->fd;
2023 free(cf);
2024 } else
2025 fd = -1;
2026 return fd;
2027 }
2028
2029 static void
2030 discardFd(struct _XtransConnFd **prev, struct _XtransConnFd *upto, int do_close)
2031 {
2032 struct _XtransConnFd *cf, *next;
2033
2034 for (cf = *prev; cf != upto; cf = next) {
2035 next = cf->next;
2036 if (do_close || cf->do_close)
2037 close(cf->fd);
2038 free(cf);
2039 }
2040 *prev = upto;
2041 }
2042
2043 static void
2044 cleanupFds(XtransConnInfo ciptr)
2045 {
2046
2047 discardFd(&ciptr->send_fds, NULL, 0);
2048
2049 discardFd(&ciptr->recv_fds, NULL, 1);
2050 }
2051
2052 static int
2053 nFd(struct _XtransConnFd **prev)
2054 {
2055 struct _XtransConnFd *cf;
2056 int n = 0;
2057
2058 for (cf = *prev; cf; cf = cf->next)
2059 n++;
2060 return n;
2061 }
2062
2063 static int
2064 TRANS(SocketRecvFd) (XtransConnInfo ciptr)
2065 {
2066 prmsg (2, "SocketRecvFd(%d)\n", ciptr->fd);
2067 return removeFd(&ciptr->recv_fds);
2068 }
2069
2070 static int
2071 TRANS(SocketSendFd) (XtransConnInfo ciptr, int fd, int do_close)
2072 {
2073 appendFd(&ciptr->send_fds, fd, do_close);
2074 return 0;
2075 }
2076
2077 static int
2078 TRANS(SocketRecvFdInvalid)(XtransConnInfo ciptr)
2079 {
2080 errno = EINVAL;
2081 return -1;
2082 }
2083
2084 static int
2085 TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
2086 {
2087 errno = EINVAL;
2088 return -1;
2089 }
2090
2091 #define MAX_FDS 128
2092
2093 union fd_pass {
2094 struct cmsghdr cmsghdr;
2095 char buf[CMSG_SPACE(MAX_FDS * sizeof(int))];
2096 };
2097
2098 #endif
2099
2100 static int
2101 TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
2102
2103 {
2104 prmsg (2,"SocketRead(%d,%p,%d)\n", ciptr->fd, buf, size);
2105
2106 #if defined(WIN32)
2107 {
2108 int ret = recv ((SOCKET)ciptr->fd, buf, size, 0);
2109 #ifdef WIN32
2110 if (ret == SOCKET_ERROR) errno = WSAGetLastError();
2111 #endif
2112 return ret;
2113 }
2114 #else
2115 #if XTRANS_SEND_FDS
2116 {
2117 struct iovec iov = {
2118 .iov_base = buf,
2119 .iov_len = size
2120 };
2121 union fd_pass cmsgbuf;
2122 struct msghdr msg = {
2123 .msg_name = NULL,
2124 .msg_namelen = 0,
2125 .msg_iov = &iov,
2126 .msg_iovlen = 1,
2127 .msg_control = cmsgbuf.buf,
2128 .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
2129 };
2130
2131 size = recvmsg(ciptr->fd, &msg, 0);
2132 if (size >= 0) {
2133 struct cmsghdr *hdr;
2134
2135 for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
2136 if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
2137 int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
2138 int i;
2139 int *fd = (int *) CMSG_DATA(hdr);
2140
2141 for (i = 0; i < nfd; i++)
2142 appendFd(&ciptr->recv_fds, fd[i], 0);
2143 }
2144 }
2145 }
2146 return size;
2147 }
2148 #else
2149 return read(ciptr->fd, buf, size);
2150 #endif
2151 #endif
2152 }
2153
2154 static int
2155 TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size)
2156
2157 {
2158 prmsg (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size);
2159
2160 #if XTRANS_SEND_FDS
2161 {
2162 union fd_pass cmsgbuf;
2163 struct msghdr msg = {
2164 .msg_name = NULL,
2165 .msg_namelen = 0,
2166 .msg_iov = buf,
2167 .msg_iovlen = size,
2168 .msg_control = cmsgbuf.buf,
2169 .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
2170 };
2171
2172 size = recvmsg(ciptr->fd, &msg, 0);
2173 if (size >= 0) {
2174 struct cmsghdr *hdr;
2175
2176 for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
2177 if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
2178 int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
2179 int i;
2180 int *fd = (int *) CMSG_DATA(hdr);
2181
2182 for (i = 0; i < nfd; i++)
2183 appendFd(&ciptr->recv_fds, fd[i], 0);
2184 }
2185 }
2186 }
2187 return size;
2188 }
2189 #else
2190 return READV (ciptr, buf, size);
2191 #endif
2192 }
2193
2194
2195 static int
2196 TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
2197
2198 {
2199 prmsg (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size);
2200
2201 #if XTRANS_SEND_FDS
2202 if (ciptr->send_fds)
2203 {
2204 union fd_pass cmsgbuf;
2205 int nfd = nFd(&ciptr->send_fds);
2206 struct _XtransConnFd *cf = ciptr->send_fds;
2207 struct msghdr msg = {
2208 .msg_name = NULL,
2209 .msg_namelen = 0,
2210 .msg_iov = buf,
2211 .msg_iovlen = size,
2212 .msg_control = cmsgbuf.buf,
2213 .msg_controllen = CMSG_LEN(nfd * sizeof(int))
2214 };
2215 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
2216 int i;
2217 int *fds;
2218
2219 hdr->cmsg_len = msg.msg_controllen;
2220 hdr->cmsg_level = SOL_SOCKET;
2221 hdr->cmsg_type = SCM_RIGHTS;
2222
2223 fds = (int *) CMSG_DATA(hdr);
2224
2225 for (i = 0; i < nfd; i++) {
2226 fds[i] = cf->fd;
2227 cf = cf->next;
2228 }
2229
2230 i = sendmsg(ciptr->fd, &msg, 0);
2231 if (i > 0)
2232 discardFd(&ciptr->send_fds, cf, 0);
2233 return i;
2234 }
2235 #endif
2236 return WRITEV (ciptr, buf, size);
2237 }
2238
2239
2240 static int
2241 TRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size)
2242
2243 {
2244 prmsg (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size);
2245
2246 #if defined(WIN32)
2247 {
2248 int ret = send ((SOCKET)ciptr->fd, buf, size, 0);
2249 #ifdef WIN32
2250 if (ret == SOCKET_ERROR) errno = WSAGetLastError();
2251 #endif
2252 return ret;
2253 }
2254 #else
2255 #if XTRANS_SEND_FDS
2256 if (ciptr->send_fds)
2257 {
2258 struct iovec iov;
2259
2260 iov.iov_base = buf;
2261 iov.iov_len = size;
2262 return TRANS(SocketWritev)(ciptr, &iov, 1);
2263 }
2264 #endif
2265 return write (ciptr->fd, buf, size);
2266 #endif
2267 }
2268
2269 static int
2270 TRANS(SocketDisconnect) (XtransConnInfo ciptr)
2271
2272 {
2273 prmsg (2,"SocketDisconnect(%p,%d)\n", ciptr, ciptr->fd);
2274
2275 #ifdef WIN32
2276 {
2277 int ret = shutdown (ciptr->fd, 2);
2278 if (ret == SOCKET_ERROR) errno = WSAGetLastError();
2279 return ret;
2280 }
2281 #else
2282 return shutdown (ciptr->fd, 2);
2283 #endif
2284 }
2285
2286
2287 #ifdef TCPCONN
2288 static int
2289 TRANS(SocketINETClose) (XtransConnInfo ciptr)
2290
2291 {
2292 prmsg (2,"SocketINETClose(%p,%d)\n", ciptr, ciptr->fd);
2293
2294 #ifdef WIN32
2295 {
2296 int ret = close (ciptr->fd);
2297 if (ret == SOCKET_ERROR) errno = WSAGetLastError();
2298 return ret;
2299 }
2300 #else
2301 return close (ciptr->fd);
2302 #endif
2303 }
2304
2305 #endif
2306
2307
2308 #ifdef UNIXCONN
2309 static int
2310 TRANS(SocketUNIXClose) (XtransConnInfo ciptr)
2311 {
2312
2313
2314
2315
2316
2317 struct sockaddr_un *sockname = (struct sockaddr_un *) ciptr->addr;
2318 int ret;
2319
2320 prmsg (2,"SocketUNIXClose(%p,%d)\n", ciptr, ciptr->fd);
2321
2322 #if XTRANS_SEND_FDS
2323 cleanupFds(ciptr);
2324 #endif
2325 ret = close(ciptr->fd);
2326
2327 if (ciptr->flags
2328 && sockname
2329 && sockname->sun_family == AF_UNIX
2330 && sockname->sun_path[0])
2331 {
2332 if (!(ciptr->flags & TRANS_NOUNLINK
2333 || ciptr->transptr->flags & TRANS_ABSTRACT))
2334 unlink (sockname->sun_path);
2335 }
2336
2337 return ret;
2338 }
2339
2340 static int
2341 TRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr)
2342
2343 {
2344
2345
2346
2347
2348 int ret;
2349
2350 prmsg (2,"SocketUNIXCloseForCloning(%p,%d)\n",
2351 ciptr, ciptr->fd);
2352
2353 #if XTRANS_SEND_FDS
2354 cleanupFds(ciptr);
2355 #endif
2356 ret = close(ciptr->fd);
2357
2358 return ret;
2359 }
2360
2361 #endif
2362
2363
2364 #ifdef TCPCONN
2365 # ifdef TRANS_SERVER
2366 static const char* tcp_nolisten[] = {
2367 "inet",
2368 #if defined(IPv6) && defined(AF_INET6)
2369 "inet6",
2370 #endif
2371 NULL
2372 };
2373 # endif
2374
2375 Xtransport TRANS(SocketTCPFuncs) = {
2376
2377 "tcp",
2378 TRANS_ALIAS,
2379 #ifdef TRANS_CLIENT
2380 TRANS(SocketOpenCOTSClient),
2381 #endif
2382 #ifdef TRANS_SERVER
2383 tcp_nolisten,
2384 TRANS(SocketOpenCOTSServer),
2385 #endif
2386 #ifdef TRANS_REOPEN
2387 TRANS(SocketReopenCOTSServer),
2388 #endif
2389 TRANS(SocketSetOption),
2390 #ifdef TRANS_SERVER
2391 TRANS(SocketINETCreateListener),
2392 NULL,
2393 TRANS(SocketINETAccept),
2394 #endif
2395 #ifdef TRANS_CLIENT
2396 TRANS(SocketINETConnect),
2397 #endif
2398 TRANS(SocketBytesReadable),
2399 TRANS(SocketRead),
2400 TRANS(SocketWrite),
2401 TRANS(SocketReadv),
2402 TRANS(SocketWritev),
2403 #if XTRANS_SEND_FDS
2404 TRANS(SocketSendFdInvalid),
2405 TRANS(SocketRecvFdInvalid),
2406 #endif
2407 TRANS(SocketDisconnect),
2408 TRANS(SocketINETClose),
2409 TRANS(SocketINETClose),
2410 };
2411
2412 Xtransport TRANS(SocketINETFuncs) = {
2413
2414 "inet",
2415 0,
2416 #ifdef TRANS_CLIENT
2417 TRANS(SocketOpenCOTSClient),
2418 #endif
2419 #ifdef TRANS_SERVER
2420 NULL,
2421 TRANS(SocketOpenCOTSServer),
2422 #endif
2423 #ifdef TRANS_REOPEN
2424 TRANS(SocketReopenCOTSServer),
2425 #endif
2426 TRANS(SocketSetOption),
2427 #ifdef TRANS_SERVER
2428 TRANS(SocketINETCreateListener),
2429 NULL,
2430 TRANS(SocketINETAccept),
2431 #endif
2432 #ifdef TRANS_CLIENT
2433 TRANS(SocketINETConnect),
2434 #endif
2435 TRANS(SocketBytesReadable),
2436 TRANS(SocketRead),
2437 TRANS(SocketWrite),
2438 TRANS(SocketReadv),
2439 TRANS(SocketWritev),
2440 #if XTRANS_SEND_FDS
2441 TRANS(SocketSendFdInvalid),
2442 TRANS(SocketRecvFdInvalid),
2443 #endif
2444 TRANS(SocketDisconnect),
2445 TRANS(SocketINETClose),
2446 TRANS(SocketINETClose),
2447 };
2448
2449 #if defined(IPv6) && defined(AF_INET6)
2450 Xtransport TRANS(SocketINET6Funcs) = {
2451
2452 "inet6",
2453 0,
2454 #ifdef TRANS_CLIENT
2455 TRANS(SocketOpenCOTSClient),
2456 #endif
2457 #ifdef TRANS_SERVER
2458 NULL,
2459 TRANS(SocketOpenCOTSServer),
2460 #endif
2461 #ifdef TRANS_REOPEN
2462 TRANS(SocketReopenCOTSServer),
2463 #endif
2464 TRANS(SocketSetOption),
2465 #ifdef TRANS_SERVER
2466 TRANS(SocketINETCreateListener),
2467 NULL,
2468 TRANS(SocketINETAccept),
2469 #endif
2470 #ifdef TRANS_CLIENT
2471 TRANS(SocketINETConnect),
2472 #endif
2473 TRANS(SocketBytesReadable),
2474 TRANS(SocketRead),
2475 TRANS(SocketWrite),
2476 TRANS(SocketReadv),
2477 TRANS(SocketWritev),
2478 #if XTRANS_SEND_FDS
2479 TRANS(SocketSendFdInvalid),
2480 TRANS(SocketRecvFdInvalid),
2481 #endif
2482 TRANS(SocketDisconnect),
2483 TRANS(SocketINETClose),
2484 TRANS(SocketINETClose),
2485 };
2486 #endif
2487 #endif
2488
2489 #ifdef UNIXCONN
2490 #if !defined(LOCALCONN)
2491 Xtransport TRANS(SocketLocalFuncs) = {
2492
2493 "local",
2494 #ifdef HAVE_ABSTRACT_SOCKETS
2495 TRANS_ABSTRACT,
2496 #else
2497 0,
2498 #endif
2499 #ifdef TRANS_CLIENT
2500 TRANS(SocketOpenCOTSClient),
2501 #endif
2502 #ifdef TRANS_SERVER
2503 NULL,
2504 TRANS(SocketOpenCOTSServer),
2505 #endif
2506 #ifdef TRANS_REOPEN
2507 TRANS(SocketReopenCOTSServer),
2508 #endif
2509 TRANS(SocketSetOption),
2510 #ifdef TRANS_SERVER
2511 TRANS(SocketUNIXCreateListener),
2512 TRANS(SocketUNIXResetListener),
2513 TRANS(SocketUNIXAccept),
2514 #endif
2515 #ifdef TRANS_CLIENT
2516 TRANS(SocketUNIXConnect),
2517 #endif
2518 TRANS(SocketBytesReadable),
2519 TRANS(SocketRead),
2520 TRANS(SocketWrite),
2521 TRANS(SocketReadv),
2522 TRANS(SocketWritev),
2523 #if XTRANS_SEND_FDS
2524 TRANS(SocketSendFd),
2525 TRANS(SocketRecvFd),
2526 #endif
2527 TRANS(SocketDisconnect),
2528 TRANS(SocketUNIXClose),
2529 TRANS(SocketUNIXCloseForCloning),
2530 };
2531 #endif
2532 # ifdef TRANS_SERVER
2533 # if !defined(LOCALCONN)
2534 static const char* unix_nolisten[] = { "local" , NULL };
2535 # endif
2536 # endif
2537
2538 Xtransport TRANS(SocketUNIXFuncs) = {
2539
2540 "unix",
2541 #if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS)
2542 TRANS_ALIAS,
2543 #else
2544 0,
2545 #endif
2546 #ifdef TRANS_CLIENT
2547 TRANS(SocketOpenCOTSClient),
2548 #endif
2549 #ifdef TRANS_SERVER
2550 #if !defined(LOCALCONN)
2551 unix_nolisten,
2552 #else
2553 NULL,
2554 #endif
2555 TRANS(SocketOpenCOTSServer),
2556 #endif
2557 #ifdef TRANS_REOPEN
2558 TRANS(SocketReopenCOTSServer),
2559 #endif
2560 TRANS(SocketSetOption),
2561 #ifdef TRANS_SERVER
2562 TRANS(SocketUNIXCreateListener),
2563 TRANS(SocketUNIXResetListener),
2564 TRANS(SocketUNIXAccept),
2565 #endif
2566 #ifdef TRANS_CLIENT
2567 TRANS(SocketUNIXConnect),
2568 #endif
2569 TRANS(SocketBytesReadable),
2570 TRANS(SocketRead),
2571 TRANS(SocketWrite),
2572 TRANS(SocketReadv),
2573 TRANS(SocketWritev),
2574 #if XTRANS_SEND_FDS
2575 TRANS(SocketSendFd),
2576 TRANS(SocketRecvFd),
2577 #endif
2578 TRANS(SocketDisconnect),
2579 TRANS(SocketUNIXClose),
2580 TRANS(SocketUNIXCloseForCloning),
2581 };
2582
2583 #endif