Xtranssock.c revision fe567363
1af928962Smrg/* 2af928962Smrg * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. 3af928962Smrg * 4af928962Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5af928962Smrg * copy of this software and associated documentation files (the "Software"), 6af928962Smrg * to deal in the Software without restriction, including without limitation 7af928962Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8af928962Smrg * and/or sell copies of the Software, and to permit persons to whom the 9af928962Smrg * Software is furnished to do so, subject to the following conditions: 10af928962Smrg * 11af928962Smrg * The above copyright notice and this permission notice (including the next 12af928962Smrg * paragraph) shall be included in all copies or substantial portions of the 13af928962Smrg * Software. 14af928962Smrg * 15af928962Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16af928962Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17af928962Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18af928962Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19af928962Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20af928962Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21af928962Smrg * DEALINGS IN THE SOFTWARE. 22af928962Smrg */ 2373143b9aSmrg/* 2473143b9aSmrg 2573143b9aSmrgCopyright 1993, 1994, 1998 The Open Group 2673143b9aSmrg 2773143b9aSmrgPermission to use, copy, modify, distribute, and sell this software and its 2873143b9aSmrgdocumentation for any purpose is hereby granted without fee, provided that 2973143b9aSmrgthe above copyright notice appear in all copies and that both that 3073143b9aSmrgcopyright notice and this permission notice appear in supporting 3173143b9aSmrgdocumentation. 3273143b9aSmrg 3373143b9aSmrgThe above copyright notice and this permission notice shall be included 3473143b9aSmrgin all copies or substantial portions of the Software. 3573143b9aSmrg 3673143b9aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 3773143b9aSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3873143b9aSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 3973143b9aSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 4073143b9aSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 4173143b9aSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 4273143b9aSmrgOTHER DEALINGS IN THE SOFTWARE. 4373143b9aSmrg 4473143b9aSmrgExcept as contained in this notice, the name of the copyright holders shall 4573143b9aSmrgnot be used in advertising or otherwise to promote the sale, use or 4673143b9aSmrgother dealings in this Software without prior written authorization 4773143b9aSmrgfrom the copyright holders. 4873143b9aSmrg 4973143b9aSmrg * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA 5073143b9aSmrg * 5173143b9aSmrg * All Rights Reserved 5273143b9aSmrg * 5373143b9aSmrg * Permission to use, copy, modify, and distribute this software and its 5473143b9aSmrg * documentation for any purpose and without fee is hereby granted, provided 5573143b9aSmrg * that the above copyright notice appear in all copies and that both that 5673143b9aSmrg * copyright notice and this permission notice appear in supporting 5773143b9aSmrg * documentation, and that the name NCR not be used in advertising 5873143b9aSmrg * or publicity pertaining to distribution of the software without specific, 5973143b9aSmrg * written prior permission. NCR makes no representations about the 6073143b9aSmrg * suitability of this software for any purpose. It is provided "as is" 6173143b9aSmrg * without express or implied warranty. 6273143b9aSmrg * 6373143b9aSmrg * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 6473143b9aSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 6573143b9aSmrg * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR 6673143b9aSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 6773143b9aSmrg * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 6873143b9aSmrg * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 6973143b9aSmrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7073143b9aSmrg */ 7173143b9aSmrg 7273143b9aSmrg#include <ctype.h> 7373143b9aSmrg#ifdef XTHREADS 7473143b9aSmrg#include <X11/Xthreads.h> 7573143b9aSmrg#endif 7673143b9aSmrg 7773143b9aSmrg#ifndef WIN32 7873143b9aSmrg 7973143b9aSmrg#if defined(TCPCONN) || defined(UNIXCONN) 8073143b9aSmrg#include <sys/socket.h> 8173143b9aSmrg#include <netinet/in.h> 8273143b9aSmrg#include <arpa/inet.h> 8373143b9aSmrg#endif 8473143b9aSmrg 8573143b9aSmrg#if defined(TCPCONN) || defined(UNIXCONN) 8673143b9aSmrg#define X_INCLUDE_NETDB_H 8773143b9aSmrg#define XOS_USE_NO_LOCKING 8873143b9aSmrg#include <X11/Xos_r.h> 8973143b9aSmrg#endif 9073143b9aSmrg 9173143b9aSmrg#ifdef UNIXCONN 9273143b9aSmrg#ifndef X_NO_SYS_UN 9373143b9aSmrg#include <sys/un.h> 9473143b9aSmrg#endif 9573143b9aSmrg#include <sys/stat.h> 9673143b9aSmrg#endif 9773143b9aSmrg 9873143b9aSmrg 9973143b9aSmrg#ifndef NO_TCP_H 100fe567363Smrg#if defined(linux) || defined(__GLIBC__) 10173143b9aSmrg#include <sys/param.h> 10273143b9aSmrg#endif /* osf */ 10373143b9aSmrg#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) 10473143b9aSmrg#include <sys/param.h> 10573143b9aSmrg#include <machine/endian.h> 10673143b9aSmrg#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __DragonFly__ */ 10773143b9aSmrg#include <netinet/tcp.h> 10873143b9aSmrg#endif /* !NO_TCP_H */ 10973143b9aSmrg 11073143b9aSmrg#include <sys/ioctl.h> 111e8a71cdfSmrg#if defined(SVR4) || defined(__SVR4) 11273143b9aSmrg#include <sys/filio.h> 11373143b9aSmrg#endif 11473143b9aSmrg 11573143b9aSmrg#if (defined(__i386__) && defined(SYSV)) && !defined(SCO325) && !defined(sun) 11673143b9aSmrg#include <net/errno.h> 117fe567363Smrg#endif 11873143b9aSmrg 119fe567363Smrg#if defined(__i386__) && defined(SYSV) 12073143b9aSmrg#include <sys/stropts.h> 121fe567363Smrg#endif 12273143b9aSmrg 1238d4c0f7bSmrg#include <unistd.h> 1248d4c0f7bSmrg 12573143b9aSmrg#else /* !WIN32 */ 12673143b9aSmrg 12773143b9aSmrg#include <X11/Xwinsock.h> 12873143b9aSmrg#include <X11/Xwindows.h> 12973143b9aSmrg#include <X11/Xw32defs.h> 13073143b9aSmrg#undef close 13173143b9aSmrg#define close closesocket 13273143b9aSmrg#define ECONNREFUSED WSAECONNREFUSED 13373143b9aSmrg#define EADDRINUSE WSAEADDRINUSE 13473143b9aSmrg#define EPROTOTYPE WSAEPROTOTYPE 13573143b9aSmrg#undef EWOULDBLOCK 13673143b9aSmrg#define EWOULDBLOCK WSAEWOULDBLOCK 13773143b9aSmrg#define EINPROGRESS WSAEINPROGRESS 13873143b9aSmrg#undef EINTR 13973143b9aSmrg#define EINTR WSAEINTR 14073143b9aSmrg#define X_INCLUDE_NETDB_H 14173143b9aSmrg#define XOS_USE_MTSAFE_NETDBAPI 14273143b9aSmrg#include <X11/Xos_r.h> 14373143b9aSmrg#endif /* WIN32 */ 14473143b9aSmrg 14573143b9aSmrg#if defined(SO_DONTLINGER) && defined(SO_LINGER) 14673143b9aSmrg#undef SO_DONTLINGER 14773143b9aSmrg#endif 14873143b9aSmrg 14973143b9aSmrg/* others don't need this */ 15073143b9aSmrg#define SocketInitOnce() /**/ 15173143b9aSmrg 15273143b9aSmrg#ifdef linux 15373143b9aSmrg#define HAVE_ABSTRACT_SOCKETS 15473143b9aSmrg#endif 15573143b9aSmrg 15673143b9aSmrg#define MIN_BACKLOG 128 15773143b9aSmrg#ifdef SOMAXCONN 15873143b9aSmrg#if SOMAXCONN > MIN_BACKLOG 15973143b9aSmrg#define BACKLOG SOMAXCONN 16073143b9aSmrg#endif 16173143b9aSmrg#endif 16273143b9aSmrg#ifndef BACKLOG 16373143b9aSmrg#define BACKLOG MIN_BACKLOG 16473143b9aSmrg#endif 16573143b9aSmrg 16673143b9aSmrg/* 16773143b9aSmrg * This is the Socket implementation of the X Transport service layer 16873143b9aSmrg * 16973143b9aSmrg * This file contains the implementation for both the UNIX and INET domains, 17073143b9aSmrg * and can be built for either one, or both. 17173143b9aSmrg * 17273143b9aSmrg */ 17373143b9aSmrg 174fe567363Smrgtypedef struct _Sockettrans2dev { 175fe567363Smrg const char *transname; 17673143b9aSmrg int family; 17773143b9aSmrg int devcotsname; 17873143b9aSmrg int devcltsname; 17973143b9aSmrg int protocol; 18073143b9aSmrg} Sockettrans2dev; 18173143b9aSmrg 18273143b9aSmrgstatic Sockettrans2dev Sockettrans2devtab[] = { 18373143b9aSmrg#ifdef TCPCONN 18473143b9aSmrg {"inet",AF_INET,SOCK_STREAM,SOCK_DGRAM,0}, 18573143b9aSmrg#if !defined(IPv6) || !defined(AF_INET6) 18673143b9aSmrg {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0}, 18773143b9aSmrg#else /* IPv6 */ 18873143b9aSmrg {"tcp",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0}, 18973143b9aSmrg {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0}, /* fallback */ 19073143b9aSmrg {"inet6",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0}, 19173143b9aSmrg#endif 19273143b9aSmrg#endif /* TCPCONN */ 19373143b9aSmrg#ifdef UNIXCONN 19473143b9aSmrg {"unix",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0}, 19573143b9aSmrg#if !defined(LOCALCONN) 19673143b9aSmrg {"local",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0}, 19773143b9aSmrg#endif /* !LOCALCONN */ 19873143b9aSmrg#endif /* UNIXCONN */ 19973143b9aSmrg}; 20073143b9aSmrg 20173143b9aSmrg#define NUMSOCKETFAMILIES (sizeof(Sockettrans2devtab)/sizeof(Sockettrans2dev)) 20273143b9aSmrg 20373143b9aSmrg#ifdef TCPCONN 20473143b9aSmrgstatic int TRANS(SocketINETClose) (XtransConnInfo ciptr); 20573143b9aSmrg#endif 20673143b9aSmrg 20773143b9aSmrg#ifdef UNIXCONN 20873143b9aSmrg 20973143b9aSmrg 21073143b9aSmrg#if defined(X11_t) 21173143b9aSmrg#define UNIX_PATH "/tmp/.X11-unix/X" 21273143b9aSmrg#define UNIX_DIR "/tmp/.X11-unix" 21373143b9aSmrg#endif /* X11_t */ 21473143b9aSmrg#if defined(XIM_t) 21573143b9aSmrg#define UNIX_PATH "/tmp/.XIM-unix/XIM" 21673143b9aSmrg#define UNIX_DIR "/tmp/.XIM-unix" 21773143b9aSmrg#endif /* XIM_t */ 21873143b9aSmrg#if defined(FS_t) || defined(FONT_t) 21973143b9aSmrg#define UNIX_PATH "/tmp/.font-unix/fs" 22073143b9aSmrg#define UNIX_DIR "/tmp/.font-unix" 22173143b9aSmrg#endif /* FS_t || FONT_t */ 22273143b9aSmrg#if defined(ICE_t) 22373143b9aSmrg#define UNIX_PATH "/tmp/.ICE-unix/" 22473143b9aSmrg#define UNIX_DIR "/tmp/.ICE-unix" 22573143b9aSmrg#endif /* ICE_t */ 22673143b9aSmrg#if defined(TEST_t) 22773143b9aSmrg#define UNIX_PATH "/tmp/.Test-unix/test" 22873143b9aSmrg#define UNIX_DIR "/tmp/.Test-unix" 22973143b9aSmrg#endif 23073143b9aSmrg#if defined(LBXPROXY_t) 23173143b9aSmrg#define UNIX_PATH "/tmp/.X11-unix/X" 23273143b9aSmrg#define UNIX_DIR "/tmp/.X11-unix" 23373143b9aSmrg#endif 23473143b9aSmrg 23573143b9aSmrg 23673143b9aSmrg#endif /* UNIXCONN */ 23773143b9aSmrg 23873143b9aSmrg#define PORTBUFSIZE 32 23973143b9aSmrg 24073143b9aSmrg#ifndef MAXHOSTNAMELEN 24173143b9aSmrg#define MAXHOSTNAMELEN 255 24273143b9aSmrg#endif 24373143b9aSmrg 24473143b9aSmrg#if defined HAVE_SOCKLEN_T || (defined(IPv6) && defined(AF_INET6)) 24573143b9aSmrg# define SOCKLEN_T socklen_t 246e8a71cdfSmrg#elif defined(SVR4) || defined(__SVR4) || defined(__SCO__) 247fe567363Smrg# define SOCKLEN_T size_t 24873143b9aSmrg#else 24973143b9aSmrg# define SOCKLEN_T int 25073143b9aSmrg#endif 25173143b9aSmrg 25273143b9aSmrg/* 25373143b9aSmrg * These are some utility function used by the real interface function below. 25473143b9aSmrg */ 25573143b9aSmrg 25673143b9aSmrgstatic int 257fe567363SmrgTRANS(SocketSelectFamily) (int first, const char *family) 25873143b9aSmrg 25973143b9aSmrg{ 26073143b9aSmrg int i; 26173143b9aSmrg 262fe567363Smrg prmsg (3,"SocketSelectFamily(%s)\n", family); 26373143b9aSmrg 26473143b9aSmrg for (i = first + 1; i < NUMSOCKETFAMILIES;i++) 26573143b9aSmrg { 26673143b9aSmrg if (!strcmp (family, Sockettrans2devtab[i].transname)) 26773143b9aSmrg return i; 26873143b9aSmrg } 26973143b9aSmrg 27073143b9aSmrg return (first == -1 ? -2 : -1); 27173143b9aSmrg} 27273143b9aSmrg 27373143b9aSmrg 27473143b9aSmrg/* 27573143b9aSmrg * This function gets the local address of the socket and stores it in the 27673143b9aSmrg * XtransConnInfo structure for the connection. 27773143b9aSmrg */ 27873143b9aSmrg 27973143b9aSmrgstatic int 28073143b9aSmrgTRANS(SocketINETGetAddr) (XtransConnInfo ciptr) 28173143b9aSmrg 28273143b9aSmrg{ 28373143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 28473143b9aSmrg struct sockaddr_storage socknamev6; 285b53e5eeaSmrg#else 28673143b9aSmrg struct sockaddr_in socknamev4; 287b53e5eeaSmrg#endif 28873143b9aSmrg void *socknamePtr; 28973143b9aSmrg SOCKLEN_T namelen; 29073143b9aSmrg 291fe567363Smrg prmsg (3,"SocketINETGetAddr(%p)\n", ciptr); 29273143b9aSmrg 29373143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 294b53e5eeaSmrg namelen = sizeof(socknamev6); 295b53e5eeaSmrg socknamePtr = &socknamev6; 296b53e5eeaSmrg#else 297b53e5eeaSmrg namelen = sizeof(socknamev4); 298b53e5eeaSmrg socknamePtr = &socknamev4; 29973143b9aSmrg#endif 30073143b9aSmrg 30173143b9aSmrg bzero(socknamePtr, namelen); 302fe567363Smrg 30373143b9aSmrg if (getsockname (ciptr->fd,(struct sockaddr *) socknamePtr, 30473143b9aSmrg (void *)&namelen) < 0) 30573143b9aSmrg { 30673143b9aSmrg#ifdef WIN32 30773143b9aSmrg errno = WSAGetLastError(); 30873143b9aSmrg#endif 309fe567363Smrg prmsg (1,"SocketINETGetAddr: getsockname() failed: %d\n", 310fe567363Smrg EGET()); 31173143b9aSmrg return -1; 31273143b9aSmrg } 31373143b9aSmrg 31473143b9aSmrg /* 31573143b9aSmrg * Everything looks good: fill in the XtransConnInfo structure. 31673143b9aSmrg */ 31773143b9aSmrg 318fe567363Smrg if ((ciptr->addr = malloc (namelen)) == NULL) 31973143b9aSmrg { 320fe567363Smrg prmsg (1, 321fe567363Smrg "SocketINETGetAddr: Can't allocate space for the addr\n"); 32273143b9aSmrg return -1; 32373143b9aSmrg } 32473143b9aSmrg 32573143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 326b53e5eeaSmrg ciptr->family = ((struct sockaddr *)socknamePtr)->sa_family; 327b53e5eeaSmrg#else 328b53e5eeaSmrg ciptr->family = socknamev4.sin_family; 32973143b9aSmrg#endif 33073143b9aSmrg ciptr->addrlen = namelen; 33173143b9aSmrg memcpy (ciptr->addr, socknamePtr, ciptr->addrlen); 33273143b9aSmrg 33373143b9aSmrg return 0; 33473143b9aSmrg} 33573143b9aSmrg 33673143b9aSmrg 33773143b9aSmrg/* 33873143b9aSmrg * This function gets the remote address of the socket and stores it in the 33973143b9aSmrg * XtransConnInfo structure for the connection. 34073143b9aSmrg */ 34173143b9aSmrg 34273143b9aSmrgstatic int 34373143b9aSmrgTRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr) 34473143b9aSmrg 34573143b9aSmrg{ 34673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 34773143b9aSmrg struct sockaddr_storage socknamev6; 34873143b9aSmrg#endif 34973143b9aSmrg struct sockaddr_in socknamev4; 35073143b9aSmrg void *socknamePtr; 35173143b9aSmrg SOCKLEN_T namelen; 35273143b9aSmrg 35373143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 354b53e5eeaSmrg if (ciptr->family == AF_INET6) 35573143b9aSmrg { 35673143b9aSmrg namelen = sizeof(socknamev6); 35773143b9aSmrg socknamePtr = &socknamev6; 35873143b9aSmrg } 35973143b9aSmrg else 36073143b9aSmrg#endif 36173143b9aSmrg { 36273143b9aSmrg namelen = sizeof(socknamev4); 36373143b9aSmrg socknamePtr = &socknamev4; 36473143b9aSmrg } 36573143b9aSmrg 36673143b9aSmrg bzero(socknamePtr, namelen); 367fe567363Smrg 368fe567363Smrg prmsg (3,"SocketINETGetPeerAddr(%p)\n", ciptr); 36973143b9aSmrg 37073143b9aSmrg if (getpeername (ciptr->fd, (struct sockaddr *) socknamePtr, 37173143b9aSmrg (void *)&namelen) < 0) 37273143b9aSmrg { 37373143b9aSmrg#ifdef WIN32 37473143b9aSmrg errno = WSAGetLastError(); 37573143b9aSmrg#endif 376fe567363Smrg prmsg (1,"SocketINETGetPeerAddr: getpeername() failed: %d\n", 377fe567363Smrg EGET()); 37873143b9aSmrg return -1; 37973143b9aSmrg } 38073143b9aSmrg 38173143b9aSmrg /* 38273143b9aSmrg * Everything looks good: fill in the XtransConnInfo structure. 38373143b9aSmrg */ 38473143b9aSmrg 385fe567363Smrg if ((ciptr->peeraddr = malloc (namelen)) == NULL) 38673143b9aSmrg { 387fe567363Smrg prmsg (1, 388fe567363Smrg "SocketINETGetPeerAddr: Can't allocate space for the addr\n"); 38973143b9aSmrg return -1; 39073143b9aSmrg } 39173143b9aSmrg 39273143b9aSmrg ciptr->peeraddrlen = namelen; 39373143b9aSmrg memcpy (ciptr->peeraddr, socknamePtr, ciptr->peeraddrlen); 39473143b9aSmrg 39573143b9aSmrg return 0; 39673143b9aSmrg} 39773143b9aSmrg 39873143b9aSmrg 39973143b9aSmrgstatic XtransConnInfo 40073143b9aSmrgTRANS(SocketOpen) (int i, int type) 40173143b9aSmrg 40273143b9aSmrg{ 40373143b9aSmrg XtransConnInfo ciptr; 40473143b9aSmrg 405fe567363Smrg prmsg (3,"SocketOpen(%d,%d)\n", i, type); 40673143b9aSmrg 407fe567363Smrg if ((ciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL) 40873143b9aSmrg { 409fe567363Smrg prmsg (1, "SocketOpen: malloc failed\n"); 41073143b9aSmrg return NULL; 41173143b9aSmrg } 41273143b9aSmrg 41373143b9aSmrg if ((ciptr->fd = socket(Sockettrans2devtab[i].family, type, 41473143b9aSmrg Sockettrans2devtab[i].protocol)) < 0 41573143b9aSmrg#ifndef WIN32 41673143b9aSmrg#if (defined(X11_t) && !defined(USE_POLL)) || defined(FS_t) || defined(FONT_t) 4178d4c0f7bSmrg || ciptr->fd >= sysconf(_SC_OPEN_MAX) 41873143b9aSmrg#endif 41973143b9aSmrg#endif 42073143b9aSmrg ) { 42173143b9aSmrg#ifdef WIN32 42273143b9aSmrg errno = WSAGetLastError(); 42373143b9aSmrg#endif 424fe567363Smrg prmsg (2, "SocketOpen: socket() failed for %s\n", 425fe567363Smrg Sockettrans2devtab[i].transname); 42673143b9aSmrg 427fe567363Smrg free (ciptr); 42873143b9aSmrg return NULL; 42973143b9aSmrg } 43073143b9aSmrg 43173143b9aSmrg#ifdef TCP_NODELAY 43273143b9aSmrg if (Sockettrans2devtab[i].family == AF_INET 43373143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 43473143b9aSmrg || Sockettrans2devtab[i].family == AF_INET6 43573143b9aSmrg#endif 43673143b9aSmrg ) 43773143b9aSmrg { 43873143b9aSmrg /* 43973143b9aSmrg * turn off TCP coalescence for INET sockets 44073143b9aSmrg */ 44173143b9aSmrg 44273143b9aSmrg int tmp = 1; 44373143b9aSmrg setsockopt (ciptr->fd, IPPROTO_TCP, TCP_NODELAY, 44473143b9aSmrg (char *) &tmp, sizeof (int)); 44573143b9aSmrg } 44673143b9aSmrg#endif 44773143b9aSmrg 44873143b9aSmrg return ciptr; 44973143b9aSmrg} 45073143b9aSmrg 45173143b9aSmrg 45273143b9aSmrg#ifdef TRANS_REOPEN 45373143b9aSmrg 45473143b9aSmrgstatic XtransConnInfo 455fe567363SmrgTRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, char *port) 45673143b9aSmrg 45773143b9aSmrg{ 45873143b9aSmrg XtransConnInfo ciptr; 45973143b9aSmrg int portlen; 46073143b9aSmrg struct sockaddr *addr; 461fe567363Smrg size_t addrlen; 46273143b9aSmrg 463fe567363Smrg prmsg (3,"SocketReopen(%d,%d,%s)\n", type, fd, port); 46473143b9aSmrg 46573143b9aSmrg if (port == NULL) { 466fe567363Smrg prmsg (1, "SocketReopen: port was null!\n"); 46773143b9aSmrg return NULL; 46873143b9aSmrg } 46973143b9aSmrg 47073143b9aSmrg portlen = strlen(port) + 1; // include space for trailing null 47173143b9aSmrg#ifdef SOCK_MAXADDRLEN 47273143b9aSmrg if (portlen < 0 || portlen > (SOCK_MAXADDRLEN + 2)) { 473fe567363Smrg prmsg (1, "SocketReopen: invalid portlen %d\n", portlen); 47473143b9aSmrg return NULL; 47573143b9aSmrg } 47673143b9aSmrg if (portlen < 14) portlen = 14; 47773143b9aSmrg#else 47873143b9aSmrg if (portlen < 0 || portlen > 14) { 479fe567363Smrg prmsg (1, "SocketReopen: invalid portlen %d\n", portlen); 48073143b9aSmrg return NULL; 48173143b9aSmrg } 48273143b9aSmrg#endif /*SOCK_MAXADDRLEN*/ 48373143b9aSmrg 484fe567363Smrg if ((ciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL) 48573143b9aSmrg { 486fe567363Smrg prmsg (1, "SocketReopen: malloc(ciptr) failed\n"); 48773143b9aSmrg return NULL; 48873143b9aSmrg } 48973143b9aSmrg 49073143b9aSmrg ciptr->fd = fd; 49173143b9aSmrg 492fe567363Smrg addrlen = portlen + offsetof(struct sockaddr, sa_data); 493fe567363Smrg if ((addr = calloc (1, addrlen)) == NULL) { 494fe567363Smrg prmsg (1, "SocketReopen: malloc(addr) failed\n"); 495fe567363Smrg free (ciptr); 49673143b9aSmrg return NULL; 49773143b9aSmrg } 4988d4c0f7bSmrg ciptr->addr = (char *) addr; 499fe567363Smrg ciptr->addrlen = addrlen; 50073143b9aSmrg 501fe567363Smrg if ((ciptr->peeraddr = calloc (1, addrlen)) == NULL) { 502fe567363Smrg prmsg (1, "SocketReopen: malloc(portaddr) failed\n"); 503fe567363Smrg free (addr); 504fe567363Smrg free (ciptr); 50573143b9aSmrg return NULL; 50673143b9aSmrg } 507fe567363Smrg ciptr->peeraddrlen = addrlen; 50873143b9aSmrg 50973143b9aSmrg /* Initialize ciptr structure as if it were a normally-opened unix socket */ 51073143b9aSmrg ciptr->flags = TRANS_LOCAL | TRANS_NOUNLINK; 51173143b9aSmrg#ifdef BSD44SOCKETS 512fe567363Smrg addr->sa_len = addrlen; 51373143b9aSmrg#endif 51473143b9aSmrg addr->sa_family = AF_UNIX; 51573143b9aSmrg#ifdef HAS_STRLCPY 51673143b9aSmrg strlcpy(addr->sa_data, port, portlen); 51773143b9aSmrg#else 51873143b9aSmrg strncpy(addr->sa_data, port, portlen); 51973143b9aSmrg#endif 52073143b9aSmrg ciptr->family = AF_UNIX; 521fe567363Smrg memcpy(ciptr->peeraddr, ciptr->addr, addrlen); 52273143b9aSmrg ciptr->port = rindex(addr->sa_data, ':'); 523e8a71cdfSmrg if (ciptr->port == NULL) { 524e8a71cdfSmrg if (is_numeric(addr->sa_data)) { 525e8a71cdfSmrg ciptr->port = addr->sa_data; 526e8a71cdfSmrg } 527e8a71cdfSmrg } else if (ciptr->port[0] == ':') { 528e8a71cdfSmrg ciptr->port++; 529e8a71cdfSmrg } 530e8a71cdfSmrg /* port should now point to portnum or NULL */ 53173143b9aSmrg return ciptr; 53273143b9aSmrg} 53373143b9aSmrg 53473143b9aSmrg#endif /* TRANS_REOPEN */ 53573143b9aSmrg 53673143b9aSmrg 53773143b9aSmrg/* 53873143b9aSmrg * These functions are the interface supplied in the Xtransport structure 53973143b9aSmrg */ 54073143b9aSmrg 54173143b9aSmrg#ifdef TRANS_CLIENT 54273143b9aSmrg 54373143b9aSmrgstatic XtransConnInfo 544fe567363SmrgTRANS(SocketOpenCOTSClientBase) (const char *transname, const char *protocol, 545fe567363Smrg const char *host, const char *port, int previndex) 54673143b9aSmrg{ 54773143b9aSmrg XtransConnInfo ciptr; 54873143b9aSmrg int i = previndex; 54973143b9aSmrg 550fe567363Smrg prmsg (2, "SocketOpenCOTSClient(%s,%s,%s)\n", 55173143b9aSmrg protocol, host, port); 55273143b9aSmrg 55373143b9aSmrg SocketInitOnce(); 55473143b9aSmrg 55573143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, transname)) >= 0) { 55673143b9aSmrg if ((ciptr = TRANS(SocketOpen) ( 557e8a71cdfSmrg i, Sockettrans2devtab[i].devcotsname)) != NULL) { 558e8a71cdfSmrg /* Save the index for later use */ 559e8a71cdfSmrg 560e8a71cdfSmrg ciptr->index = i; 56173143b9aSmrg break; 562e8a71cdfSmrg } 56373143b9aSmrg } 56473143b9aSmrg if (i < 0) { 56573143b9aSmrg if (i == -1) 566fe567363Smrg prmsg (1,"SocketOpenCOTSClient: Unable to open socket for %s\n", 567fe567363Smrg transname); 56873143b9aSmrg else 569fe567363Smrg prmsg (1,"SocketOpenCOTSClient: Unable to determine socket type for %s\n", 570fe567363Smrg transname); 57173143b9aSmrg return NULL; 57273143b9aSmrg } 57373143b9aSmrg 57473143b9aSmrg return ciptr; 57573143b9aSmrg} 57673143b9aSmrg 57773143b9aSmrgstatic XtransConnInfo 578fe567363SmrgTRANS(SocketOpenCOTSClient) (Xtransport *thistrans, char *protocol, 57973143b9aSmrg char *host, char *port) 58073143b9aSmrg{ 58173143b9aSmrg return TRANS(SocketOpenCOTSClientBase)( 58273143b9aSmrg thistrans->TransName, protocol, host, port, -1); 58373143b9aSmrg} 58473143b9aSmrg 58573143b9aSmrg 58673143b9aSmrg#endif /* TRANS_CLIENT */ 58773143b9aSmrg 58873143b9aSmrg 58973143b9aSmrg#ifdef TRANS_SERVER 59073143b9aSmrg 59173143b9aSmrgstatic XtransConnInfo 592fe567363SmrgTRANS(SocketOpenCOTSServer) (Xtransport *thistrans, char *protocol, 59373143b9aSmrg char *host, char *port) 59473143b9aSmrg 59573143b9aSmrg{ 59673143b9aSmrg XtransConnInfo ciptr; 59773143b9aSmrg int i = -1; 59873143b9aSmrg 599fe567363Smrg prmsg (2,"SocketOpenCOTSServer(%s,%s,%s)\n", protocol, host, port); 60073143b9aSmrg 60173143b9aSmrg SocketInitOnce(); 60273143b9aSmrg 60373143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 60473143b9aSmrg if ((ciptr = TRANS(SocketOpen) ( 60573143b9aSmrg i, Sockettrans2devtab[i].devcotsname)) != NULL) 60673143b9aSmrg break; 60773143b9aSmrg } 60873143b9aSmrg if (i < 0) { 60973143b9aSmrg if (i == -1) 610fe567363Smrg prmsg (1,"SocketOpenCOTSServer: Unable to open socket for %s\n", 611fe567363Smrg thistrans->TransName); 61273143b9aSmrg else 613fe567363Smrg prmsg (1,"SocketOpenCOTSServer: Unable to determine socket type for %s\n", 614fe567363Smrg thistrans->TransName); 61573143b9aSmrg return NULL; 61673143b9aSmrg } 61773143b9aSmrg 61873143b9aSmrg /* 61973143b9aSmrg * Using this prevents the bind() check for an existing server listening 62073143b9aSmrg * on the same port, but it is required for other reasons. 62173143b9aSmrg */ 62273143b9aSmrg#ifdef SO_REUSEADDR 62373143b9aSmrg 62473143b9aSmrg /* 62573143b9aSmrg * SO_REUSEADDR only applied to AF_INET && AF_INET6 62673143b9aSmrg */ 62773143b9aSmrg 62873143b9aSmrg if (Sockettrans2devtab[i].family == AF_INET 62973143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 63073143b9aSmrg || Sockettrans2devtab[i].family == AF_INET6 63173143b9aSmrg#endif 63273143b9aSmrg ) 63373143b9aSmrg { 63473143b9aSmrg int one = 1; 63573143b9aSmrg setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR, 63673143b9aSmrg (char *) &one, sizeof (int)); 63773143b9aSmrg } 63873143b9aSmrg#endif 63973143b9aSmrg#ifdef IPV6_V6ONLY 64073143b9aSmrg if (Sockettrans2devtab[i].family == AF_INET6) 64173143b9aSmrg { 64273143b9aSmrg int one = 1; 64373143b9aSmrg setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int)); 64473143b9aSmrg } 64573143b9aSmrg#endif 64673143b9aSmrg /* Save the index for later use */ 64773143b9aSmrg 64873143b9aSmrg ciptr->index = i; 64973143b9aSmrg 65073143b9aSmrg return ciptr; 65173143b9aSmrg} 65273143b9aSmrg 65373143b9aSmrg#endif /* TRANS_SERVER */ 65473143b9aSmrg 65573143b9aSmrg 65673143b9aSmrg#ifdef TRANS_CLIENT 65773143b9aSmrg 65873143b9aSmrgstatic XtransConnInfo 659fe567363SmrgTRANS(SocketOpenCLTSClient) (Xtransport *thistrans, char *protocol, 66073143b9aSmrg char *host, char *port) 66173143b9aSmrg 66273143b9aSmrg{ 66373143b9aSmrg XtransConnInfo ciptr; 66473143b9aSmrg int i = -1; 66573143b9aSmrg 666fe567363Smrg prmsg (2,"SocketOpenCLTSClient(%s,%s,%s)\n", protocol, host, port); 66773143b9aSmrg 66873143b9aSmrg SocketInitOnce(); 66973143b9aSmrg 67073143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 67173143b9aSmrg if ((ciptr = TRANS(SocketOpen) ( 67273143b9aSmrg i, Sockettrans2devtab[i].devcotsname)) != NULL) 67373143b9aSmrg break; 67473143b9aSmrg } 67573143b9aSmrg if (i < 0) { 67673143b9aSmrg if (i == -1) 677fe567363Smrg prmsg (1,"SocketOpenCLTSClient: Unable to open socket for %s\n", 678fe567363Smrg thistrans->TransName); 67973143b9aSmrg else 680fe567363Smrg prmsg (1,"SocketOpenCLTSClient: Unable to determine socket type for %s\n", 681fe567363Smrg thistrans->TransName); 68273143b9aSmrg return NULL; 68373143b9aSmrg } 68473143b9aSmrg 68573143b9aSmrg /* Save the index for later use */ 68673143b9aSmrg 68773143b9aSmrg ciptr->index = i; 68873143b9aSmrg 68973143b9aSmrg return ciptr; 69073143b9aSmrg} 69173143b9aSmrg 69273143b9aSmrg#endif /* TRANS_CLIENT */ 69373143b9aSmrg 69473143b9aSmrg 69573143b9aSmrg#ifdef TRANS_SERVER 69673143b9aSmrg 69773143b9aSmrgstatic XtransConnInfo 698fe567363SmrgTRANS(SocketOpenCLTSServer) (Xtransport *thistrans, char *protocol, 69973143b9aSmrg char *host, char *port) 70073143b9aSmrg 70173143b9aSmrg{ 70273143b9aSmrg XtransConnInfo ciptr; 70373143b9aSmrg int i = -1; 70473143b9aSmrg 705fe567363Smrg prmsg (2,"SocketOpenCLTSServer(%s,%s,%s)\n", protocol, host, port); 70673143b9aSmrg 70773143b9aSmrg SocketInitOnce(); 70873143b9aSmrg 70973143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 71073143b9aSmrg if ((ciptr = TRANS(SocketOpen) ( 71173143b9aSmrg i, Sockettrans2devtab[i].devcotsname)) != NULL) 71273143b9aSmrg break; 71373143b9aSmrg } 71473143b9aSmrg if (i < 0) { 71573143b9aSmrg if (i == -1) 716fe567363Smrg prmsg (1,"SocketOpenCLTSServer: Unable to open socket for %s\n", 717fe567363Smrg thistrans->TransName); 71873143b9aSmrg else 719fe567363Smrg prmsg (1,"SocketOpenCLTSServer: Unable to determine socket type for %s\n", 720fe567363Smrg thistrans->TransName); 72173143b9aSmrg return NULL; 72273143b9aSmrg } 72373143b9aSmrg 72473143b9aSmrg#ifdef IPV6_V6ONLY 72573143b9aSmrg if (Sockettrans2devtab[i].family == AF_INET6) 72673143b9aSmrg { 72773143b9aSmrg int one = 1; 72873143b9aSmrg setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int)); 72973143b9aSmrg } 73073143b9aSmrg#endif 73173143b9aSmrg /* Save the index for later use */ 73273143b9aSmrg 73373143b9aSmrg ciptr->index = i; 73473143b9aSmrg 73573143b9aSmrg return ciptr; 73673143b9aSmrg} 73773143b9aSmrg 73873143b9aSmrg#endif /* TRANS_SERVER */ 73973143b9aSmrg 74073143b9aSmrg 74173143b9aSmrg#ifdef TRANS_REOPEN 74273143b9aSmrg 74373143b9aSmrgstatic XtransConnInfo 74473143b9aSmrgTRANS(SocketReopenCOTSServer) (Xtransport *thistrans, int fd, char *port) 74573143b9aSmrg 74673143b9aSmrg{ 74773143b9aSmrg XtransConnInfo ciptr; 74873143b9aSmrg int i = -1; 74973143b9aSmrg 750fe567363Smrg prmsg (2, 751fe567363Smrg "SocketReopenCOTSServer(%d, %s)\n", fd, port); 75273143b9aSmrg 75373143b9aSmrg SocketInitOnce(); 75473143b9aSmrg 75573143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 75673143b9aSmrg if ((ciptr = TRANS(SocketReopen) ( 75773143b9aSmrg i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL) 75873143b9aSmrg break; 75973143b9aSmrg } 76073143b9aSmrg if (i < 0) { 76173143b9aSmrg if (i == -1) 762fe567363Smrg prmsg (1,"SocketReopenCOTSServer: Unable to open socket for %s\n", 763fe567363Smrg thistrans->TransName); 76473143b9aSmrg else 765fe567363Smrg prmsg (1,"SocketReopenCOTSServer: Unable to determine socket type for %s\n", 766fe567363Smrg thistrans->TransName); 76773143b9aSmrg return NULL; 76873143b9aSmrg } 76973143b9aSmrg 77073143b9aSmrg /* Save the index for later use */ 77173143b9aSmrg 77273143b9aSmrg ciptr->index = i; 77373143b9aSmrg 77473143b9aSmrg return ciptr; 77573143b9aSmrg} 77673143b9aSmrg 77773143b9aSmrgstatic XtransConnInfo 77873143b9aSmrgTRANS(SocketReopenCLTSServer) (Xtransport *thistrans, int fd, char *port) 77973143b9aSmrg 78073143b9aSmrg{ 78173143b9aSmrg XtransConnInfo ciptr; 78273143b9aSmrg int i = -1; 78373143b9aSmrg 784fe567363Smrg prmsg (2, 785fe567363Smrg "SocketReopenCLTSServer(%d, %s)\n", fd, port); 78673143b9aSmrg 78773143b9aSmrg SocketInitOnce(); 78873143b9aSmrg 78973143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 79073143b9aSmrg if ((ciptr = TRANS(SocketReopen) ( 79173143b9aSmrg i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL) 79273143b9aSmrg break; 79373143b9aSmrg } 79473143b9aSmrg if (i < 0) { 79573143b9aSmrg if (i == -1) 796fe567363Smrg prmsg (1,"SocketReopenCLTSServer: Unable to open socket for %s\n", 797fe567363Smrg thistrans->TransName); 79873143b9aSmrg else 799fe567363Smrg prmsg (1,"SocketReopenCLTSServer: Unable to determine socket type for %s\n", 800fe567363Smrg thistrans->TransName); 80173143b9aSmrg return NULL; 80273143b9aSmrg } 80373143b9aSmrg 80473143b9aSmrg /* Save the index for later use */ 80573143b9aSmrg 80673143b9aSmrg ciptr->index = i; 80773143b9aSmrg 80873143b9aSmrg return ciptr; 80973143b9aSmrg} 81073143b9aSmrg 81173143b9aSmrg#endif /* TRANS_REOPEN */ 81273143b9aSmrg 81373143b9aSmrg 81473143b9aSmrgstatic int 81573143b9aSmrgTRANS(SocketSetOption) (XtransConnInfo ciptr, int option, int arg) 81673143b9aSmrg 81773143b9aSmrg{ 818fe567363Smrg prmsg (2,"SocketSetOption(%d,%d,%d)\n", ciptr->fd, option, arg); 81973143b9aSmrg 82073143b9aSmrg return -1; 82173143b9aSmrg} 82273143b9aSmrg 82373143b9aSmrg#ifdef UNIXCONN 82473143b9aSmrgstatic int 82573143b9aSmrgset_sun_path(const char *port, const char *upath, char *path, int abstract) 82673143b9aSmrg{ 82773143b9aSmrg struct sockaddr_un s; 82873143b9aSmrg int maxlen = sizeof(s.sun_path) - 1; 82973143b9aSmrg const char *at = ""; 83073143b9aSmrg 83173143b9aSmrg if (!port || !*port || !path) 83273143b9aSmrg return -1; 83373143b9aSmrg 83473143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 83573143b9aSmrg if (port[0] == '@') 83673143b9aSmrg upath = ""; 83773143b9aSmrg else if (abstract) 83873143b9aSmrg at = "@"; 83973143b9aSmrg#endif 84073143b9aSmrg 84173143b9aSmrg if (*port == '/') /* a full pathname */ 84273143b9aSmrg upath = ""; 84373143b9aSmrg 84473143b9aSmrg if (strlen(port) + strlen(upath) > maxlen) 84573143b9aSmrg return -1; 846fe567363Smrg snprintf(path, sizeof(s.sun_path), "%s%s%s", at, upath, port); 84773143b9aSmrg return 0; 84873143b9aSmrg} 84973143b9aSmrg#endif 85073143b9aSmrg 85173143b9aSmrg#ifdef TRANS_SERVER 85273143b9aSmrg 85373143b9aSmrgstatic int 854fe567363SmrgTRANS(SocketCreateListener) (XtransConnInfo ciptr, 85573143b9aSmrg struct sockaddr *sockname, 85673143b9aSmrg int socknamelen, unsigned int flags) 85773143b9aSmrg 85873143b9aSmrg{ 85973143b9aSmrg SOCKLEN_T namelen = socknamelen; 86073143b9aSmrg int fd = ciptr->fd; 86173143b9aSmrg int retry; 86273143b9aSmrg 863fe567363Smrg prmsg (3, "SocketCreateListener(%p,%d)\n", ciptr, fd); 86473143b9aSmrg 86573143b9aSmrg if (Sockettrans2devtab[ciptr->index].family == AF_INET 86673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 86773143b9aSmrg || Sockettrans2devtab[ciptr->index].family == AF_INET6 86873143b9aSmrg#endif 86973143b9aSmrg ) 87073143b9aSmrg retry = 20; 87173143b9aSmrg else 87273143b9aSmrg retry = 0; 87373143b9aSmrg 87473143b9aSmrg while (bind (fd, (struct sockaddr *) sockname, namelen) < 0) 87573143b9aSmrg { 87673143b9aSmrg if (errno == EADDRINUSE) { 87773143b9aSmrg if (flags & ADDR_IN_USE_ALLOWED) 87873143b9aSmrg break; 87973143b9aSmrg else 88073143b9aSmrg return TRANS_ADDR_IN_USE; 88173143b9aSmrg } 882fe567363Smrg 88373143b9aSmrg if (retry-- == 0) { 884fe567363Smrg prmsg (1, "SocketCreateListener: failed to bind listener\n"); 88573143b9aSmrg close (fd); 88673143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 88773143b9aSmrg } 88873143b9aSmrg#ifdef SO_REUSEADDR 88973143b9aSmrg sleep (1); 89073143b9aSmrg#else 89173143b9aSmrg sleep (10); 89273143b9aSmrg#endif /* SO_REUSEDADDR */ 89373143b9aSmrg } 89473143b9aSmrg 89573143b9aSmrg if (Sockettrans2devtab[ciptr->index].family == AF_INET 89673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 89773143b9aSmrg || Sockettrans2devtab[ciptr->index].family == AF_INET6 89873143b9aSmrg#endif 89973143b9aSmrg ) { 90073143b9aSmrg#ifdef SO_DONTLINGER 90173143b9aSmrg setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0); 90273143b9aSmrg#else 90373143b9aSmrg#ifdef SO_LINGER 90473143b9aSmrg { 90573143b9aSmrg static int linger[2] = { 0, 0 }; 90673143b9aSmrg setsockopt (fd, SOL_SOCKET, SO_LINGER, 90773143b9aSmrg (char *) linger, sizeof (linger)); 90873143b9aSmrg } 90973143b9aSmrg#endif 91073143b9aSmrg#endif 91173143b9aSmrg} 91273143b9aSmrg 91373143b9aSmrg if (listen (fd, BACKLOG) < 0) 91473143b9aSmrg { 915fe567363Smrg prmsg (1, "SocketCreateListener: listen() failed\n"); 91673143b9aSmrg close (fd); 91773143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 91873143b9aSmrg } 919fe567363Smrg 92073143b9aSmrg /* Set a flag to indicate that this connection is a listener */ 92173143b9aSmrg 92273143b9aSmrg ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS); 92373143b9aSmrg 92473143b9aSmrg return 0; 92573143b9aSmrg} 92673143b9aSmrg 92773143b9aSmrg#ifdef TCPCONN 92873143b9aSmrgstatic int 92973143b9aSmrgTRANS(SocketINETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags) 93073143b9aSmrg 93173143b9aSmrg{ 93273143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 93373143b9aSmrg struct sockaddr_storage sockname; 93473143b9aSmrg#else 93573143b9aSmrg struct sockaddr_in sockname; 93673143b9aSmrg#endif 93773143b9aSmrg unsigned short sport; 93873143b9aSmrg SOCKLEN_T namelen = sizeof(sockname); 93973143b9aSmrg int status; 94073143b9aSmrg long tmpport; 94173143b9aSmrg#ifdef XTHREADS_NEEDS_BYNAMEPARAMS 94273143b9aSmrg _Xgetservbynameparams sparams; 94373143b9aSmrg#endif 94473143b9aSmrg struct servent *servp; 94573143b9aSmrg 94673143b9aSmrg#ifdef X11_t 94773143b9aSmrg char portbuf[PORTBUFSIZE]; 94873143b9aSmrg#endif 949fe567363Smrg 950fe567363Smrg prmsg (2, "SocketINETCreateListener(%s)\n", port); 95173143b9aSmrg 95273143b9aSmrg#ifdef X11_t 95373143b9aSmrg /* 95473143b9aSmrg * X has a well known port, that is transport dependent. It is easier 95573143b9aSmrg * to handle it here, than try and come up with a transport independent 95673143b9aSmrg * representation that can be passed in and resolved the usual way. 95773143b9aSmrg * 95873143b9aSmrg * The port that is passed here is really a string containing the idisplay 95973143b9aSmrg * from ConnectDisplay(). 96073143b9aSmrg */ 96173143b9aSmrg 96273143b9aSmrg if (is_numeric (port)) 96373143b9aSmrg { 96473143b9aSmrg /* fixup the server port address */ 96573143b9aSmrg tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); 966fe567363Smrg snprintf (portbuf, sizeof(portbuf), "%lu", tmpport); 96773143b9aSmrg port = portbuf; 96873143b9aSmrg } 96973143b9aSmrg#endif 97073143b9aSmrg 97173143b9aSmrg if (port && *port) 97273143b9aSmrg { 97373143b9aSmrg /* Check to see if the port string is just a number (handles X11) */ 97473143b9aSmrg 97573143b9aSmrg if (!is_numeric (port)) 97673143b9aSmrg { 97773143b9aSmrg if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) 97873143b9aSmrg { 979fe567363Smrg prmsg (1, 98073143b9aSmrg "SocketINETCreateListener: Unable to get service for %s\n", 981fe567363Smrg port); 98273143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 98373143b9aSmrg } 98473143b9aSmrg /* we trust getservbyname to return a valid number */ 98573143b9aSmrg sport = servp->s_port; 98673143b9aSmrg } 98773143b9aSmrg else 98873143b9aSmrg { 98973143b9aSmrg tmpport = strtol (port, (char**)NULL, 10); 990fe567363Smrg /* 99173143b9aSmrg * check that somehow the port address isn't negative or in 99273143b9aSmrg * the range of reserved port addresses. This can happen and 993fe567363Smrg * be very bad if the server is suid-root and the user does 994fe567363Smrg * something (dumb) like `X :60049`. 99573143b9aSmrg */ 99673143b9aSmrg if (tmpport < 1024 || tmpport > USHRT_MAX) 99773143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 99873143b9aSmrg 99973143b9aSmrg sport = (unsigned short) tmpport; 100073143b9aSmrg } 100173143b9aSmrg } 100273143b9aSmrg else 100373143b9aSmrg sport = 0; 100473143b9aSmrg 100573143b9aSmrg bzero(&sockname, sizeof(sockname)); 100673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 100773143b9aSmrg if (Sockettrans2devtab[ciptr->index].family == AF_INET) { 100873143b9aSmrg namelen = sizeof (struct sockaddr_in); 100973143b9aSmrg#ifdef BSD44SOCKETS 101073143b9aSmrg ((struct sockaddr_in *)&sockname)->sin_len = namelen; 101173143b9aSmrg#endif 101273143b9aSmrg ((struct sockaddr_in *)&sockname)->sin_family = AF_INET; 101373143b9aSmrg ((struct sockaddr_in *)&sockname)->sin_port = htons(sport); 101473143b9aSmrg ((struct sockaddr_in *)&sockname)->sin_addr.s_addr = htonl(INADDR_ANY); 101573143b9aSmrg } else { 101673143b9aSmrg namelen = sizeof (struct sockaddr_in6); 101773143b9aSmrg#ifdef SIN6_LEN 101873143b9aSmrg ((struct sockaddr_in6 *)&sockname)->sin6_len = sizeof(sockname); 101973143b9aSmrg#endif 102073143b9aSmrg ((struct sockaddr_in6 *)&sockname)->sin6_family = AF_INET6; 102173143b9aSmrg ((struct sockaddr_in6 *)&sockname)->sin6_port = htons(sport); 102273143b9aSmrg ((struct sockaddr_in6 *)&sockname)->sin6_addr = in6addr_any; 102373143b9aSmrg } 102473143b9aSmrg#else 102573143b9aSmrg#ifdef BSD44SOCKETS 102673143b9aSmrg sockname.sin_len = sizeof (sockname); 102773143b9aSmrg#endif 102873143b9aSmrg sockname.sin_family = AF_INET; 102973143b9aSmrg sockname.sin_port = htons (sport); 103073143b9aSmrg sockname.sin_addr.s_addr = htonl (INADDR_ANY); 103173143b9aSmrg#endif 103273143b9aSmrg 103373143b9aSmrg if ((status = TRANS(SocketCreateListener) (ciptr, 103473143b9aSmrg (struct sockaddr *) &sockname, namelen, flags)) < 0) 103573143b9aSmrg { 1036fe567363Smrg prmsg (1, 1037fe567363Smrg "SocketINETCreateListener: ...SocketCreateListener() failed\n"); 103873143b9aSmrg return status; 103973143b9aSmrg } 104073143b9aSmrg 104173143b9aSmrg if (TRANS(SocketINETGetAddr) (ciptr) < 0) 104273143b9aSmrg { 1043fe567363Smrg prmsg (1, 1044fe567363Smrg "SocketINETCreateListener: ...SocketINETGetAddr() failed\n"); 104573143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 104673143b9aSmrg } 104773143b9aSmrg 104873143b9aSmrg return 0; 104973143b9aSmrg} 105073143b9aSmrg 105173143b9aSmrg#endif /* TCPCONN */ 105273143b9aSmrg 105373143b9aSmrg 105473143b9aSmrg#ifdef UNIXCONN 105573143b9aSmrg 105673143b9aSmrgstatic int 105773143b9aSmrgTRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, char *port, 105873143b9aSmrg unsigned int flags) 105973143b9aSmrg 106073143b9aSmrg{ 106173143b9aSmrg struct sockaddr_un sockname; 106273143b9aSmrg int namelen; 106373143b9aSmrg int oldUmask; 106473143b9aSmrg int status; 106573143b9aSmrg unsigned int mode; 106673143b9aSmrg char tmpport[108]; 106773143b9aSmrg 106873143b9aSmrg int abstract = 0; 106973143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 107073143b9aSmrg abstract = ciptr->transptr->flags & TRANS_ABSTRACT; 107173143b9aSmrg#endif 107273143b9aSmrg 1073fe567363Smrg prmsg (2, "SocketUNIXCreateListener(%s)\n", 1074fe567363Smrg port ? port : "NULL"); 107573143b9aSmrg 107673143b9aSmrg /* Make sure the directory is created */ 107773143b9aSmrg 107873143b9aSmrg oldUmask = umask (0); 107973143b9aSmrg 108073143b9aSmrg#ifdef UNIX_DIR 108173143b9aSmrg#ifdef HAS_STICKY_DIR_BIT 108273143b9aSmrg mode = 01777; 108373143b9aSmrg#else 108473143b9aSmrg mode = 0777; 108573143b9aSmrg#endif 10868d4c0f7bSmrg if (!abstract && trans_mkdir(UNIX_DIR, mode) == -1) { 1087fe567363Smrg prmsg (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n", 1088fe567363Smrg UNIX_DIR, errno); 108973143b9aSmrg (void) umask (oldUmask); 109073143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 109173143b9aSmrg } 109273143b9aSmrg#endif 109373143b9aSmrg 109473143b9aSmrg memset(&sockname, 0, sizeof(sockname)); 109573143b9aSmrg sockname.sun_family = AF_UNIX; 109673143b9aSmrg 109773143b9aSmrg if (!(port && *port)) { 109873143b9aSmrg snprintf (tmpport, sizeof(tmpport), "%s%ld", UNIX_PATH, (long)getpid()); 109973143b9aSmrg port = tmpport; 110073143b9aSmrg } 110173143b9aSmrg if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { 1102fe567363Smrg prmsg (1, "SocketUNIXCreateListener: path too long\n"); 110373143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 110473143b9aSmrg } 110573143b9aSmrg 1106fe567363Smrg#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) 110773143b9aSmrg sockname.sun_len = strlen(sockname.sun_path); 110873143b9aSmrg#endif 110973143b9aSmrg 111073143b9aSmrg#if defined(BSD44SOCKETS) || defined(SUN_LEN) 111173143b9aSmrg namelen = SUN_LEN(&sockname); 111273143b9aSmrg#else 111373143b9aSmrg namelen = strlen(sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); 111473143b9aSmrg#endif 111573143b9aSmrg 111673143b9aSmrg if (abstract) { 111773143b9aSmrg sockname.sun_path[0] = '\0'; 111873143b9aSmrg namelen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&sockname.sun_path[1]); 111973143b9aSmrg } 112073143b9aSmrg else 112173143b9aSmrg unlink (sockname.sun_path); 112273143b9aSmrg 112373143b9aSmrg if ((status = TRANS(SocketCreateListener) (ciptr, 112473143b9aSmrg (struct sockaddr *) &sockname, namelen, flags)) < 0) 112573143b9aSmrg { 1126fe567363Smrg prmsg (1, 1127fe567363Smrg "SocketUNIXCreateListener: ...SocketCreateListener() failed\n"); 112873143b9aSmrg (void) umask (oldUmask); 112973143b9aSmrg return status; 113073143b9aSmrg } 113173143b9aSmrg 113273143b9aSmrg /* 113373143b9aSmrg * Now that the listener is esablished, create the addr info for 113473143b9aSmrg * this connection. getpeername() doesn't work for UNIX Domain Sockets 113573143b9aSmrg * on some systems (hpux at least), so we will just do it manually, instead 113673143b9aSmrg * of calling something like TRANS(SocketUNIXGetAddr). 113773143b9aSmrg */ 113873143b9aSmrg 113973143b9aSmrg namelen = sizeof (sockname); /* this will always make it the same size */ 114073143b9aSmrg 1141fe567363Smrg if ((ciptr->addr = malloc (namelen)) == NULL) 114273143b9aSmrg { 1143fe567363Smrg prmsg (1, 1144fe567363Smrg "SocketUNIXCreateListener: Can't allocate space for the addr\n"); 114573143b9aSmrg (void) umask (oldUmask); 114673143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 114773143b9aSmrg } 114873143b9aSmrg 114973143b9aSmrg if (abstract) 115073143b9aSmrg sockname.sun_path[0] = '@'; 115173143b9aSmrg 115273143b9aSmrg ciptr->family = sockname.sun_family; 115373143b9aSmrg ciptr->addrlen = namelen; 115473143b9aSmrg memcpy (ciptr->addr, &sockname, ciptr->addrlen); 115573143b9aSmrg 115673143b9aSmrg (void) umask (oldUmask); 115773143b9aSmrg 115873143b9aSmrg return 0; 115973143b9aSmrg} 116073143b9aSmrg 116173143b9aSmrg 116273143b9aSmrgstatic int 116373143b9aSmrgTRANS(SocketUNIXResetListener) (XtransConnInfo ciptr) 116473143b9aSmrg 116573143b9aSmrg{ 116673143b9aSmrg /* 116773143b9aSmrg * See if the unix domain socket has disappeared. If it has, recreate it. 116873143b9aSmrg */ 116973143b9aSmrg 117073143b9aSmrg struct sockaddr_un *unsock = (struct sockaddr_un *) ciptr->addr; 117173143b9aSmrg struct stat statb; 117273143b9aSmrg int status = TRANS_RESET_NOOP; 117373143b9aSmrg unsigned int mode; 117473143b9aSmrg int abstract = 0; 117573143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 117673143b9aSmrg abstract = ciptr->transptr->flags & TRANS_ABSTRACT; 117773143b9aSmrg#endif 117873143b9aSmrg 1179fe567363Smrg prmsg (3, "SocketUNIXResetListener(%p,%d)\n", ciptr, ciptr->fd); 118073143b9aSmrg 118173143b9aSmrg if (!abstract && ( 118273143b9aSmrg stat (unsock->sun_path, &statb) == -1 || 118373143b9aSmrg ((statb.st_mode & S_IFMT) != 1184e8a71cdfSmrg#if defined(NCR) || defined(SCO325) || !defined(S_IFSOCK) 118573143b9aSmrg S_IFIFO 118673143b9aSmrg#else 118773143b9aSmrg S_IFSOCK 118873143b9aSmrg#endif 118973143b9aSmrg ))) 119073143b9aSmrg { 119173143b9aSmrg int oldUmask = umask (0); 119273143b9aSmrg 119373143b9aSmrg#ifdef UNIX_DIR 119473143b9aSmrg#ifdef HAS_STICKY_DIR_BIT 119573143b9aSmrg mode = 01777; 119673143b9aSmrg#else 119773143b9aSmrg mode = 0777; 119873143b9aSmrg#endif 119973143b9aSmrg if (trans_mkdir(UNIX_DIR, mode) == -1) { 1200fe567363Smrg prmsg (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n", 1201fe567363Smrg UNIX_DIR, errno); 120273143b9aSmrg (void) umask (oldUmask); 120373143b9aSmrg return TRANS_RESET_FAILURE; 120473143b9aSmrg } 120573143b9aSmrg#endif 120673143b9aSmrg 120773143b9aSmrg close (ciptr->fd); 120873143b9aSmrg unlink (unsock->sun_path); 120973143b9aSmrg 121073143b9aSmrg if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) 121173143b9aSmrg { 121273143b9aSmrg TRANS(FreeConnInfo) (ciptr); 121373143b9aSmrg (void) umask (oldUmask); 121473143b9aSmrg return TRANS_RESET_FAILURE; 121573143b9aSmrg } 121673143b9aSmrg 121773143b9aSmrg if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0) 121873143b9aSmrg { 121973143b9aSmrg close (ciptr->fd); 122073143b9aSmrg TRANS(FreeConnInfo) (ciptr); 122173143b9aSmrg return TRANS_RESET_FAILURE; 122273143b9aSmrg } 122373143b9aSmrg 122473143b9aSmrg if (listen (ciptr->fd, BACKLOG) < 0) 122573143b9aSmrg { 122673143b9aSmrg close (ciptr->fd); 122773143b9aSmrg TRANS(FreeConnInfo) (ciptr); 122873143b9aSmrg (void) umask (oldUmask); 122973143b9aSmrg return TRANS_RESET_FAILURE; 123073143b9aSmrg } 123173143b9aSmrg 123273143b9aSmrg umask (oldUmask); 123373143b9aSmrg 123473143b9aSmrg status = TRANS_RESET_NEW_FD; 123573143b9aSmrg } 123673143b9aSmrg 123773143b9aSmrg return status; 123873143b9aSmrg} 123973143b9aSmrg 124073143b9aSmrg#endif /* UNIXCONN */ 124173143b9aSmrg 124273143b9aSmrg 124373143b9aSmrg#ifdef TCPCONN 124473143b9aSmrg 124573143b9aSmrgstatic XtransConnInfo 124673143b9aSmrgTRANS(SocketINETAccept) (XtransConnInfo ciptr, int *status) 124773143b9aSmrg 124873143b9aSmrg{ 124973143b9aSmrg XtransConnInfo newciptr; 125073143b9aSmrg struct sockaddr_in sockname; 125173143b9aSmrg SOCKLEN_T namelen = sizeof(sockname); 125273143b9aSmrg 1253fe567363Smrg prmsg (2, "SocketINETAccept(%p,%d)\n", ciptr, ciptr->fd); 125473143b9aSmrg 1255fe567363Smrg if ((newciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL) 125673143b9aSmrg { 1257fe567363Smrg prmsg (1, "SocketINETAccept: malloc failed\n"); 125873143b9aSmrg *status = TRANS_ACCEPT_BAD_MALLOC; 125973143b9aSmrg return NULL; 126073143b9aSmrg } 126173143b9aSmrg 126273143b9aSmrg if ((newciptr->fd = accept (ciptr->fd, 126373143b9aSmrg (struct sockaddr *) &sockname, (void *)&namelen)) < 0) 126473143b9aSmrg { 126573143b9aSmrg#ifdef WIN32 126673143b9aSmrg errno = WSAGetLastError(); 126773143b9aSmrg#endif 1268fe567363Smrg prmsg (1, "SocketINETAccept: accept() failed\n"); 1269fe567363Smrg free (newciptr); 127073143b9aSmrg *status = TRANS_ACCEPT_FAILED; 127173143b9aSmrg return NULL; 127273143b9aSmrg } 127373143b9aSmrg 127473143b9aSmrg#ifdef TCP_NODELAY 127573143b9aSmrg { 127673143b9aSmrg /* 127773143b9aSmrg * turn off TCP coalescence for INET sockets 127873143b9aSmrg */ 127973143b9aSmrg 128073143b9aSmrg int tmp = 1; 128173143b9aSmrg setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY, 128273143b9aSmrg (char *) &tmp, sizeof (int)); 128373143b9aSmrg } 128473143b9aSmrg#endif 128573143b9aSmrg 128673143b9aSmrg /* 1287fe567363Smrg * Get this address again because the transport may give a more 128873143b9aSmrg * specific address now that a connection is established. 128973143b9aSmrg */ 129073143b9aSmrg 129173143b9aSmrg if (TRANS(SocketINETGetAddr) (newciptr) < 0) 129273143b9aSmrg { 1293fe567363Smrg prmsg (1, 1294fe567363Smrg "SocketINETAccept: ...SocketINETGetAddr() failed:\n"); 129573143b9aSmrg close (newciptr->fd); 1296fe567363Smrg free (newciptr); 129773143b9aSmrg *status = TRANS_ACCEPT_MISC_ERROR; 129873143b9aSmrg return NULL; 129973143b9aSmrg } 130073143b9aSmrg 130173143b9aSmrg if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0) 130273143b9aSmrg { 1303fe567363Smrg prmsg (1, 1304fe567363Smrg "SocketINETAccept: ...SocketINETGetPeerAddr() failed:\n"); 130573143b9aSmrg close (newciptr->fd); 1306fe567363Smrg if (newciptr->addr) free (newciptr->addr); 1307fe567363Smrg free (newciptr); 130873143b9aSmrg *status = TRANS_ACCEPT_MISC_ERROR; 130973143b9aSmrg return NULL; 131073143b9aSmrg } 131173143b9aSmrg 131273143b9aSmrg *status = 0; 131373143b9aSmrg 131473143b9aSmrg return newciptr; 131573143b9aSmrg} 131673143b9aSmrg 131773143b9aSmrg#endif /* TCPCONN */ 131873143b9aSmrg 131973143b9aSmrg 132073143b9aSmrg#ifdef UNIXCONN 132173143b9aSmrgstatic XtransConnInfo 132273143b9aSmrgTRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) 132373143b9aSmrg 132473143b9aSmrg{ 132573143b9aSmrg XtransConnInfo newciptr; 132673143b9aSmrg struct sockaddr_un sockname; 132773143b9aSmrg SOCKLEN_T namelen = sizeof sockname; 132873143b9aSmrg 1329fe567363Smrg prmsg (2, "SocketUNIXAccept(%p,%d)\n", ciptr, ciptr->fd); 133073143b9aSmrg 1331fe567363Smrg if ((newciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL) 133273143b9aSmrg { 1333fe567363Smrg prmsg (1, "SocketUNIXAccept: malloc() failed\n"); 133473143b9aSmrg *status = TRANS_ACCEPT_BAD_MALLOC; 133573143b9aSmrg return NULL; 133673143b9aSmrg } 133773143b9aSmrg 133873143b9aSmrg if ((newciptr->fd = accept (ciptr->fd, 133973143b9aSmrg (struct sockaddr *) &sockname, (void *)&namelen)) < 0) 134073143b9aSmrg { 1341fe567363Smrg prmsg (1, "SocketUNIXAccept: accept() failed\n"); 1342fe567363Smrg free (newciptr); 134373143b9aSmrg *status = TRANS_ACCEPT_FAILED; 134473143b9aSmrg return NULL; 134573143b9aSmrg } 134673143b9aSmrg 134773143b9aSmrg ciptr->addrlen = namelen; 134873143b9aSmrg /* 134973143b9aSmrg * Get the socket name and the peer name from the listener socket, 135073143b9aSmrg * since this is unix domain. 135173143b9aSmrg */ 135273143b9aSmrg 1353fe567363Smrg if ((newciptr->addr = malloc (ciptr->addrlen)) == NULL) 135473143b9aSmrg { 1355fe567363Smrg prmsg (1, 1356fe567363Smrg "SocketUNIXAccept: Can't allocate space for the addr\n"); 135773143b9aSmrg close (newciptr->fd); 1358fe567363Smrg free (newciptr); 135973143b9aSmrg *status = TRANS_ACCEPT_BAD_MALLOC; 136073143b9aSmrg return NULL; 136173143b9aSmrg } 136273143b9aSmrg 136373143b9aSmrg /* 136473143b9aSmrg * if the socket is abstract, we already modified the address to have a 136573143b9aSmrg * @ instead of the initial NUL, so no need to do that again here. 136673143b9aSmrg */ 136773143b9aSmrg 136873143b9aSmrg newciptr->addrlen = ciptr->addrlen; 136973143b9aSmrg memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen); 137073143b9aSmrg 1371fe567363Smrg if ((newciptr->peeraddr = malloc (ciptr->addrlen)) == NULL) 137273143b9aSmrg { 1373fe567363Smrg prmsg (1, 1374fe567363Smrg "SocketUNIXAccept: Can't allocate space for the addr\n"); 137573143b9aSmrg close (newciptr->fd); 1376fe567363Smrg if (newciptr->addr) free (newciptr->addr); 1377fe567363Smrg free (newciptr); 137873143b9aSmrg *status = TRANS_ACCEPT_BAD_MALLOC; 137973143b9aSmrg return NULL; 138073143b9aSmrg } 1381fe567363Smrg 138273143b9aSmrg newciptr->peeraddrlen = ciptr->addrlen; 138373143b9aSmrg memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen); 138473143b9aSmrg 138573143b9aSmrg newciptr->family = AF_UNIX; 138673143b9aSmrg 138773143b9aSmrg *status = 0; 138873143b9aSmrg 138973143b9aSmrg return newciptr; 139073143b9aSmrg} 139173143b9aSmrg 139273143b9aSmrg#endif /* UNIXCONN */ 139373143b9aSmrg 139473143b9aSmrg#endif /* TRANS_SERVER */ 139573143b9aSmrg 139673143b9aSmrg 139773143b9aSmrg#ifdef TRANS_CLIENT 139873143b9aSmrg 139973143b9aSmrg#ifdef TCPCONN 140073143b9aSmrg 140173143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 140273143b9aSmrgstruct addrlist { 140373143b9aSmrg struct addrinfo * addr; 1404fe567363Smrg struct addrinfo * firstaddr; 140573143b9aSmrg char port[PORTBUFSIZE]; 140673143b9aSmrg char host[MAXHOSTNAMELEN]; 140773143b9aSmrg}; 140873143b9aSmrgstatic struct addrlist *addrlist = NULL; 140973143b9aSmrg#endif 141073143b9aSmrg 141173143b9aSmrg 141273143b9aSmrgstatic int 141373143b9aSmrgTRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) 141473143b9aSmrg 141573143b9aSmrg{ 141673143b9aSmrg struct sockaddr * socketaddr = NULL; 141773143b9aSmrg int socketaddrlen = 0; 141873143b9aSmrg int res; 141973143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 142073143b9aSmrg struct addrinfo hints; 142173143b9aSmrg char ntopbuf[INET6_ADDRSTRLEN]; 142273143b9aSmrg int resetonce = 0; 1423fe567363Smrg#else 142473143b9aSmrg struct sockaddr_in sockname; 1425fe567363Smrg struct hostent *hostp; 1426fe567363Smrg struct servent *servp; 1427fe567363Smrg unsigned long tmpaddr; 1428fe567363Smrg#endif 142973143b9aSmrg#ifdef XTHREADS_NEEDS_BYNAMEPARAMS 143073143b9aSmrg _Xgethostbynameparams hparams; 143173143b9aSmrg _Xgetservbynameparams sparams; 143273143b9aSmrg#endif 143373143b9aSmrg#ifdef X11_t 143473143b9aSmrg char portbuf[PORTBUFSIZE]; 143573143b9aSmrg#endif 143673143b9aSmrg 143773143b9aSmrg char hostnamebuf[256]; /* tmp space */ 143873143b9aSmrg 1439fe567363Smrg prmsg (2,"SocketINETConnect(%d,%s,%s)\n", ciptr->fd, host, port); 144073143b9aSmrg 144173143b9aSmrg if (!host) 144273143b9aSmrg { 144373143b9aSmrg hostnamebuf[0] = '\0'; 144473143b9aSmrg (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf); 144573143b9aSmrg host = hostnamebuf; 144673143b9aSmrg } 144773143b9aSmrg 144873143b9aSmrg#ifdef X11_t 144973143b9aSmrg /* 145073143b9aSmrg * X has a well known port, that is transport dependent. It is easier 145173143b9aSmrg * to handle it here, than try and come up with a transport independent 145273143b9aSmrg * representation that can be passed in and resolved the usual way. 145373143b9aSmrg * 145473143b9aSmrg * The port that is passed here is really a string containing the idisplay 145573143b9aSmrg * from ConnectDisplay(). 145673143b9aSmrg */ 145773143b9aSmrg 145873143b9aSmrg if (is_numeric (port)) 145973143b9aSmrg { 1460fe567363Smrg long tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); 1461fe567363Smrg snprintf (portbuf, sizeof(portbuf), "%lu", tmpport); 146273143b9aSmrg port = portbuf; 146373143b9aSmrg } 146473143b9aSmrg#endif 146573143b9aSmrg 146673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 1467b53e5eeaSmrg { 146873143b9aSmrg if (addrlist != NULL) { 146973143b9aSmrg if (strcmp(host,addrlist->host) || strcmp(port,addrlist->port)) { 147073143b9aSmrg if (addrlist->firstaddr) 147173143b9aSmrg freeaddrinfo(addrlist->firstaddr); 147273143b9aSmrg addrlist->firstaddr = NULL; 147373143b9aSmrg } 147473143b9aSmrg } else { 147573143b9aSmrg addrlist = malloc(sizeof(struct addrlist)); 147673143b9aSmrg addrlist->firstaddr = NULL; 147773143b9aSmrg } 147873143b9aSmrg 147973143b9aSmrg if (addrlist->firstaddr == NULL) { 148073143b9aSmrg strncpy(addrlist->port, port, sizeof(addrlist->port)); 148173143b9aSmrg addrlist->port[sizeof(addrlist->port) - 1] = '\0'; 148273143b9aSmrg strncpy(addrlist->host, host, sizeof(addrlist->host)); 148373143b9aSmrg addrlist->host[sizeof(addrlist->host) - 1] = '\0'; 148473143b9aSmrg 148573143b9aSmrg bzero(&hints,sizeof(hints)); 148673143b9aSmrg hints.ai_socktype = Sockettrans2devtab[ciptr->index].devcotsname; 148773143b9aSmrg 148873143b9aSmrg res = getaddrinfo(host,port,&hints,&addrlist->firstaddr); 148973143b9aSmrg if (res != 0) { 1490fe567363Smrg prmsg (1, "SocketINETConnect() can't get address " 149173143b9aSmrg "for %s:%s: %s\n", host, port, gai_strerror(res)); 149273143b9aSmrg ESET(EINVAL); 149373143b9aSmrg return TRANS_CONNECT_FAILED; 149473143b9aSmrg } 149573143b9aSmrg for (res = 0, addrlist->addr = addrlist->firstaddr; 149673143b9aSmrg addrlist->addr ; res++) { 149773143b9aSmrg addrlist->addr = addrlist->addr->ai_next; 149873143b9aSmrg } 1499fe567363Smrg prmsg(4,"Got New Address list with %d addresses\n", res); 150073143b9aSmrg res = 0; 150173143b9aSmrg addrlist->addr = NULL; 150273143b9aSmrg } 150373143b9aSmrg 150473143b9aSmrg while (socketaddr == NULL) { 150573143b9aSmrg if (addrlist->addr == NULL) { 1506fe567363Smrg if (resetonce) { 150773143b9aSmrg /* Already checked entire list - no usable addresses */ 1508fe567363Smrg prmsg (1, "SocketINETConnect() no usable address " 1509fe567363Smrg "for %s:%s\n", host, port); 151073143b9aSmrg return TRANS_CONNECT_FAILED; 151173143b9aSmrg } else { 151273143b9aSmrg /* Go back to beginning of list */ 151373143b9aSmrg resetonce = 1; 151473143b9aSmrg addrlist->addr = addrlist->firstaddr; 151573143b9aSmrg } 1516fe567363Smrg } 151773143b9aSmrg 151873143b9aSmrg socketaddr = addrlist->addr->ai_addr; 151973143b9aSmrg socketaddrlen = addrlist->addr->ai_addrlen; 152073143b9aSmrg 152173143b9aSmrg if (addrlist->addr->ai_family == AF_INET) { 152273143b9aSmrg struct sockaddr_in *sin = (struct sockaddr_in *) socketaddr; 152373143b9aSmrg 1524fe567363Smrg prmsg (4,"SocketINETConnect() sockname.sin_addr = %s\n", 152573143b9aSmrg inet_ntop(addrlist->addr->ai_family,&sin->sin_addr, 1526fe567363Smrg ntopbuf,sizeof(ntopbuf))); 152773143b9aSmrg 1528fe567363Smrg prmsg (4,"SocketINETConnect() sockname.sin_port = %d\n", 1529fe567363Smrg ntohs(sin->sin_port)); 153073143b9aSmrg 153173143b9aSmrg if (Sockettrans2devtab[ciptr->index].family == AF_INET6) { 153273143b9aSmrg if (strcmp(Sockettrans2devtab[ciptr->index].transname, 153373143b9aSmrg "tcp") == 0) { 153473143b9aSmrg XtransConnInfo newciptr; 153573143b9aSmrg 153673143b9aSmrg /* 153773143b9aSmrg * Our socket is an IPv6 socket, but the address is 153873143b9aSmrg * IPv4. Close it and get an IPv4 socket. This is 153973143b9aSmrg * needed for IPv4 connections to work on platforms 154073143b9aSmrg * that don't allow IPv4 over IPv6 sockets. 154173143b9aSmrg */ 154273143b9aSmrg TRANS(SocketINETClose)(ciptr); 154373143b9aSmrg newciptr = TRANS(SocketOpenCOTSClientBase)( 154473143b9aSmrg "tcp", "tcp", host, port, ciptr->index); 154573143b9aSmrg if (newciptr) 154673143b9aSmrg ciptr->fd = newciptr->fd; 154773143b9aSmrg if (!newciptr || 154873143b9aSmrg Sockettrans2devtab[newciptr->index].family != 154973143b9aSmrg AF_INET) { 155073143b9aSmrg socketaddr = NULL; 1551fe567363Smrg prmsg (4,"SocketINETConnect() Cannot get IPv4 " 1552fe567363Smrg " socketfor IPv4 address\n"); 155373143b9aSmrg } 155473143b9aSmrg if (newciptr) 1555fe567363Smrg free(newciptr); 155673143b9aSmrg } else { 155773143b9aSmrg socketaddr = NULL; 1558fe567363Smrg prmsg (4,"SocketINETConnect Skipping IPv4 address\n"); 155973143b9aSmrg } 156073143b9aSmrg } 156173143b9aSmrg } else if (addrlist->addr->ai_family == AF_INET6) { 156273143b9aSmrg struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) socketaddr; 1563fe567363Smrg 1564fe567363Smrg prmsg (4,"SocketINETConnect() sockname.sin6_addr = %s\n", 156573143b9aSmrg inet_ntop(addrlist->addr->ai_family, 1566fe567363Smrg &sin6->sin6_addr,ntopbuf,sizeof(ntopbuf))); 1567fe567363Smrg prmsg (4,"SocketINETConnect() sockname.sin6_port = %d\n", 1568fe567363Smrg ntohs(sin6->sin6_port)); 156973143b9aSmrg 157073143b9aSmrg if (Sockettrans2devtab[ciptr->index].family == AF_INET) { 157173143b9aSmrg if (strcmp(Sockettrans2devtab[ciptr->index].transname, 157273143b9aSmrg "tcp") == 0) { 157373143b9aSmrg XtransConnInfo newciptr; 157473143b9aSmrg 157573143b9aSmrg /* 157673143b9aSmrg * Close the IPv4 socket and try to open an IPv6 socket. 157773143b9aSmrg */ 157873143b9aSmrg TRANS(SocketINETClose)(ciptr); 157973143b9aSmrg newciptr = TRANS(SocketOpenCOTSClientBase)( 158073143b9aSmrg "tcp", "tcp", host, port, -1); 158173143b9aSmrg if (newciptr) 158273143b9aSmrg ciptr->fd = newciptr->fd; 158373143b9aSmrg if (!newciptr || 158473143b9aSmrg Sockettrans2devtab[newciptr->index].family != 158573143b9aSmrg AF_INET6) { 158673143b9aSmrg socketaddr = NULL; 1587fe567363Smrg prmsg (4,"SocketINETConnect() Cannot get IPv6 " 1588fe567363Smrg "socket for IPv6 address\n"); 158973143b9aSmrg } 159073143b9aSmrg if (newciptr) 1591fe567363Smrg free(newciptr); 159273143b9aSmrg } 159373143b9aSmrg else 159473143b9aSmrg { 159573143b9aSmrg socketaddr = NULL; 1596fe567363Smrg prmsg (4,"SocketINETConnect() Skipping IPv6 address\n"); 159773143b9aSmrg } 159873143b9aSmrg } 159973143b9aSmrg } else { 160073143b9aSmrg socketaddr = NULL; /* Unsupported address type */ 160173143b9aSmrg } 160273143b9aSmrg if (socketaddr == NULL) { 160373143b9aSmrg addrlist->addr = addrlist->addr->ai_next; 160473143b9aSmrg } 1605fe567363Smrg } 1606b53e5eeaSmrg } 1607b53e5eeaSmrg#else 160873143b9aSmrg { 160973143b9aSmrg /* 161073143b9aSmrg * Build the socket name. 161173143b9aSmrg */ 161273143b9aSmrg 161373143b9aSmrg#ifdef BSD44SOCKETS 161473143b9aSmrg sockname.sin_len = sizeof (struct sockaddr_in); 161573143b9aSmrg#endif 161673143b9aSmrg sockname.sin_family = AF_INET; 161773143b9aSmrg 161873143b9aSmrg /* 161973143b9aSmrg * fill in sin_addr 162073143b9aSmrg */ 162173143b9aSmrg 162273143b9aSmrg#ifndef INADDR_NONE 162373143b9aSmrg#define INADDR_NONE ((in_addr_t) 0xffffffff) 162473143b9aSmrg#endif 162573143b9aSmrg 162673143b9aSmrg /* check for ww.xx.yy.zz host string */ 162773143b9aSmrg 162873143b9aSmrg if (isascii (host[0]) && isdigit (host[0])) { 162973143b9aSmrg tmpaddr = inet_addr (host); /* returns network byte order */ 163073143b9aSmrg } else { 163173143b9aSmrg tmpaddr = INADDR_NONE; 163273143b9aSmrg } 163373143b9aSmrg 1634fe567363Smrg prmsg (4,"SocketINETConnect() inet_addr(%s) = %x\n", host, tmpaddr); 163573143b9aSmrg 163673143b9aSmrg if (tmpaddr == INADDR_NONE) { 163773143b9aSmrg if ((hostp = _XGethostbyname(host,hparams)) == NULL) { 1638fe567363Smrg prmsg (1,"SocketINETConnect: Can't get address for %s\n", 1639fe567363Smrg host); 164073143b9aSmrg ESET(EINVAL); 164173143b9aSmrg return TRANS_CONNECT_FAILED; 164273143b9aSmrg } 164373143b9aSmrg if (hostp->h_addrtype != AF_INET) { /* is IP host? */ 1644fe567363Smrg prmsg (1,"SocketINETConnect: not INET host%s\n", host); 164573143b9aSmrg ESET(EPROTOTYPE); 164673143b9aSmrg return TRANS_CONNECT_FAILED; 164773143b9aSmrg } 1648fe567363Smrg 164973143b9aSmrg memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr, 165073143b9aSmrg sizeof (sockname.sin_addr)); 165173143b9aSmrg 165273143b9aSmrg } else { 165373143b9aSmrg sockname.sin_addr.s_addr = tmpaddr; 165473143b9aSmrg } 165573143b9aSmrg 165673143b9aSmrg /* 165773143b9aSmrg * fill in sin_port 165873143b9aSmrg */ 165973143b9aSmrg 166073143b9aSmrg /* Check for number in the port string */ 166173143b9aSmrg 166273143b9aSmrg if (!is_numeric (port)) { 166373143b9aSmrg if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) { 1664fe567363Smrg prmsg (1,"SocketINETConnect: can't get service for %s\n", 1665fe567363Smrg port); 166673143b9aSmrg return TRANS_CONNECT_FAILED; 166773143b9aSmrg } 166873143b9aSmrg sockname.sin_port = htons (servp->s_port); 166973143b9aSmrg } else { 1670fe567363Smrg long tmpport = strtol (port, (char**)NULL, 10); 167173143b9aSmrg if (tmpport < 1024 || tmpport > USHRT_MAX) 167273143b9aSmrg return TRANS_CONNECT_FAILED; 167373143b9aSmrg sockname.sin_port = htons (((unsigned short) tmpport)); 167473143b9aSmrg } 167573143b9aSmrg 1676fe567363Smrg prmsg (4,"SocketINETConnect: sockname.sin_port = %d\n", 1677fe567363Smrg ntohs(sockname.sin_port)); 167873143b9aSmrg socketaddr = (struct sockaddr *) &sockname; 167973143b9aSmrg socketaddrlen = sizeof(sockname); 168073143b9aSmrg } 1681b53e5eeaSmrg#endif 168273143b9aSmrg 168373143b9aSmrg /* 168473143b9aSmrg * Turn on socket keepalive so the client process will eventually 168573143b9aSmrg * be notified with a SIGPIPE signal if the display server fails 168673143b9aSmrg * to respond to a periodic transmission of messages 168773143b9aSmrg * on the connected socket. 168873143b9aSmrg * This is useful to avoid hung application processes when the 168973143b9aSmrg * processes are not spawned from the xdm session and 169073143b9aSmrg * the display server terminates abnormally. 169173143b9aSmrg * (Someone turned off the power switch.) 169273143b9aSmrg */ 169373143b9aSmrg 169473143b9aSmrg { 169573143b9aSmrg int tmp = 1; 169673143b9aSmrg setsockopt (ciptr->fd, SOL_SOCKET, SO_KEEPALIVE, 169773143b9aSmrg (char *) &tmp, sizeof (int)); 169873143b9aSmrg } 169973143b9aSmrg 170073143b9aSmrg /* 170173143b9aSmrg * Do the connect() 170273143b9aSmrg */ 170373143b9aSmrg 170473143b9aSmrg if (connect (ciptr->fd, socketaddr, socketaddrlen ) < 0) 170573143b9aSmrg { 170673143b9aSmrg#ifdef WIN32 170773143b9aSmrg int olderrno = WSAGetLastError(); 170873143b9aSmrg#else 170973143b9aSmrg int olderrno = errno; 171073143b9aSmrg#endif 171173143b9aSmrg 171273143b9aSmrg /* 171373143b9aSmrg * If the error was ECONNREFUSED, the server may be overloaded 171473143b9aSmrg * and we should try again. 171573143b9aSmrg * 171673143b9aSmrg * If the error was EWOULDBLOCK or EINPROGRESS then the socket 171773143b9aSmrg * was non-blocking and we should poll using select 171873143b9aSmrg * 171973143b9aSmrg * If the error was EINTR, the connect was interrupted and we 172073143b9aSmrg * should try again. 172173143b9aSmrg * 172273143b9aSmrg * If multiple addresses are found for a host then we should 172373143b9aSmrg * try to connect again with a different address for a larger 172473143b9aSmrg * number of errors that made us quit before, since those 172573143b9aSmrg * could be caused by trying to use an IPv6 address to contact 172673143b9aSmrg * a machine with an IPv4-only server or other reasons that 1727fe567363Smrg * only affect one of a set of addresses. 172873143b9aSmrg */ 172973143b9aSmrg 173073143b9aSmrg if (olderrno == ECONNREFUSED || olderrno == EINTR 173173143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 1732b53e5eeaSmrg || (((addrlist->addr->ai_next != NULL) || 173373143b9aSmrg (addrlist->addr != addrlist->firstaddr)) && 173473143b9aSmrg (olderrno == ENETUNREACH || olderrno == EAFNOSUPPORT || 173573143b9aSmrg olderrno == EADDRNOTAVAIL || olderrno == ETIMEDOUT 173673143b9aSmrg#if defined(EHOSTDOWN) 173773143b9aSmrg || olderrno == EHOSTDOWN 173873143b9aSmrg#endif 173973143b9aSmrg )) 174073143b9aSmrg#endif 174173143b9aSmrg ) 174273143b9aSmrg res = TRANS_TRY_CONNECT_AGAIN; 174373143b9aSmrg else if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS) 174473143b9aSmrg res = TRANS_IN_PROGRESS; 174573143b9aSmrg else 174673143b9aSmrg { 1747fe567363Smrg prmsg (2,"SocketINETConnect: Can't connect: errno = %d\n", 1748fe567363Smrg olderrno); 174973143b9aSmrg 1750fe567363Smrg res = TRANS_CONNECT_FAILED; 175173143b9aSmrg } 175273143b9aSmrg } else { 175373143b9aSmrg res = 0; 1754fe567363Smrg 175573143b9aSmrg 175673143b9aSmrg /* 175773143b9aSmrg * Sync up the address fields of ciptr. 175873143b9aSmrg */ 1759fe567363Smrg 176073143b9aSmrg if (TRANS(SocketINETGetAddr) (ciptr) < 0) 176173143b9aSmrg { 1762fe567363Smrg prmsg (1, 1763fe567363Smrg "SocketINETConnect: ...SocketINETGetAddr() failed:\n"); 176473143b9aSmrg res = TRANS_CONNECT_FAILED; 176573143b9aSmrg } 176673143b9aSmrg 176773143b9aSmrg else if (TRANS(SocketINETGetPeerAddr) (ciptr) < 0) 176873143b9aSmrg { 1769fe567363Smrg prmsg (1, 1770fe567363Smrg "SocketINETConnect: ...SocketINETGetPeerAddr() failed:\n"); 177173143b9aSmrg res = TRANS_CONNECT_FAILED; 177273143b9aSmrg } 177373143b9aSmrg } 177473143b9aSmrg 177573143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 1776b53e5eeaSmrg if (res != 0) { 177773143b9aSmrg addrlist->addr = addrlist->addr->ai_next; 177873143b9aSmrg } 177973143b9aSmrg#endif 178073143b9aSmrg 178173143b9aSmrg return res; 178273143b9aSmrg} 178373143b9aSmrg 178473143b9aSmrg#endif /* TCPCONN */ 178573143b9aSmrg 178673143b9aSmrg 178773143b9aSmrg 178873143b9aSmrg#ifdef UNIXCONN 178973143b9aSmrg 179073143b9aSmrg/* 179173143b9aSmrg * Make sure 'host' is really local. 179273143b9aSmrg */ 179373143b9aSmrg 179473143b9aSmrgstatic int 179573143b9aSmrgUnixHostReallyLocal (char *host) 179673143b9aSmrg 179773143b9aSmrg{ 179873143b9aSmrg char hostnamebuf[256]; 179973143b9aSmrg 180073143b9aSmrg TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf)); 180173143b9aSmrg 180273143b9aSmrg if (strcmp (hostnamebuf, host) == 0) 180373143b9aSmrg { 180473143b9aSmrg return (1); 1805b53e5eeaSmrg } else { 180673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 180773143b9aSmrg struct addrinfo *localhostaddr; 180873143b9aSmrg struct addrinfo *otherhostaddr; 180973143b9aSmrg struct addrinfo *i, *j; 181073143b9aSmrg int equiv = 0; 181173143b9aSmrg 181273143b9aSmrg if (getaddrinfo(hostnamebuf, NULL, NULL, &localhostaddr) != 0) 181373143b9aSmrg return 0; 181473143b9aSmrg if (getaddrinfo(host, NULL, NULL, &otherhostaddr) != 0) { 181573143b9aSmrg freeaddrinfo(localhostaddr); 181673143b9aSmrg return 0; 181773143b9aSmrg } 181873143b9aSmrg 181973143b9aSmrg for (i = localhostaddr; i != NULL && equiv == 0; i = i->ai_next) { 182073143b9aSmrg for (j = otherhostaddr; j != NULL && equiv == 0; j = j->ai_next) { 182173143b9aSmrg if (i->ai_family == j->ai_family) { 182273143b9aSmrg if (i->ai_family == AF_INET) { 1823fe567363Smrg struct sockaddr_in *sinA 182473143b9aSmrg = (struct sockaddr_in *) i->ai_addr; 182573143b9aSmrg struct sockaddr_in *sinB 182673143b9aSmrg = (struct sockaddr_in *) j->ai_addr; 182773143b9aSmrg struct in_addr *A = &sinA->sin_addr; 182873143b9aSmrg struct in_addr *B = &sinB->sin_addr; 182973143b9aSmrg 183073143b9aSmrg if (memcmp(A,B,sizeof(struct in_addr)) == 0) { 183173143b9aSmrg equiv = 1; 183273143b9aSmrg } 183373143b9aSmrg } else if (i->ai_family == AF_INET6) { 1834fe567363Smrg struct sockaddr_in6 *sinA 183573143b9aSmrg = (struct sockaddr_in6 *) i->ai_addr; 1836fe567363Smrg struct sockaddr_in6 *sinB 183773143b9aSmrg = (struct sockaddr_in6 *) j->ai_addr; 183873143b9aSmrg struct in6_addr *A = &sinA->sin6_addr; 183973143b9aSmrg struct in6_addr *B = &sinB->sin6_addr; 184073143b9aSmrg 184173143b9aSmrg if (memcmp(A,B,sizeof(struct in6_addr)) == 0) { 184273143b9aSmrg equiv = 1; 184373143b9aSmrg } 184473143b9aSmrg } 184573143b9aSmrg } 184673143b9aSmrg } 184773143b9aSmrg } 1848fe567363Smrg 184973143b9aSmrg freeaddrinfo(localhostaddr); 185073143b9aSmrg freeaddrinfo(otherhostaddr); 185173143b9aSmrg return equiv; 1852b53e5eeaSmrg#else 185373143b9aSmrg /* 185473143b9aSmrg * A host may have more than one network address. If any of the 185573143b9aSmrg * network addresses of 'host' (specified to the connect call) 185673143b9aSmrg * match any of the network addresses of 'hostname' (determined 185773143b9aSmrg * by TRANS(GetHostname)), then the two hostnames are equivalent, 185873143b9aSmrg * and we know that 'host' is really a local host. 185973143b9aSmrg */ 186073143b9aSmrg char specified_local_addr_list[10][4]; 186173143b9aSmrg int scount, equiv, i, j; 186273143b9aSmrg#ifdef XTHREADS_NEEDS_BYNAMEPARAMS 186373143b9aSmrg _Xgethostbynameparams hparams; 186473143b9aSmrg#endif 186573143b9aSmrg struct hostent *hostp; 186673143b9aSmrg 186773143b9aSmrg if ((hostp = _XGethostbyname (host,hparams)) == NULL) 186873143b9aSmrg return (0); 186973143b9aSmrg 187073143b9aSmrg scount = 0; 187173143b9aSmrg while (hostp->h_addr_list[scount] && scount <= 8) 187273143b9aSmrg { 187373143b9aSmrg /* 187473143b9aSmrg * The 2nd call to gethostname() overrides the data 187573143b9aSmrg * from the 1st call, so we must save the address list. 187673143b9aSmrg */ 187773143b9aSmrg 1878fe567363Smrg specified_local_addr_list[scount][0] = 187973143b9aSmrg hostp->h_addr_list[scount][0]; 1880fe567363Smrg specified_local_addr_list[scount][1] = 188173143b9aSmrg hostp->h_addr_list[scount][1]; 1882fe567363Smrg specified_local_addr_list[scount][2] = 188373143b9aSmrg hostp->h_addr_list[scount][2]; 1884fe567363Smrg specified_local_addr_list[scount][3] = 188573143b9aSmrg hostp->h_addr_list[scount][3]; 188673143b9aSmrg scount++; 188773143b9aSmrg } 188873143b9aSmrg if ((hostp = _XGethostbyname (hostnamebuf,hparams)) == NULL) 188973143b9aSmrg return (0); 189073143b9aSmrg 189173143b9aSmrg equiv = 0; 189273143b9aSmrg i = 0; 189373143b9aSmrg 189473143b9aSmrg while (i < scount && !equiv) 189573143b9aSmrg { 189673143b9aSmrg j = 0; 189773143b9aSmrg 189873143b9aSmrg while (hostp->h_addr_list[j]) 189973143b9aSmrg { 1900fe567363Smrg if ((specified_local_addr_list[i][0] == 190173143b9aSmrg hostp->h_addr_list[j][0]) && 1902fe567363Smrg (specified_local_addr_list[i][1] == 190373143b9aSmrg hostp->h_addr_list[j][1]) && 1904fe567363Smrg (specified_local_addr_list[i][2] == 190573143b9aSmrg hostp->h_addr_list[j][2]) && 1906fe567363Smrg (specified_local_addr_list[i][3] == 190773143b9aSmrg hostp->h_addr_list[j][3])) 190873143b9aSmrg { 190973143b9aSmrg /* They're equal, so we're done */ 1910fe567363Smrg 191173143b9aSmrg equiv = 1; 191273143b9aSmrg break; 191373143b9aSmrg } 191473143b9aSmrg 191573143b9aSmrg j++; 191673143b9aSmrg } 191773143b9aSmrg 191873143b9aSmrg i++; 191973143b9aSmrg } 192073143b9aSmrg return (equiv); 1921b53e5eeaSmrg#endif 192273143b9aSmrg } 192373143b9aSmrg} 192473143b9aSmrg 192573143b9aSmrgstatic int 192673143b9aSmrgTRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) 192773143b9aSmrg 192873143b9aSmrg{ 192973143b9aSmrg struct sockaddr_un sockname; 193073143b9aSmrg SOCKLEN_T namelen; 193173143b9aSmrg 193273143b9aSmrg 193373143b9aSmrg int abstract = 0; 193473143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 193573143b9aSmrg abstract = ciptr->transptr->flags & TRANS_ABSTRACT; 193673143b9aSmrg#endif 193773143b9aSmrg 1938fe567363Smrg prmsg (2,"SocketUNIXConnect(%d,%s,%s)\n", ciptr->fd, host, port); 1939fe567363Smrg 194073143b9aSmrg /* 194173143b9aSmrg * Make sure 'host' is really local. If not, we return failure. 194273143b9aSmrg * The reason we make this check is because a process may advertise 194373143b9aSmrg * a "local" network ID for which it can accept connections, but if 194473143b9aSmrg * a process on a remote machine tries to connect to this network ID, 194573143b9aSmrg * we know for sure it will fail. 194673143b9aSmrg */ 194773143b9aSmrg 194873143b9aSmrg if (host && *host && host[0]!='/' && strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host)) 194973143b9aSmrg { 1950fe567363Smrg prmsg (1, 195173143b9aSmrg "SocketUNIXConnect: Cannot connect to non-local host %s\n", 1952fe567363Smrg host); 195373143b9aSmrg return TRANS_CONNECT_FAILED; 195473143b9aSmrg } 195573143b9aSmrg 195673143b9aSmrg 195773143b9aSmrg /* 195873143b9aSmrg * Check the port. 195973143b9aSmrg */ 196073143b9aSmrg 196173143b9aSmrg if (!port || !*port) 196273143b9aSmrg { 1963fe567363Smrg prmsg (1,"SocketUNIXConnect: Missing port specification\n"); 196473143b9aSmrg return TRANS_CONNECT_FAILED; 196573143b9aSmrg } 196673143b9aSmrg 196773143b9aSmrg /* 196873143b9aSmrg * Build the socket name. 196973143b9aSmrg */ 1970fe567363Smrg 197173143b9aSmrg sockname.sun_family = AF_UNIX; 197273143b9aSmrg 197373143b9aSmrg if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { 1974fe567363Smrg prmsg (1, "SocketUNIXConnect: path too long\n"); 197573143b9aSmrg return TRANS_CONNECT_FAILED; 197673143b9aSmrg } 197773143b9aSmrg 1978fe567363Smrg#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) 197973143b9aSmrg sockname.sun_len = strlen (sockname.sun_path); 198073143b9aSmrg#endif 198173143b9aSmrg 198273143b9aSmrg#if defined(BSD44SOCKETS) || defined(SUN_LEN) 198373143b9aSmrg namelen = SUN_LEN (&sockname); 198473143b9aSmrg#else 198573143b9aSmrg namelen = strlen (sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); 198673143b9aSmrg#endif 198773143b9aSmrg 198873143b9aSmrg 198973143b9aSmrg 199073143b9aSmrg /* 199173143b9aSmrg * Adjust the socket path if using abstract sockets. 199273143b9aSmrg * Done here because otherwise all the strlen() calls above would fail. 199373143b9aSmrg */ 199473143b9aSmrg 199573143b9aSmrg if (abstract) { 199673143b9aSmrg sockname.sun_path[0] = '\0'; 199773143b9aSmrg } 199873143b9aSmrg 199973143b9aSmrg /* 200073143b9aSmrg * Do the connect() 200173143b9aSmrg */ 200273143b9aSmrg 200373143b9aSmrg if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0) 200473143b9aSmrg { 200573143b9aSmrg int olderrno = errno; 200673143b9aSmrg int connected = 0; 2007fe567363Smrg 200873143b9aSmrg if (!connected) 200973143b9aSmrg { 201073143b9aSmrg errno = olderrno; 2011fe567363Smrg 201273143b9aSmrg /* 201373143b9aSmrg * If the error was ENOENT, the server may be starting up; we used 201473143b9aSmrg * to suggest to try again in this case with 201573143b9aSmrg * TRANS_TRY_CONNECT_AGAIN, but this introduced problems for 201673143b9aSmrg * processes still referencing stale sockets in their environment. 201773143b9aSmrg * Hence, we now return a hard error, TRANS_CONNECT_FAILED, and it 201873143b9aSmrg * is suggested that higher level stacks handle retries on their 201973143b9aSmrg * level when they face a slow starting server. 202073143b9aSmrg * 202173143b9aSmrg * If the error was EWOULDBLOCK or EINPROGRESS then the socket 202273143b9aSmrg * was non-blocking and we should poll using select 202373143b9aSmrg * 202473143b9aSmrg * If the error was EINTR, the connect was interrupted and we 202573143b9aSmrg * should try again. 202673143b9aSmrg */ 202773143b9aSmrg 202873143b9aSmrg if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS) 202973143b9aSmrg return TRANS_IN_PROGRESS; 203073143b9aSmrg else if (olderrno == EINTR) 203173143b9aSmrg return TRANS_TRY_CONNECT_AGAIN; 20328d4c0f7bSmrg else if (olderrno == ENOENT || olderrno == ECONNREFUSED) { 203373143b9aSmrg /* If opening as abstract socket failed, try again normally */ 203473143b9aSmrg if (abstract) { 203573143b9aSmrg ciptr->transptr->flags &= ~(TRANS_ABSTRACT); 203673143b9aSmrg return TRANS_TRY_CONNECT_AGAIN; 203773143b9aSmrg } else { 203873143b9aSmrg return TRANS_CONNECT_FAILED; 203973143b9aSmrg } 204073143b9aSmrg } else { 2041fe567363Smrg prmsg (2,"SocketUNIXConnect: Can't connect: errno = %d\n", 2042fe567363Smrg EGET()); 204373143b9aSmrg 204473143b9aSmrg return TRANS_CONNECT_FAILED; 204573143b9aSmrg } 204673143b9aSmrg } 204773143b9aSmrg } 204873143b9aSmrg 204973143b9aSmrg /* 205073143b9aSmrg * Get the socket name and the peer name from the connect socket, 205173143b9aSmrg * since this is unix domain. 205273143b9aSmrg */ 205373143b9aSmrg 2054fe567363Smrg if ((ciptr->addr = malloc(namelen)) == NULL || 2055fe567363Smrg (ciptr->peeraddr = malloc(namelen)) == NULL) 205673143b9aSmrg { 2057fe567363Smrg prmsg (1, 2058fe567363Smrg "SocketUNIXCreateListener: Can't allocate space for the addr\n"); 205973143b9aSmrg return TRANS_CONNECT_FAILED; 206073143b9aSmrg } 206173143b9aSmrg 206273143b9aSmrg if (abstract) 206373143b9aSmrg sockname.sun_path[0] = '@'; 206473143b9aSmrg 206573143b9aSmrg ciptr->family = AF_UNIX; 206673143b9aSmrg ciptr->addrlen = namelen; 206773143b9aSmrg ciptr->peeraddrlen = namelen; 206873143b9aSmrg memcpy (ciptr->addr, &sockname, ciptr->addrlen); 206973143b9aSmrg memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen); 207073143b9aSmrg 207173143b9aSmrg return 0; 207273143b9aSmrg} 207373143b9aSmrg 207473143b9aSmrg#endif /* UNIXCONN */ 207573143b9aSmrg 207673143b9aSmrg#endif /* TRANS_CLIENT */ 207773143b9aSmrg 207873143b9aSmrg 207973143b9aSmrgstatic int 208073143b9aSmrgTRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) 208173143b9aSmrg 208273143b9aSmrg{ 2083fe567363Smrg prmsg (2,"SocketBytesReadable(%p,%d,%p)\n", 208473143b9aSmrg ciptr, ciptr->fd, pend); 208573143b9aSmrg#ifdef WIN32 208673143b9aSmrg { 208773143b9aSmrg int ret = ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend); 208873143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 208973143b9aSmrg return ret; 209073143b9aSmrg } 209173143b9aSmrg#else 2092fe567363Smrg#if defined(__i386__) && defined(SYSV) && !defined(SCO325) 209373143b9aSmrg return ioctl (ciptr->fd, I_NREAD, (char *) pend); 209473143b9aSmrg#else 209573143b9aSmrg return ioctl (ciptr->fd, FIONREAD, (char *) pend); 209673143b9aSmrg#endif /* __i386__ && SYSV || _SEQUENT_ && _SOCKET_VERSION == 1 */ 209773143b9aSmrg#endif /* WIN32 */ 209873143b9aSmrg} 209973143b9aSmrg 210073143b9aSmrg 210173143b9aSmrgstatic int 210273143b9aSmrgTRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size) 210373143b9aSmrg 210473143b9aSmrg{ 2105fe567363Smrg prmsg (2,"SocketRead(%d,%p,%d)\n", ciptr->fd, buf, size); 210673143b9aSmrg 2107fe567363Smrg#if defined(WIN32) 210873143b9aSmrg { 210973143b9aSmrg int ret = recv ((SOCKET)ciptr->fd, buf, size, 0); 211073143b9aSmrg#ifdef WIN32 211173143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 211273143b9aSmrg#endif 211373143b9aSmrg return ret; 211473143b9aSmrg } 211573143b9aSmrg#else 211673143b9aSmrg return read (ciptr->fd, buf, size); 211773143b9aSmrg#endif /* WIN32 */ 211873143b9aSmrg} 211973143b9aSmrg 212073143b9aSmrg 212173143b9aSmrgstatic int 212273143b9aSmrgTRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size) 212373143b9aSmrg 212473143b9aSmrg{ 2125fe567363Smrg prmsg (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size); 212673143b9aSmrg 2127fe567363Smrg#if defined(WIN32) 212873143b9aSmrg { 212973143b9aSmrg int ret = send ((SOCKET)ciptr->fd, buf, size, 0); 213073143b9aSmrg#ifdef WIN32 213173143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 213273143b9aSmrg#endif 213373143b9aSmrg return ret; 213473143b9aSmrg } 213573143b9aSmrg#else 213673143b9aSmrg return write (ciptr->fd, buf, size); 213773143b9aSmrg#endif /* WIN32 */ 213873143b9aSmrg} 213973143b9aSmrg 214073143b9aSmrg 214173143b9aSmrgstatic int 214273143b9aSmrgTRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size) 214373143b9aSmrg 214473143b9aSmrg{ 2145fe567363Smrg prmsg (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size); 214673143b9aSmrg 214773143b9aSmrg return READV (ciptr, buf, size); 214873143b9aSmrg} 214973143b9aSmrg 215073143b9aSmrg 215173143b9aSmrgstatic int 215273143b9aSmrgTRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) 215373143b9aSmrg 215473143b9aSmrg{ 2155fe567363Smrg prmsg (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size); 215673143b9aSmrg 215773143b9aSmrg return WRITEV (ciptr, buf, size); 215873143b9aSmrg} 215973143b9aSmrg 216073143b9aSmrg 216173143b9aSmrgstatic int 216273143b9aSmrgTRANS(SocketDisconnect) (XtransConnInfo ciptr) 216373143b9aSmrg 216473143b9aSmrg{ 2165fe567363Smrg prmsg (2,"SocketDisconnect(%p,%d)\n", ciptr, ciptr->fd); 216673143b9aSmrg 216773143b9aSmrg#ifdef WIN32 2168fe567363Smrg { 216973143b9aSmrg int ret = shutdown (ciptr->fd, 2); 217073143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 217173143b9aSmrg return ret; 217273143b9aSmrg } 217373143b9aSmrg#else 217473143b9aSmrg return shutdown (ciptr->fd, 2); /* disallow further sends and receives */ 217573143b9aSmrg#endif 217673143b9aSmrg} 217773143b9aSmrg 217873143b9aSmrg 217973143b9aSmrg#ifdef TCPCONN 218073143b9aSmrgstatic int 218173143b9aSmrgTRANS(SocketINETClose) (XtransConnInfo ciptr) 218273143b9aSmrg 218373143b9aSmrg{ 2184fe567363Smrg prmsg (2,"SocketINETClose(%p,%d)\n", ciptr, ciptr->fd); 218573143b9aSmrg 218673143b9aSmrg#ifdef WIN32 218773143b9aSmrg { 218873143b9aSmrg int ret = close (ciptr->fd); 218973143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 219073143b9aSmrg return ret; 219173143b9aSmrg } 219273143b9aSmrg#else 219373143b9aSmrg return close (ciptr->fd); 219473143b9aSmrg#endif 219573143b9aSmrg} 219673143b9aSmrg 219773143b9aSmrg#endif /* TCPCONN */ 219873143b9aSmrg 219973143b9aSmrg 220073143b9aSmrg#ifdef UNIXCONN 220173143b9aSmrgstatic int 220273143b9aSmrgTRANS(SocketUNIXClose) (XtransConnInfo ciptr) 220373143b9aSmrg{ 220473143b9aSmrg /* 220573143b9aSmrg * If this is the server side, then once the socket is closed, 220673143b9aSmrg * it must be unlinked to completely close it 220773143b9aSmrg */ 220873143b9aSmrg 220973143b9aSmrg struct sockaddr_un *sockname = (struct sockaddr_un *) ciptr->addr; 221073143b9aSmrg int ret; 221173143b9aSmrg 2212fe567363Smrg prmsg (2,"SocketUNIXClose(%p,%d)\n", ciptr, ciptr->fd); 221373143b9aSmrg 221473143b9aSmrg ret = close(ciptr->fd); 221573143b9aSmrg 221673143b9aSmrg if (ciptr->flags 221773143b9aSmrg && sockname 221873143b9aSmrg && sockname->sun_family == AF_UNIX 221973143b9aSmrg && sockname->sun_path[0]) 222073143b9aSmrg { 222173143b9aSmrg if (!(ciptr->flags & TRANS_NOUNLINK 222273143b9aSmrg || ciptr->transptr->flags & TRANS_ABSTRACT)) 222373143b9aSmrg unlink (sockname->sun_path); 222473143b9aSmrg } 222573143b9aSmrg 222673143b9aSmrg return ret; 222773143b9aSmrg} 222873143b9aSmrg 222973143b9aSmrgstatic int 223073143b9aSmrgTRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr) 223173143b9aSmrg 223273143b9aSmrg{ 223373143b9aSmrg /* 223473143b9aSmrg * Don't unlink path. 223573143b9aSmrg */ 223673143b9aSmrg 223773143b9aSmrg int ret; 223873143b9aSmrg 2239fe567363Smrg prmsg (2,"SocketUNIXCloseForCloning(%p,%d)\n", 2240fe567363Smrg ciptr, ciptr->fd); 224173143b9aSmrg 224273143b9aSmrg ret = close(ciptr->fd); 224373143b9aSmrg 224473143b9aSmrg return ret; 224573143b9aSmrg} 224673143b9aSmrg 224773143b9aSmrg#endif /* UNIXCONN */ 224873143b9aSmrg 224973143b9aSmrg 225073143b9aSmrg#ifdef TCPCONN 225173143b9aSmrg# ifdef TRANS_SERVER 2252fe567363Smrgstatic const char* tcp_nolisten[] = { 225373143b9aSmrg "inet", 225473143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 225573143b9aSmrg "inet6", 225673143b9aSmrg#endif 225773143b9aSmrg NULL 225873143b9aSmrg}; 225973143b9aSmrg# endif 226073143b9aSmrg 226173143b9aSmrgXtransport TRANS(SocketTCPFuncs) = { 226273143b9aSmrg /* Socket Interface */ 226373143b9aSmrg "tcp", 226473143b9aSmrg TRANS_ALIAS, 226573143b9aSmrg#ifdef TRANS_CLIENT 226673143b9aSmrg TRANS(SocketOpenCOTSClient), 226773143b9aSmrg#endif /* TRANS_CLIENT */ 226873143b9aSmrg#ifdef TRANS_SERVER 226973143b9aSmrg tcp_nolisten, 227073143b9aSmrg TRANS(SocketOpenCOTSServer), 227173143b9aSmrg#endif /* TRANS_SERVER */ 227273143b9aSmrg#ifdef TRANS_CLIENT 227373143b9aSmrg TRANS(SocketOpenCLTSClient), 227473143b9aSmrg#endif /* TRANS_CLIENT */ 227573143b9aSmrg#ifdef TRANS_SERVER 227673143b9aSmrg TRANS(SocketOpenCLTSServer), 227773143b9aSmrg#endif /* TRANS_SERVER */ 227873143b9aSmrg#ifdef TRANS_REOPEN 227973143b9aSmrg TRANS(SocketReopenCOTSServer), 228073143b9aSmrg TRANS(SocketReopenCLTSServer), 228173143b9aSmrg#endif 228273143b9aSmrg TRANS(SocketSetOption), 228373143b9aSmrg#ifdef TRANS_SERVER 228473143b9aSmrg TRANS(SocketINETCreateListener), 228573143b9aSmrg NULL, /* ResetListener */ 228673143b9aSmrg TRANS(SocketINETAccept), 228773143b9aSmrg#endif /* TRANS_SERVER */ 228873143b9aSmrg#ifdef TRANS_CLIENT 228973143b9aSmrg TRANS(SocketINETConnect), 229073143b9aSmrg#endif /* TRANS_CLIENT */ 229173143b9aSmrg TRANS(SocketBytesReadable), 229273143b9aSmrg TRANS(SocketRead), 229373143b9aSmrg TRANS(SocketWrite), 229473143b9aSmrg TRANS(SocketReadv), 229573143b9aSmrg TRANS(SocketWritev), 229673143b9aSmrg TRANS(SocketDisconnect), 229773143b9aSmrg TRANS(SocketINETClose), 229873143b9aSmrg TRANS(SocketINETClose), 229973143b9aSmrg }; 230073143b9aSmrg 230173143b9aSmrgXtransport TRANS(SocketINETFuncs) = { 230273143b9aSmrg /* Socket Interface */ 230373143b9aSmrg "inet", 230473143b9aSmrg 0, 230573143b9aSmrg#ifdef TRANS_CLIENT 230673143b9aSmrg TRANS(SocketOpenCOTSClient), 230773143b9aSmrg#endif /* TRANS_CLIENT */ 230873143b9aSmrg#ifdef TRANS_SERVER 230973143b9aSmrg NULL, 231073143b9aSmrg TRANS(SocketOpenCOTSServer), 231173143b9aSmrg#endif /* TRANS_SERVER */ 231273143b9aSmrg#ifdef TRANS_CLIENT 231373143b9aSmrg TRANS(SocketOpenCLTSClient), 231473143b9aSmrg#endif /* TRANS_CLIENT */ 231573143b9aSmrg#ifdef TRANS_SERVER 231673143b9aSmrg TRANS(SocketOpenCLTSServer), 231773143b9aSmrg#endif /* TRANS_SERVER */ 231873143b9aSmrg#ifdef TRANS_REOPEN 231973143b9aSmrg TRANS(SocketReopenCOTSServer), 232073143b9aSmrg TRANS(SocketReopenCLTSServer), 232173143b9aSmrg#endif 232273143b9aSmrg TRANS(SocketSetOption), 232373143b9aSmrg#ifdef TRANS_SERVER 232473143b9aSmrg TRANS(SocketINETCreateListener), 232573143b9aSmrg NULL, /* ResetListener */ 232673143b9aSmrg TRANS(SocketINETAccept), 232773143b9aSmrg#endif /* TRANS_SERVER */ 232873143b9aSmrg#ifdef TRANS_CLIENT 232973143b9aSmrg TRANS(SocketINETConnect), 233073143b9aSmrg#endif /* TRANS_CLIENT */ 233173143b9aSmrg TRANS(SocketBytesReadable), 233273143b9aSmrg TRANS(SocketRead), 233373143b9aSmrg TRANS(SocketWrite), 233473143b9aSmrg TRANS(SocketReadv), 233573143b9aSmrg TRANS(SocketWritev), 233673143b9aSmrg TRANS(SocketDisconnect), 233773143b9aSmrg TRANS(SocketINETClose), 233873143b9aSmrg TRANS(SocketINETClose), 233973143b9aSmrg }; 234073143b9aSmrg 234173143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 234273143b9aSmrgXtransport TRANS(SocketINET6Funcs) = { 234373143b9aSmrg /* Socket Interface */ 234473143b9aSmrg "inet6", 234573143b9aSmrg 0, 234673143b9aSmrg#ifdef TRANS_CLIENT 234773143b9aSmrg TRANS(SocketOpenCOTSClient), 234873143b9aSmrg#endif /* TRANS_CLIENT */ 234973143b9aSmrg#ifdef TRANS_SERVER 235073143b9aSmrg NULL, 235173143b9aSmrg TRANS(SocketOpenCOTSServer), 235273143b9aSmrg#endif /* TRANS_SERVER */ 235373143b9aSmrg#ifdef TRANS_CLIENT 235473143b9aSmrg TRANS(SocketOpenCLTSClient), 235573143b9aSmrg#endif /* TRANS_CLIENT */ 235673143b9aSmrg#ifdef TRANS_SERVER 235773143b9aSmrg TRANS(SocketOpenCLTSServer), 235873143b9aSmrg#endif /* TRANS_SERVER */ 235973143b9aSmrg#ifdef TRANS_REOPEN 236073143b9aSmrg TRANS(SocketReopenCOTSServer), 236173143b9aSmrg TRANS(SocketReopenCLTSServer), 236273143b9aSmrg#endif 236373143b9aSmrg TRANS(SocketSetOption), 236473143b9aSmrg#ifdef TRANS_SERVER 236573143b9aSmrg TRANS(SocketINETCreateListener), 236673143b9aSmrg NULL, /* ResetListener */ 236773143b9aSmrg TRANS(SocketINETAccept), 236873143b9aSmrg#endif /* TRANS_SERVER */ 236973143b9aSmrg#ifdef TRANS_CLIENT 237073143b9aSmrg TRANS(SocketINETConnect), 237173143b9aSmrg#endif /* TRANS_CLIENT */ 237273143b9aSmrg TRANS(SocketBytesReadable), 237373143b9aSmrg TRANS(SocketRead), 237473143b9aSmrg TRANS(SocketWrite), 237573143b9aSmrg TRANS(SocketReadv), 237673143b9aSmrg TRANS(SocketWritev), 237773143b9aSmrg TRANS(SocketDisconnect), 237873143b9aSmrg TRANS(SocketINETClose), 237973143b9aSmrg TRANS(SocketINETClose), 238073143b9aSmrg }; 238173143b9aSmrg#endif /* IPv6 */ 238273143b9aSmrg#endif /* TCPCONN */ 238373143b9aSmrg 238473143b9aSmrg#ifdef UNIXCONN 238573143b9aSmrg#if !defined(LOCALCONN) 238673143b9aSmrgXtransport TRANS(SocketLocalFuncs) = { 238773143b9aSmrg /* Socket Interface */ 238873143b9aSmrg "local", 238973143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 239073143b9aSmrg TRANS_ABSTRACT, 239173143b9aSmrg#else 239273143b9aSmrg 0, 239373143b9aSmrg#endif 239473143b9aSmrg#ifdef TRANS_CLIENT 239573143b9aSmrg TRANS(SocketOpenCOTSClient), 239673143b9aSmrg#endif /* TRANS_CLIENT */ 239773143b9aSmrg#ifdef TRANS_SERVER 239873143b9aSmrg NULL, 239973143b9aSmrg TRANS(SocketOpenCOTSServer), 240073143b9aSmrg#endif /* TRANS_SERVER */ 240173143b9aSmrg#ifdef TRANS_CLIENT 240273143b9aSmrg TRANS(SocketOpenCLTSClient), 240373143b9aSmrg#endif /* TRANS_CLIENT */ 240473143b9aSmrg#ifdef TRANS_SERVER 240573143b9aSmrg TRANS(SocketOpenCLTSServer), 240673143b9aSmrg#endif /* TRANS_SERVER */ 240773143b9aSmrg#ifdef TRANS_REOPEN 240873143b9aSmrg TRANS(SocketReopenCOTSServer), 240973143b9aSmrg TRANS(SocketReopenCLTSServer), 241073143b9aSmrg#endif 241173143b9aSmrg TRANS(SocketSetOption), 241273143b9aSmrg#ifdef TRANS_SERVER 241373143b9aSmrg TRANS(SocketUNIXCreateListener), 241473143b9aSmrg TRANS(SocketUNIXResetListener), 241573143b9aSmrg TRANS(SocketUNIXAccept), 241673143b9aSmrg#endif /* TRANS_SERVER */ 241773143b9aSmrg#ifdef TRANS_CLIENT 241873143b9aSmrg TRANS(SocketUNIXConnect), 241973143b9aSmrg#endif /* TRANS_CLIENT */ 242073143b9aSmrg TRANS(SocketBytesReadable), 242173143b9aSmrg TRANS(SocketRead), 242273143b9aSmrg TRANS(SocketWrite), 242373143b9aSmrg TRANS(SocketReadv), 242473143b9aSmrg TRANS(SocketWritev), 242573143b9aSmrg TRANS(SocketDisconnect), 242673143b9aSmrg TRANS(SocketUNIXClose), 242773143b9aSmrg TRANS(SocketUNIXCloseForCloning), 242873143b9aSmrg }; 242973143b9aSmrg#endif /* !LOCALCONN */ 243073143b9aSmrg# ifdef TRANS_SERVER 243173143b9aSmrg# if !defined(LOCALCONN) 243273143b9aSmrgstatic char* unix_nolisten[] = { "local" , NULL }; 243373143b9aSmrg# endif 243473143b9aSmrg# endif 2435fe567363Smrg 243673143b9aSmrgXtransport TRANS(SocketUNIXFuncs) = { 243773143b9aSmrg /* Socket Interface */ 243873143b9aSmrg "unix", 243973143b9aSmrg#if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS) 244073143b9aSmrg TRANS_ALIAS, 244173143b9aSmrg#else 244273143b9aSmrg 0, 244373143b9aSmrg#endif 244473143b9aSmrg#ifdef TRANS_CLIENT 244573143b9aSmrg TRANS(SocketOpenCOTSClient), 244673143b9aSmrg#endif /* TRANS_CLIENT */ 244773143b9aSmrg#ifdef TRANS_SERVER 244873143b9aSmrg#if !defined(LOCALCONN) 244973143b9aSmrg unix_nolisten, 245073143b9aSmrg#else 245173143b9aSmrg NULL, 245273143b9aSmrg#endif 245373143b9aSmrg TRANS(SocketOpenCOTSServer), 245473143b9aSmrg#endif /* TRANS_SERVER */ 245573143b9aSmrg#ifdef TRANS_CLIENT 245673143b9aSmrg TRANS(SocketOpenCLTSClient), 245773143b9aSmrg#endif /* TRANS_CLIENT */ 245873143b9aSmrg#ifdef TRANS_SERVER 245973143b9aSmrg TRANS(SocketOpenCLTSServer), 246073143b9aSmrg#endif /* TRANS_SERVER */ 246173143b9aSmrg#ifdef TRANS_REOPEN 246273143b9aSmrg TRANS(SocketReopenCOTSServer), 246373143b9aSmrg TRANS(SocketReopenCLTSServer), 246473143b9aSmrg#endif 246573143b9aSmrg TRANS(SocketSetOption), 246673143b9aSmrg#ifdef TRANS_SERVER 246773143b9aSmrg TRANS(SocketUNIXCreateListener), 246873143b9aSmrg TRANS(SocketUNIXResetListener), 246973143b9aSmrg TRANS(SocketUNIXAccept), 247073143b9aSmrg#endif /* TRANS_SERVER */ 247173143b9aSmrg#ifdef TRANS_CLIENT 247273143b9aSmrg TRANS(SocketUNIXConnect), 247373143b9aSmrg#endif /* TRANS_CLIENT */ 247473143b9aSmrg TRANS(SocketBytesReadable), 247573143b9aSmrg TRANS(SocketRead), 247673143b9aSmrg TRANS(SocketWrite), 247773143b9aSmrg TRANS(SocketReadv), 247873143b9aSmrg TRANS(SocketWritev), 247973143b9aSmrg TRANS(SocketDisconnect), 248073143b9aSmrg TRANS(SocketUNIXClose), 248173143b9aSmrg TRANS(SocketUNIXCloseForCloning), 248273143b9aSmrg }; 248373143b9aSmrg 248473143b9aSmrg#endif /* UNIXCONN */ 2485