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