Xtranssock.c revision af928962
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 1008d4c0f7bSmrg#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> 11773143b9aSmrg#endif 11873143b9aSmrg 1198d4c0f7bSmrg#if defined(__i386__) && defined(SYSV) 12073143b9aSmrg#include <sys/stropts.h> 12173143b9aSmrg#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 17473143b9aSmrgtypedef struct _Sockettrans2dev { 17573143b9aSmrg 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__) 24773143b9aSmrg# 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 25773143b9aSmrgTRANS(SocketSelectFamily) (int first, char *family) 25873143b9aSmrg 25973143b9aSmrg{ 26073143b9aSmrg int i; 26173143b9aSmrg 26273143b9aSmrg PRMSG (3,"SocketSelectFamily(%s)\n", family, 0, 0); 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 29173143b9aSmrg PRMSG (3,"SocketINETGetAddr(%p)\n", ciptr, 0, 0); 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); 30273143b9aSmrg 30373143b9aSmrg if (getsockname (ciptr->fd,(struct sockaddr *) socknamePtr, 30473143b9aSmrg (void *)&namelen) < 0) 30573143b9aSmrg { 30673143b9aSmrg#ifdef WIN32 30773143b9aSmrg errno = WSAGetLastError(); 30873143b9aSmrg#endif 30973143b9aSmrg PRMSG (1,"SocketINETGetAddr: getsockname() failed: %d\n", 31073143b9aSmrg EGET(),0, 0); 31173143b9aSmrg return -1; 31273143b9aSmrg } 31373143b9aSmrg 31473143b9aSmrg /* 31573143b9aSmrg * Everything looks good: fill in the XtransConnInfo structure. 31673143b9aSmrg */ 31773143b9aSmrg 31873143b9aSmrg if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) 31973143b9aSmrg { 32073143b9aSmrg PRMSG (1, 32173143b9aSmrg "SocketINETGetAddr: Can't allocate space for the addr\n", 32273143b9aSmrg 0, 0, 0); 32373143b9aSmrg return -1; 32473143b9aSmrg } 32573143b9aSmrg 32673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 327b53e5eeaSmrg ciptr->family = ((struct sockaddr *)socknamePtr)->sa_family; 328b53e5eeaSmrg#else 329b53e5eeaSmrg ciptr->family = socknamev4.sin_family; 33073143b9aSmrg#endif 33173143b9aSmrg ciptr->addrlen = namelen; 33273143b9aSmrg memcpy (ciptr->addr, socknamePtr, ciptr->addrlen); 33373143b9aSmrg 33473143b9aSmrg return 0; 33573143b9aSmrg} 33673143b9aSmrg 33773143b9aSmrg 33873143b9aSmrg/* 33973143b9aSmrg * This function gets the remote address of the socket and stores it in the 34073143b9aSmrg * XtransConnInfo structure for the connection. 34173143b9aSmrg */ 34273143b9aSmrg 34373143b9aSmrgstatic int 34473143b9aSmrgTRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr) 34573143b9aSmrg 34673143b9aSmrg{ 34773143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 34873143b9aSmrg struct sockaddr_storage socknamev6; 34973143b9aSmrg#endif 35073143b9aSmrg struct sockaddr_in socknamev4; 35173143b9aSmrg void *socknamePtr; 35273143b9aSmrg SOCKLEN_T namelen; 35373143b9aSmrg 35473143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 355b53e5eeaSmrg if (ciptr->family == AF_INET6) 35673143b9aSmrg { 35773143b9aSmrg namelen = sizeof(socknamev6); 35873143b9aSmrg socknamePtr = &socknamev6; 35973143b9aSmrg } 36073143b9aSmrg else 36173143b9aSmrg#endif 36273143b9aSmrg { 36373143b9aSmrg namelen = sizeof(socknamev4); 36473143b9aSmrg socknamePtr = &socknamev4; 36573143b9aSmrg } 36673143b9aSmrg 36773143b9aSmrg bzero(socknamePtr, namelen); 36873143b9aSmrg 36973143b9aSmrg PRMSG (3,"SocketINETGetPeerAddr(%p)\n", ciptr, 0, 0); 37073143b9aSmrg 37173143b9aSmrg if (getpeername (ciptr->fd, (struct sockaddr *) socknamePtr, 37273143b9aSmrg (void *)&namelen) < 0) 37373143b9aSmrg { 37473143b9aSmrg#ifdef WIN32 37573143b9aSmrg errno = WSAGetLastError(); 37673143b9aSmrg#endif 37773143b9aSmrg PRMSG (1,"SocketINETGetPeerAddr: getpeername() failed: %d\n", 37873143b9aSmrg EGET(), 0, 0); 37973143b9aSmrg return -1; 38073143b9aSmrg } 38173143b9aSmrg 38273143b9aSmrg /* 38373143b9aSmrg * Everything looks good: fill in the XtransConnInfo structure. 38473143b9aSmrg */ 38573143b9aSmrg 38673143b9aSmrg if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL) 38773143b9aSmrg { 38873143b9aSmrg PRMSG (1, 38973143b9aSmrg "SocketINETGetPeerAddr: Can't allocate space for the addr\n", 39073143b9aSmrg 0, 0, 0); 39173143b9aSmrg return -1; 39273143b9aSmrg } 39373143b9aSmrg 39473143b9aSmrg ciptr->peeraddrlen = namelen; 39573143b9aSmrg memcpy (ciptr->peeraddr, socknamePtr, ciptr->peeraddrlen); 39673143b9aSmrg 39773143b9aSmrg return 0; 39873143b9aSmrg} 39973143b9aSmrg 40073143b9aSmrg 40173143b9aSmrgstatic XtransConnInfo 40273143b9aSmrgTRANS(SocketOpen) (int i, int type) 40373143b9aSmrg 40473143b9aSmrg{ 40573143b9aSmrg XtransConnInfo ciptr; 40673143b9aSmrg 40773143b9aSmrg PRMSG (3,"SocketOpen(%d,%d)\n", i, type, 0); 40873143b9aSmrg 40973143b9aSmrg if ((ciptr = (XtransConnInfo) xcalloc ( 41073143b9aSmrg 1, sizeof(struct _XtransConnInfo))) == NULL) 41173143b9aSmrg { 41273143b9aSmrg PRMSG (1, "SocketOpen: malloc failed\n", 0, 0, 0); 41373143b9aSmrg return NULL; 41473143b9aSmrg } 41573143b9aSmrg 41673143b9aSmrg if ((ciptr->fd = socket(Sockettrans2devtab[i].family, type, 41773143b9aSmrg Sockettrans2devtab[i].protocol)) < 0 41873143b9aSmrg#ifndef WIN32 41973143b9aSmrg#if (defined(X11_t) && !defined(USE_POLL)) || defined(FS_t) || defined(FONT_t) 4208d4c0f7bSmrg || ciptr->fd >= sysconf(_SC_OPEN_MAX) 42173143b9aSmrg#endif 42273143b9aSmrg#endif 42373143b9aSmrg ) { 42473143b9aSmrg#ifdef WIN32 42573143b9aSmrg errno = WSAGetLastError(); 42673143b9aSmrg#endif 42773143b9aSmrg PRMSG (2, "SocketOpen: socket() failed for %s\n", 42873143b9aSmrg Sockettrans2devtab[i].transname, 0, 0); 42973143b9aSmrg 43073143b9aSmrg xfree ((char *) ciptr); 43173143b9aSmrg return NULL; 43273143b9aSmrg } 43373143b9aSmrg 43473143b9aSmrg#ifdef TCP_NODELAY 43573143b9aSmrg if (Sockettrans2devtab[i].family == AF_INET 43673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 43773143b9aSmrg || Sockettrans2devtab[i].family == AF_INET6 43873143b9aSmrg#endif 43973143b9aSmrg ) 44073143b9aSmrg { 44173143b9aSmrg /* 44273143b9aSmrg * turn off TCP coalescence for INET sockets 44373143b9aSmrg */ 44473143b9aSmrg 44573143b9aSmrg int tmp = 1; 44673143b9aSmrg setsockopt (ciptr->fd, IPPROTO_TCP, TCP_NODELAY, 44773143b9aSmrg (char *) &tmp, sizeof (int)); 44873143b9aSmrg } 44973143b9aSmrg#endif 45073143b9aSmrg 45173143b9aSmrg return ciptr; 45273143b9aSmrg} 45373143b9aSmrg 45473143b9aSmrg 45573143b9aSmrg#ifdef TRANS_REOPEN 45673143b9aSmrg 45773143b9aSmrgstatic XtransConnInfo 45873143b9aSmrgTRANS(SocketReopen) (int i, int type, int fd, char *port) 45973143b9aSmrg 46073143b9aSmrg{ 46173143b9aSmrg XtransConnInfo ciptr; 46273143b9aSmrg int portlen; 46373143b9aSmrg struct sockaddr *addr; 46473143b9aSmrg 46573143b9aSmrg PRMSG (3,"SocketReopen(%d,%d,%s)\n", type, fd, port); 46673143b9aSmrg 46773143b9aSmrg if (port == NULL) { 46873143b9aSmrg PRMSG (1, "SocketReopen: port was null!\n", 0, 0, 0); 46973143b9aSmrg return NULL; 47073143b9aSmrg } 47173143b9aSmrg 47273143b9aSmrg portlen = strlen(port) + 1; // include space for trailing null 47373143b9aSmrg#ifdef SOCK_MAXADDRLEN 47473143b9aSmrg if (portlen < 0 || portlen > (SOCK_MAXADDRLEN + 2)) { 47573143b9aSmrg PRMSG (1, "SocketReopen: invalid portlen %d\n", portlen, 0, 0); 47673143b9aSmrg return NULL; 47773143b9aSmrg } 47873143b9aSmrg if (portlen < 14) portlen = 14; 47973143b9aSmrg#else 48073143b9aSmrg if (portlen < 0 || portlen > 14) { 48173143b9aSmrg PRMSG (1, "SocketReopen: invalid portlen %d\n", portlen, 0, 0); 48273143b9aSmrg return NULL; 48373143b9aSmrg } 48473143b9aSmrg#endif /*SOCK_MAXADDRLEN*/ 48573143b9aSmrg 48673143b9aSmrg if ((ciptr = (XtransConnInfo) xcalloc ( 48773143b9aSmrg 1, sizeof(struct _XtransConnInfo))) == NULL) 48873143b9aSmrg { 48973143b9aSmrg PRMSG (1, "SocketReopen: malloc(ciptr) failed\n", 0, 0, 0); 49073143b9aSmrg return NULL; 49173143b9aSmrg } 49273143b9aSmrg 49373143b9aSmrg ciptr->fd = fd; 49473143b9aSmrg 49573143b9aSmrg if ((addr = (struct sockaddr *) xcalloc (1, portlen + 2)) == NULL) { 49673143b9aSmrg PRMSG (1, "SocketReopen: malloc(addr) failed\n", 0, 0, 0); 49773143b9aSmrg return NULL; 49873143b9aSmrg } 4998d4c0f7bSmrg ciptr->addr = (char *) addr; 50073143b9aSmrg ciptr->addrlen = portlen + 2; 50173143b9aSmrg 5028d4c0f7bSmrg if ((ciptr->peeraddr = (char *) xcalloc (1, portlen + 2)) == NULL) { 50373143b9aSmrg PRMSG (1, "SocketReopen: malloc(portaddr) failed\n", 0, 0, 0); 50473143b9aSmrg return NULL; 50573143b9aSmrg } 50673143b9aSmrg ciptr->peeraddrlen = portlen + 2; 50773143b9aSmrg 50873143b9aSmrg /* Initialize ciptr structure as if it were a normally-opened unix socket */ 50973143b9aSmrg ciptr->flags = TRANS_LOCAL | TRANS_NOUNLINK; 51073143b9aSmrg#ifdef BSD44SOCKETS 51173143b9aSmrg addr->sa_len = portlen + 1; 51273143b9aSmrg#endif 51373143b9aSmrg addr->sa_family = AF_UNIX; 51473143b9aSmrg#ifdef HAS_STRLCPY 51573143b9aSmrg strlcpy(addr->sa_data, port, portlen); 51673143b9aSmrg#else 51773143b9aSmrg strncpy(addr->sa_data, port, portlen); 51873143b9aSmrg#endif 51973143b9aSmrg ciptr->family = AF_UNIX; 52073143b9aSmrg memcpy(ciptr->peeraddr, ciptr->addr, sizeof(struct sockaddr)); 52173143b9aSmrg ciptr->port = rindex(addr->sa_data, ':'); 522e8a71cdfSmrg if (ciptr->port == NULL) { 523e8a71cdfSmrg if (is_numeric(addr->sa_data)) { 524e8a71cdfSmrg ciptr->port = addr->sa_data; 525e8a71cdfSmrg } 526e8a71cdfSmrg } else if (ciptr->port[0] == ':') { 527e8a71cdfSmrg ciptr->port++; 528e8a71cdfSmrg } 529e8a71cdfSmrg /* port should now point to portnum or NULL */ 53073143b9aSmrg return ciptr; 53173143b9aSmrg} 53273143b9aSmrg 53373143b9aSmrg#endif /* TRANS_REOPEN */ 53473143b9aSmrg 53573143b9aSmrg 53673143b9aSmrg/* 53773143b9aSmrg * These functions are the interface supplied in the Xtransport structure 53873143b9aSmrg */ 53973143b9aSmrg 54073143b9aSmrg#ifdef TRANS_CLIENT 54173143b9aSmrg 54273143b9aSmrgstatic XtransConnInfo 54373143b9aSmrgTRANS(SocketOpenCOTSClientBase) (char *transname, char *protocol, 54473143b9aSmrg char *host, char *port, int previndex) 54573143b9aSmrg{ 54673143b9aSmrg XtransConnInfo ciptr; 54773143b9aSmrg int i = previndex; 54873143b9aSmrg 54973143b9aSmrg PRMSG (2, "SocketOpenCOTSClient(%s,%s,%s)\n", 55073143b9aSmrg protocol, host, port); 55173143b9aSmrg 55273143b9aSmrg SocketInitOnce(); 55373143b9aSmrg 55473143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, transname)) >= 0) { 55573143b9aSmrg if ((ciptr = TRANS(SocketOpen) ( 556e8a71cdfSmrg i, Sockettrans2devtab[i].devcotsname)) != NULL) { 557e8a71cdfSmrg /* Save the index for later use */ 558e8a71cdfSmrg 559e8a71cdfSmrg ciptr->index = i; 56073143b9aSmrg break; 561e8a71cdfSmrg } 56273143b9aSmrg } 56373143b9aSmrg if (i < 0) { 56473143b9aSmrg if (i == -1) 56573143b9aSmrg PRMSG (1,"SocketOpenCOTSClient: Unable to open socket for %s\n", 56673143b9aSmrg transname, 0, 0); 56773143b9aSmrg else 56873143b9aSmrg PRMSG (1,"SocketOpenCOTSClient: Unable to determine socket type for %s\n", 56973143b9aSmrg transname, 0, 0); 57073143b9aSmrg return NULL; 57173143b9aSmrg } 57273143b9aSmrg 57373143b9aSmrg return ciptr; 57473143b9aSmrg} 57573143b9aSmrg 57673143b9aSmrgstatic XtransConnInfo 57773143b9aSmrgTRANS(SocketOpenCOTSClient) (Xtransport *thistrans, char *protocol, 57873143b9aSmrg char *host, char *port) 57973143b9aSmrg{ 58073143b9aSmrg return TRANS(SocketOpenCOTSClientBase)( 58173143b9aSmrg thistrans->TransName, protocol, host, port, -1); 58273143b9aSmrg} 58373143b9aSmrg 58473143b9aSmrg 58573143b9aSmrg#endif /* TRANS_CLIENT */ 58673143b9aSmrg 58773143b9aSmrg 58873143b9aSmrg#ifdef TRANS_SERVER 58973143b9aSmrg 59073143b9aSmrgstatic XtransConnInfo 59173143b9aSmrgTRANS(SocketOpenCOTSServer) (Xtransport *thistrans, char *protocol, 59273143b9aSmrg char *host, char *port) 59373143b9aSmrg 59473143b9aSmrg{ 59573143b9aSmrg XtransConnInfo ciptr; 59673143b9aSmrg int i = -1; 59773143b9aSmrg 59873143b9aSmrg PRMSG (2,"SocketOpenCOTSServer(%s,%s,%s)\n", protocol, host, port); 59973143b9aSmrg 60073143b9aSmrg SocketInitOnce(); 60173143b9aSmrg 60273143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 60373143b9aSmrg if ((ciptr = TRANS(SocketOpen) ( 60473143b9aSmrg i, Sockettrans2devtab[i].devcotsname)) != NULL) 60573143b9aSmrg break; 60673143b9aSmrg } 60773143b9aSmrg if (i < 0) { 60873143b9aSmrg if (i == -1) 60973143b9aSmrg PRMSG (1,"SocketOpenCOTSServer: Unable to open socket for %s\n", 61073143b9aSmrg thistrans->TransName, 0, 0); 61173143b9aSmrg else 61273143b9aSmrg PRMSG (1,"SocketOpenCOTSServer: Unable to determine socket type for %s\n", 61373143b9aSmrg thistrans->TransName, 0, 0); 61473143b9aSmrg return NULL; 61573143b9aSmrg } 61673143b9aSmrg 61773143b9aSmrg /* 61873143b9aSmrg * Using this prevents the bind() check for an existing server listening 61973143b9aSmrg * on the same port, but it is required for other reasons. 62073143b9aSmrg */ 62173143b9aSmrg#ifdef SO_REUSEADDR 62273143b9aSmrg 62373143b9aSmrg /* 62473143b9aSmrg * SO_REUSEADDR only applied to AF_INET && AF_INET6 62573143b9aSmrg */ 62673143b9aSmrg 62773143b9aSmrg if (Sockettrans2devtab[i].family == AF_INET 62873143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 62973143b9aSmrg || Sockettrans2devtab[i].family == AF_INET6 63073143b9aSmrg#endif 63173143b9aSmrg ) 63273143b9aSmrg { 63373143b9aSmrg int one = 1; 63473143b9aSmrg setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR, 63573143b9aSmrg (char *) &one, sizeof (int)); 63673143b9aSmrg } 63773143b9aSmrg#endif 63873143b9aSmrg#ifdef IPV6_V6ONLY 63973143b9aSmrg if (Sockettrans2devtab[i].family == AF_INET6) 64073143b9aSmrg { 64173143b9aSmrg int one = 1; 64273143b9aSmrg setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int)); 64373143b9aSmrg } 64473143b9aSmrg#endif 64573143b9aSmrg /* Save the index for later use */ 64673143b9aSmrg 64773143b9aSmrg ciptr->index = i; 64873143b9aSmrg 64973143b9aSmrg return ciptr; 65073143b9aSmrg} 65173143b9aSmrg 65273143b9aSmrg#endif /* TRANS_SERVER */ 65373143b9aSmrg 65473143b9aSmrg 65573143b9aSmrg#ifdef TRANS_CLIENT 65673143b9aSmrg 65773143b9aSmrgstatic XtransConnInfo 65873143b9aSmrgTRANS(SocketOpenCLTSClient) (Xtransport *thistrans, char *protocol, 65973143b9aSmrg char *host, char *port) 66073143b9aSmrg 66173143b9aSmrg{ 66273143b9aSmrg XtransConnInfo ciptr; 66373143b9aSmrg int i = -1; 66473143b9aSmrg 66573143b9aSmrg PRMSG (2,"SocketOpenCLTSClient(%s,%s,%s)\n", protocol, host, port); 66673143b9aSmrg 66773143b9aSmrg SocketInitOnce(); 66873143b9aSmrg 66973143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 67073143b9aSmrg if ((ciptr = TRANS(SocketOpen) ( 67173143b9aSmrg i, Sockettrans2devtab[i].devcotsname)) != NULL) 67273143b9aSmrg break; 67373143b9aSmrg } 67473143b9aSmrg if (i < 0) { 67573143b9aSmrg if (i == -1) 67673143b9aSmrg PRMSG (1,"SocketOpenCLTSClient: Unable to open socket for %s\n", 67773143b9aSmrg thistrans->TransName, 0, 0); 67873143b9aSmrg else 67973143b9aSmrg PRMSG (1,"SocketOpenCLTSClient: Unable to determine socket type for %s\n", 68073143b9aSmrg thistrans->TransName, 0, 0); 68173143b9aSmrg return NULL; 68273143b9aSmrg } 68373143b9aSmrg 68473143b9aSmrg /* Save the index for later use */ 68573143b9aSmrg 68673143b9aSmrg ciptr->index = i; 68773143b9aSmrg 68873143b9aSmrg return ciptr; 68973143b9aSmrg} 69073143b9aSmrg 69173143b9aSmrg#endif /* TRANS_CLIENT */ 69273143b9aSmrg 69373143b9aSmrg 69473143b9aSmrg#ifdef TRANS_SERVER 69573143b9aSmrg 69673143b9aSmrgstatic XtransConnInfo 69773143b9aSmrgTRANS(SocketOpenCLTSServer) (Xtransport *thistrans, char *protocol, 69873143b9aSmrg char *host, char *port) 69973143b9aSmrg 70073143b9aSmrg{ 70173143b9aSmrg XtransConnInfo ciptr; 70273143b9aSmrg int i = -1; 70373143b9aSmrg 70473143b9aSmrg PRMSG (2,"SocketOpenCLTSServer(%s,%s,%s)\n", protocol, host, port); 70573143b9aSmrg 70673143b9aSmrg SocketInitOnce(); 70773143b9aSmrg 70873143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 70973143b9aSmrg if ((ciptr = TRANS(SocketOpen) ( 71073143b9aSmrg i, Sockettrans2devtab[i].devcotsname)) != NULL) 71173143b9aSmrg break; 71273143b9aSmrg } 71373143b9aSmrg if (i < 0) { 71473143b9aSmrg if (i == -1) 71573143b9aSmrg PRMSG (1,"SocketOpenCLTSServer: Unable to open socket for %s\n", 71673143b9aSmrg thistrans->TransName, 0, 0); 71773143b9aSmrg else 71873143b9aSmrg PRMSG (1,"SocketOpenCLTSServer: Unable to determine socket type for %s\n", 71973143b9aSmrg thistrans->TransName, 0, 0); 72073143b9aSmrg return NULL; 72173143b9aSmrg } 72273143b9aSmrg 72373143b9aSmrg#ifdef IPV6_V6ONLY 72473143b9aSmrg if (Sockettrans2devtab[i].family == AF_INET6) 72573143b9aSmrg { 72673143b9aSmrg int one = 1; 72773143b9aSmrg setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int)); 72873143b9aSmrg } 72973143b9aSmrg#endif 73073143b9aSmrg /* Save the index for later use */ 73173143b9aSmrg 73273143b9aSmrg ciptr->index = i; 73373143b9aSmrg 73473143b9aSmrg return ciptr; 73573143b9aSmrg} 73673143b9aSmrg 73773143b9aSmrg#endif /* TRANS_SERVER */ 73873143b9aSmrg 73973143b9aSmrg 74073143b9aSmrg#ifdef TRANS_REOPEN 74173143b9aSmrg 74273143b9aSmrgstatic XtransConnInfo 74373143b9aSmrgTRANS(SocketReopenCOTSServer) (Xtransport *thistrans, int fd, char *port) 74473143b9aSmrg 74573143b9aSmrg{ 74673143b9aSmrg XtransConnInfo ciptr; 74773143b9aSmrg int i = -1; 74873143b9aSmrg 74973143b9aSmrg PRMSG (2, 75073143b9aSmrg "SocketReopenCOTSServer(%d, %s)\n", fd, port, 0); 75173143b9aSmrg 75273143b9aSmrg SocketInitOnce(); 75373143b9aSmrg 75473143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 75573143b9aSmrg if ((ciptr = TRANS(SocketReopen) ( 75673143b9aSmrg i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL) 75773143b9aSmrg break; 75873143b9aSmrg } 75973143b9aSmrg if (i < 0) { 76073143b9aSmrg if (i == -1) 76173143b9aSmrg PRMSG (1,"SocketReopenCOTSServer: Unable to open socket for %s\n", 76273143b9aSmrg thistrans->TransName, 0, 0); 76373143b9aSmrg else 76473143b9aSmrg PRMSG (1,"SocketReopenCOTSServer: Unable to determine socket type for %s\n", 76573143b9aSmrg thistrans->TransName, 0, 0); 76673143b9aSmrg return NULL; 76773143b9aSmrg } 76873143b9aSmrg 76973143b9aSmrg /* Save the index for later use */ 77073143b9aSmrg 77173143b9aSmrg ciptr->index = i; 77273143b9aSmrg 77373143b9aSmrg return ciptr; 77473143b9aSmrg} 77573143b9aSmrg 77673143b9aSmrgstatic XtransConnInfo 77773143b9aSmrgTRANS(SocketReopenCLTSServer) (Xtransport *thistrans, int fd, char *port) 77873143b9aSmrg 77973143b9aSmrg{ 78073143b9aSmrg XtransConnInfo ciptr; 78173143b9aSmrg int i = -1; 78273143b9aSmrg 78373143b9aSmrg PRMSG (2, 78473143b9aSmrg "SocketReopenCLTSServer(%d, %s)\n", fd, port, 0); 78573143b9aSmrg 78673143b9aSmrg SocketInitOnce(); 78773143b9aSmrg 78873143b9aSmrg while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) { 78973143b9aSmrg if ((ciptr = TRANS(SocketReopen) ( 79073143b9aSmrg i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL) 79173143b9aSmrg break; 79273143b9aSmrg } 79373143b9aSmrg if (i < 0) { 79473143b9aSmrg if (i == -1) 79573143b9aSmrg PRMSG (1,"SocketReopenCLTSServer: Unable to open socket for %s\n", 79673143b9aSmrg thistrans->TransName, 0, 0); 79773143b9aSmrg else 79873143b9aSmrg PRMSG (1,"SocketReopenCLTSServer: Unable to determine socket type for %s\n", 79973143b9aSmrg thistrans->TransName, 0, 0); 80073143b9aSmrg return NULL; 80173143b9aSmrg } 80273143b9aSmrg 80373143b9aSmrg /* Save the index for later use */ 80473143b9aSmrg 80573143b9aSmrg ciptr->index = i; 80673143b9aSmrg 80773143b9aSmrg return ciptr; 80873143b9aSmrg} 80973143b9aSmrg 81073143b9aSmrg#endif /* TRANS_REOPEN */ 81173143b9aSmrg 81273143b9aSmrg 81373143b9aSmrgstatic int 81473143b9aSmrgTRANS(SocketSetOption) (XtransConnInfo ciptr, int option, int arg) 81573143b9aSmrg 81673143b9aSmrg{ 81773143b9aSmrg PRMSG (2,"SocketSetOption(%d,%d,%d)\n", ciptr->fd, option, arg); 81873143b9aSmrg 81973143b9aSmrg return -1; 82073143b9aSmrg} 82173143b9aSmrg 82273143b9aSmrg#ifdef UNIXCONN 82373143b9aSmrgstatic int 82473143b9aSmrgset_sun_path(const char *port, const char *upath, char *path, int abstract) 82573143b9aSmrg{ 82673143b9aSmrg struct sockaddr_un s; 82773143b9aSmrg int maxlen = sizeof(s.sun_path) - 1; 82873143b9aSmrg const char *at = ""; 82973143b9aSmrg 83073143b9aSmrg if (!port || !*port || !path) 83173143b9aSmrg return -1; 83273143b9aSmrg 83373143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 83473143b9aSmrg if (port[0] == '@') 83573143b9aSmrg upath = ""; 83673143b9aSmrg else if (abstract) 83773143b9aSmrg at = "@"; 83873143b9aSmrg#endif 83973143b9aSmrg 84073143b9aSmrg if (*port == '/') /* a full pathname */ 84173143b9aSmrg upath = ""; 84273143b9aSmrg 84373143b9aSmrg if (strlen(port) + strlen(upath) > maxlen) 84473143b9aSmrg return -1; 84573143b9aSmrg sprintf(path, "%s%s%s", at, upath, port); 84673143b9aSmrg return 0; 84773143b9aSmrg} 84873143b9aSmrg#endif 84973143b9aSmrg 85073143b9aSmrg#ifdef TRANS_SERVER 85173143b9aSmrg 85273143b9aSmrgstatic int 85373143b9aSmrgTRANS(SocketCreateListener) (XtransConnInfo ciptr, 85473143b9aSmrg struct sockaddr *sockname, 85573143b9aSmrg int socknamelen, unsigned int flags) 85673143b9aSmrg 85773143b9aSmrg{ 85873143b9aSmrg SOCKLEN_T namelen = socknamelen; 85973143b9aSmrg int fd = ciptr->fd; 86073143b9aSmrg int retry; 86173143b9aSmrg 86273143b9aSmrg PRMSG (3, "SocketCreateListener(%x,%p)\n", ciptr, fd, 0); 86373143b9aSmrg 86473143b9aSmrg if (Sockettrans2devtab[ciptr->index].family == AF_INET 86573143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 86673143b9aSmrg || Sockettrans2devtab[ciptr->index].family == AF_INET6 86773143b9aSmrg#endif 86873143b9aSmrg ) 86973143b9aSmrg retry = 20; 87073143b9aSmrg else 87173143b9aSmrg retry = 0; 87273143b9aSmrg 87373143b9aSmrg while (bind (fd, (struct sockaddr *) sockname, namelen) < 0) 87473143b9aSmrg { 87573143b9aSmrg if (errno == EADDRINUSE) { 87673143b9aSmrg if (flags & ADDR_IN_USE_ALLOWED) 87773143b9aSmrg break; 87873143b9aSmrg else 87973143b9aSmrg return TRANS_ADDR_IN_USE; 88073143b9aSmrg } 88173143b9aSmrg 88273143b9aSmrg if (retry-- == 0) { 88373143b9aSmrg PRMSG (1, "SocketCreateListener: failed to bind listener\n", 88473143b9aSmrg 0, 0, 0); 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 { 91573143b9aSmrg PRMSG (1, "SocketCreateListener: listen() failed\n", 0, 0, 0); 91673143b9aSmrg close (fd); 91773143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 91873143b9aSmrg } 91973143b9aSmrg 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 94973143b9aSmrg 95073143b9aSmrg PRMSG (2, "SocketINETCreateListener(%s)\n", port, 0, 0); 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); 96673143b9aSmrg sprintf (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 { 97973143b9aSmrg PRMSG (1, 98073143b9aSmrg "SocketINETCreateListener: Unable to get service for %s\n", 98173143b9aSmrg port, 0, 0); 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); 99073143b9aSmrg /* 99173143b9aSmrg * check that somehow the port address isn't negative or in 99273143b9aSmrg * the range of reserved port addresses. This can happen and 99373143b9aSmrg * be very bad if the server is suid-root and the user does 99473143b9aSmrg * 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 { 103673143b9aSmrg PRMSG (1, 103773143b9aSmrg "SocketINETCreateListener: ...SocketCreateListener() failed\n", 103873143b9aSmrg 0, 0, 0); 103973143b9aSmrg return status; 104073143b9aSmrg } 104173143b9aSmrg 104273143b9aSmrg if (TRANS(SocketINETGetAddr) (ciptr) < 0) 104373143b9aSmrg { 104473143b9aSmrg PRMSG (1, 104573143b9aSmrg "SocketINETCreateListener: ...SocketINETGetAddr() failed\n", 104673143b9aSmrg 0, 0, 0); 104773143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 104873143b9aSmrg } 104973143b9aSmrg 105073143b9aSmrg return 0; 105173143b9aSmrg} 105273143b9aSmrg 105373143b9aSmrg#endif /* TCPCONN */ 105473143b9aSmrg 105573143b9aSmrg 105673143b9aSmrg#ifdef UNIXCONN 105773143b9aSmrg 105873143b9aSmrgstatic int 105973143b9aSmrgTRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, char *port, 106073143b9aSmrg unsigned int flags) 106173143b9aSmrg 106273143b9aSmrg{ 106373143b9aSmrg struct sockaddr_un sockname; 106473143b9aSmrg int namelen; 106573143b9aSmrg int oldUmask; 106673143b9aSmrg int status; 106773143b9aSmrg unsigned int mode; 106873143b9aSmrg char tmpport[108]; 106973143b9aSmrg 107073143b9aSmrg int abstract = 0; 107173143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 107273143b9aSmrg abstract = ciptr->transptr->flags & TRANS_ABSTRACT; 107373143b9aSmrg#endif 107473143b9aSmrg 107573143b9aSmrg PRMSG (2, "SocketUNIXCreateListener(%s)\n", 107673143b9aSmrg port ? port : "NULL", 0, 0); 107773143b9aSmrg 107873143b9aSmrg /* Make sure the directory is created */ 107973143b9aSmrg 108073143b9aSmrg oldUmask = umask (0); 108173143b9aSmrg 108273143b9aSmrg#ifdef UNIX_DIR 108373143b9aSmrg#ifdef HAS_STICKY_DIR_BIT 108473143b9aSmrg mode = 01777; 108573143b9aSmrg#else 108673143b9aSmrg mode = 0777; 108773143b9aSmrg#endif 10888d4c0f7bSmrg if (!abstract && trans_mkdir(UNIX_DIR, mode) == -1) { 108973143b9aSmrg PRMSG (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n", 109073143b9aSmrg UNIX_DIR, errno, 0); 109173143b9aSmrg (void) umask (oldUmask); 109273143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 109373143b9aSmrg } 109473143b9aSmrg#endif 109573143b9aSmrg 109673143b9aSmrg memset(&sockname, 0, sizeof(sockname)); 109773143b9aSmrg sockname.sun_family = AF_UNIX; 109873143b9aSmrg 109973143b9aSmrg if (!(port && *port)) { 110073143b9aSmrg snprintf (tmpport, sizeof(tmpport), "%s%ld", UNIX_PATH, (long)getpid()); 110173143b9aSmrg port = tmpport; 110273143b9aSmrg } 110373143b9aSmrg if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { 110473143b9aSmrg PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0); 110573143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 110673143b9aSmrg } 110773143b9aSmrg 11088d4c0f7bSmrg#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) 110973143b9aSmrg sockname.sun_len = strlen(sockname.sun_path); 111073143b9aSmrg#endif 111173143b9aSmrg 111273143b9aSmrg#if defined(BSD44SOCKETS) || defined(SUN_LEN) 111373143b9aSmrg namelen = SUN_LEN(&sockname); 111473143b9aSmrg#else 111573143b9aSmrg namelen = strlen(sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); 111673143b9aSmrg#endif 111773143b9aSmrg 111873143b9aSmrg if (abstract) { 111973143b9aSmrg sockname.sun_path[0] = '\0'; 112073143b9aSmrg namelen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&sockname.sun_path[1]); 112173143b9aSmrg } 112273143b9aSmrg else 112373143b9aSmrg unlink (sockname.sun_path); 112473143b9aSmrg 112573143b9aSmrg if ((status = TRANS(SocketCreateListener) (ciptr, 112673143b9aSmrg (struct sockaddr *) &sockname, namelen, flags)) < 0) 112773143b9aSmrg { 112873143b9aSmrg PRMSG (1, 112973143b9aSmrg "SocketUNIXCreateListener: ...SocketCreateListener() failed\n", 113073143b9aSmrg 0, 0, 0); 113173143b9aSmrg (void) umask (oldUmask); 113273143b9aSmrg return status; 113373143b9aSmrg } 113473143b9aSmrg 113573143b9aSmrg /* 113673143b9aSmrg * Now that the listener is esablished, create the addr info for 113773143b9aSmrg * this connection. getpeername() doesn't work for UNIX Domain Sockets 113873143b9aSmrg * on some systems (hpux at least), so we will just do it manually, instead 113973143b9aSmrg * of calling something like TRANS(SocketUNIXGetAddr). 114073143b9aSmrg */ 114173143b9aSmrg 114273143b9aSmrg namelen = sizeof (sockname); /* this will always make it the same size */ 114373143b9aSmrg 114473143b9aSmrg if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) 114573143b9aSmrg { 114673143b9aSmrg PRMSG (1, 114773143b9aSmrg "SocketUNIXCreateListener: Can't allocate space for the addr\n", 114873143b9aSmrg 0, 0, 0); 114973143b9aSmrg (void) umask (oldUmask); 115073143b9aSmrg return TRANS_CREATE_LISTENER_FAILED; 115173143b9aSmrg } 115273143b9aSmrg 115373143b9aSmrg if (abstract) 115473143b9aSmrg sockname.sun_path[0] = '@'; 115573143b9aSmrg 115673143b9aSmrg ciptr->family = sockname.sun_family; 115773143b9aSmrg ciptr->addrlen = namelen; 115873143b9aSmrg memcpy (ciptr->addr, &sockname, ciptr->addrlen); 115973143b9aSmrg 116073143b9aSmrg (void) umask (oldUmask); 116173143b9aSmrg 116273143b9aSmrg return 0; 116373143b9aSmrg} 116473143b9aSmrg 116573143b9aSmrg 116673143b9aSmrgstatic int 116773143b9aSmrgTRANS(SocketUNIXResetListener) (XtransConnInfo ciptr) 116873143b9aSmrg 116973143b9aSmrg{ 117073143b9aSmrg /* 117173143b9aSmrg * See if the unix domain socket has disappeared. If it has, recreate it. 117273143b9aSmrg */ 117373143b9aSmrg 117473143b9aSmrg struct sockaddr_un *unsock = (struct sockaddr_un *) ciptr->addr; 117573143b9aSmrg struct stat statb; 117673143b9aSmrg int status = TRANS_RESET_NOOP; 117773143b9aSmrg unsigned int mode; 117873143b9aSmrg int abstract = 0; 117973143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 118073143b9aSmrg abstract = ciptr->transptr->flags & TRANS_ABSTRACT; 118173143b9aSmrg#endif 118273143b9aSmrg 118373143b9aSmrg PRMSG (3, "SocketUNIXResetListener(%p,%d)\n", ciptr, ciptr->fd, 0); 118473143b9aSmrg 118573143b9aSmrg if (!abstract && ( 118673143b9aSmrg stat (unsock->sun_path, &statb) == -1 || 118773143b9aSmrg ((statb.st_mode & S_IFMT) != 1188e8a71cdfSmrg#if defined(NCR) || defined(SCO325) || !defined(S_IFSOCK) 118973143b9aSmrg S_IFIFO 119073143b9aSmrg#else 119173143b9aSmrg S_IFSOCK 119273143b9aSmrg#endif 119373143b9aSmrg ))) 119473143b9aSmrg { 119573143b9aSmrg int oldUmask = umask (0); 119673143b9aSmrg 119773143b9aSmrg#ifdef UNIX_DIR 119873143b9aSmrg#ifdef HAS_STICKY_DIR_BIT 119973143b9aSmrg mode = 01777; 120073143b9aSmrg#else 120173143b9aSmrg mode = 0777; 120273143b9aSmrg#endif 120373143b9aSmrg if (trans_mkdir(UNIX_DIR, mode) == -1) { 120473143b9aSmrg PRMSG (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n", 120573143b9aSmrg UNIX_DIR, errno, 0); 120673143b9aSmrg (void) umask (oldUmask); 120773143b9aSmrg return TRANS_RESET_FAILURE; 120873143b9aSmrg } 120973143b9aSmrg#endif 121073143b9aSmrg 121173143b9aSmrg close (ciptr->fd); 121273143b9aSmrg unlink (unsock->sun_path); 121373143b9aSmrg 121473143b9aSmrg if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) 121573143b9aSmrg { 121673143b9aSmrg TRANS(FreeConnInfo) (ciptr); 121773143b9aSmrg (void) umask (oldUmask); 121873143b9aSmrg return TRANS_RESET_FAILURE; 121973143b9aSmrg } 122073143b9aSmrg 122173143b9aSmrg if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0) 122273143b9aSmrg { 122373143b9aSmrg close (ciptr->fd); 122473143b9aSmrg TRANS(FreeConnInfo) (ciptr); 122573143b9aSmrg return TRANS_RESET_FAILURE; 122673143b9aSmrg } 122773143b9aSmrg 122873143b9aSmrg if (listen (ciptr->fd, BACKLOG) < 0) 122973143b9aSmrg { 123073143b9aSmrg close (ciptr->fd); 123173143b9aSmrg TRANS(FreeConnInfo) (ciptr); 123273143b9aSmrg (void) umask (oldUmask); 123373143b9aSmrg return TRANS_RESET_FAILURE; 123473143b9aSmrg } 123573143b9aSmrg 123673143b9aSmrg umask (oldUmask); 123773143b9aSmrg 123873143b9aSmrg status = TRANS_RESET_NEW_FD; 123973143b9aSmrg } 124073143b9aSmrg 124173143b9aSmrg return status; 124273143b9aSmrg} 124373143b9aSmrg 124473143b9aSmrg#endif /* UNIXCONN */ 124573143b9aSmrg 124673143b9aSmrg 124773143b9aSmrg#ifdef TCPCONN 124873143b9aSmrg 124973143b9aSmrgstatic XtransConnInfo 125073143b9aSmrgTRANS(SocketINETAccept) (XtransConnInfo ciptr, int *status) 125173143b9aSmrg 125273143b9aSmrg{ 125373143b9aSmrg XtransConnInfo newciptr; 125473143b9aSmrg struct sockaddr_in sockname; 125573143b9aSmrg SOCKLEN_T namelen = sizeof(sockname); 125673143b9aSmrg 125773143b9aSmrg PRMSG (2, "SocketINETAccept(%p,%d)\n", ciptr, ciptr->fd, 0); 125873143b9aSmrg 125973143b9aSmrg if ((newciptr = (XtransConnInfo) xcalloc ( 126073143b9aSmrg 1, sizeof(struct _XtransConnInfo))) == NULL) 126173143b9aSmrg { 126273143b9aSmrg PRMSG (1, "SocketINETAccept: malloc failed\n", 0, 0, 0); 126373143b9aSmrg *status = TRANS_ACCEPT_BAD_MALLOC; 126473143b9aSmrg return NULL; 126573143b9aSmrg } 126673143b9aSmrg 126773143b9aSmrg if ((newciptr->fd = accept (ciptr->fd, 126873143b9aSmrg (struct sockaddr *) &sockname, (void *)&namelen)) < 0) 126973143b9aSmrg { 127073143b9aSmrg#ifdef WIN32 127173143b9aSmrg errno = WSAGetLastError(); 127273143b9aSmrg#endif 127373143b9aSmrg PRMSG (1, "SocketINETAccept: accept() failed\n", 0, 0, 0); 127473143b9aSmrg xfree (newciptr); 127573143b9aSmrg *status = TRANS_ACCEPT_FAILED; 127673143b9aSmrg return NULL; 127773143b9aSmrg } 127873143b9aSmrg 127973143b9aSmrg#ifdef TCP_NODELAY 128073143b9aSmrg { 128173143b9aSmrg /* 128273143b9aSmrg * turn off TCP coalescence for INET sockets 128373143b9aSmrg */ 128473143b9aSmrg 128573143b9aSmrg int tmp = 1; 128673143b9aSmrg setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY, 128773143b9aSmrg (char *) &tmp, sizeof (int)); 128873143b9aSmrg } 128973143b9aSmrg#endif 129073143b9aSmrg 129173143b9aSmrg /* 129273143b9aSmrg * Get this address again because the transport may give a more 129373143b9aSmrg * specific address now that a connection is established. 129473143b9aSmrg */ 129573143b9aSmrg 129673143b9aSmrg if (TRANS(SocketINETGetAddr) (newciptr) < 0) 129773143b9aSmrg { 129873143b9aSmrg PRMSG (1, 129973143b9aSmrg "SocketINETAccept: ...SocketINETGetAddr() failed:\n", 130073143b9aSmrg 0, 0, 0); 130173143b9aSmrg close (newciptr->fd); 130273143b9aSmrg xfree (newciptr); 130373143b9aSmrg *status = TRANS_ACCEPT_MISC_ERROR; 130473143b9aSmrg return NULL; 130573143b9aSmrg } 130673143b9aSmrg 130773143b9aSmrg if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0) 130873143b9aSmrg { 130973143b9aSmrg PRMSG (1, 131073143b9aSmrg "SocketINETAccept: ...SocketINETGetPeerAddr() failed:\n", 131173143b9aSmrg 0, 0, 0); 131273143b9aSmrg close (newciptr->fd); 131373143b9aSmrg if (newciptr->addr) xfree (newciptr->addr); 131473143b9aSmrg xfree (newciptr); 131573143b9aSmrg *status = TRANS_ACCEPT_MISC_ERROR; 131673143b9aSmrg return NULL; 131773143b9aSmrg } 131873143b9aSmrg 131973143b9aSmrg *status = 0; 132073143b9aSmrg 132173143b9aSmrg return newciptr; 132273143b9aSmrg} 132373143b9aSmrg 132473143b9aSmrg#endif /* TCPCONN */ 132573143b9aSmrg 132673143b9aSmrg 132773143b9aSmrg#ifdef UNIXCONN 132873143b9aSmrgstatic XtransConnInfo 132973143b9aSmrgTRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) 133073143b9aSmrg 133173143b9aSmrg{ 133273143b9aSmrg XtransConnInfo newciptr; 133373143b9aSmrg struct sockaddr_un sockname; 133473143b9aSmrg SOCKLEN_T namelen = sizeof sockname; 133573143b9aSmrg 133673143b9aSmrg PRMSG (2, "SocketUNIXAccept(%p,%d)\n", ciptr, ciptr->fd, 0); 133773143b9aSmrg 133873143b9aSmrg if ((newciptr = (XtransConnInfo) xcalloc ( 133973143b9aSmrg 1, sizeof(struct _XtransConnInfo))) == NULL) 134073143b9aSmrg { 134173143b9aSmrg PRMSG (1, "SocketUNIXAccept: malloc() failed\n", 0, 0, 0); 134273143b9aSmrg *status = TRANS_ACCEPT_BAD_MALLOC; 134373143b9aSmrg return NULL; 134473143b9aSmrg } 134573143b9aSmrg 134673143b9aSmrg if ((newciptr->fd = accept (ciptr->fd, 134773143b9aSmrg (struct sockaddr *) &sockname, (void *)&namelen)) < 0) 134873143b9aSmrg { 134973143b9aSmrg PRMSG (1, "SocketUNIXAccept: accept() failed\n", 0, 0, 0); 135073143b9aSmrg xfree (newciptr); 135173143b9aSmrg *status = TRANS_ACCEPT_FAILED; 135273143b9aSmrg return NULL; 135373143b9aSmrg } 135473143b9aSmrg 135573143b9aSmrg ciptr->addrlen = namelen; 135673143b9aSmrg /* 135773143b9aSmrg * Get the socket name and the peer name from the listener socket, 135873143b9aSmrg * since this is unix domain. 135973143b9aSmrg */ 136073143b9aSmrg 136173143b9aSmrg if ((newciptr->addr = (char *) xalloc (ciptr->addrlen)) == NULL) 136273143b9aSmrg { 136373143b9aSmrg PRMSG (1, 136473143b9aSmrg "SocketUNIXAccept: Can't allocate space for the addr\n", 136573143b9aSmrg 0, 0, 0); 136673143b9aSmrg close (newciptr->fd); 136773143b9aSmrg xfree (newciptr); 136873143b9aSmrg *status = TRANS_ACCEPT_BAD_MALLOC; 136973143b9aSmrg return NULL; 137073143b9aSmrg } 137173143b9aSmrg 137273143b9aSmrg /* 137373143b9aSmrg * if the socket is abstract, we already modified the address to have a 137473143b9aSmrg * @ instead of the initial NUL, so no need to do that again here. 137573143b9aSmrg */ 137673143b9aSmrg 137773143b9aSmrg newciptr->addrlen = ciptr->addrlen; 137873143b9aSmrg memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen); 137973143b9aSmrg 138073143b9aSmrg if ((newciptr->peeraddr = (char *) xalloc (ciptr->addrlen)) == NULL) 138173143b9aSmrg { 138273143b9aSmrg PRMSG (1, 138373143b9aSmrg "SocketUNIXAccept: Can't allocate space for the addr\n", 138473143b9aSmrg 0, 0, 0); 138573143b9aSmrg close (newciptr->fd); 138673143b9aSmrg if (newciptr->addr) xfree (newciptr->addr); 138773143b9aSmrg xfree (newciptr); 138873143b9aSmrg *status = TRANS_ACCEPT_BAD_MALLOC; 138973143b9aSmrg return NULL; 139073143b9aSmrg } 139173143b9aSmrg 139273143b9aSmrg newciptr->peeraddrlen = ciptr->addrlen; 139373143b9aSmrg memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen); 139473143b9aSmrg 139573143b9aSmrg newciptr->family = AF_UNIX; 139673143b9aSmrg 139773143b9aSmrg *status = 0; 139873143b9aSmrg 139973143b9aSmrg return newciptr; 140073143b9aSmrg} 140173143b9aSmrg 140273143b9aSmrg#endif /* UNIXCONN */ 140373143b9aSmrg 140473143b9aSmrg#endif /* TRANS_SERVER */ 140573143b9aSmrg 140673143b9aSmrg 140773143b9aSmrg#ifdef TRANS_CLIENT 140873143b9aSmrg 140973143b9aSmrg#ifdef TCPCONN 141073143b9aSmrg 141173143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 141273143b9aSmrgstruct addrlist { 141373143b9aSmrg struct addrinfo * addr; 141473143b9aSmrg struct addrinfo * firstaddr; 141573143b9aSmrg char port[PORTBUFSIZE]; 141673143b9aSmrg char host[MAXHOSTNAMELEN]; 141773143b9aSmrg}; 141873143b9aSmrgstatic struct addrlist *addrlist = NULL; 141973143b9aSmrg#endif 142073143b9aSmrg 142173143b9aSmrg 142273143b9aSmrgstatic int 142373143b9aSmrgTRANS(SocketINETConnect) (XtransConnInfo ciptr, char *host, char *port) 142473143b9aSmrg 142573143b9aSmrg{ 142673143b9aSmrg struct sockaddr * socketaddr = NULL; 142773143b9aSmrg int socketaddrlen = 0; 142873143b9aSmrg int res; 142973143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 143073143b9aSmrg struct addrinfo hints; 143173143b9aSmrg char ntopbuf[INET6_ADDRSTRLEN]; 143273143b9aSmrg int resetonce = 0; 143373143b9aSmrg#endif 143473143b9aSmrg struct sockaddr_in sockname; 143573143b9aSmrg#ifdef XTHREADS_NEEDS_BYNAMEPARAMS 143673143b9aSmrg _Xgethostbynameparams hparams; 143773143b9aSmrg _Xgetservbynameparams sparams; 143873143b9aSmrg#endif 143973143b9aSmrg struct hostent *hostp; 144073143b9aSmrg struct servent *servp; 144173143b9aSmrg unsigned long tmpaddr; 144273143b9aSmrg#ifdef X11_t 144373143b9aSmrg char portbuf[PORTBUFSIZE]; 144473143b9aSmrg#endif 144573143b9aSmrg 144673143b9aSmrg long tmpport; 144773143b9aSmrg char hostnamebuf[256]; /* tmp space */ 144873143b9aSmrg 144973143b9aSmrg PRMSG (2,"SocketINETConnect(%d,%s,%s)\n", ciptr->fd, host, port); 145073143b9aSmrg 145173143b9aSmrg if (!host) 145273143b9aSmrg { 145373143b9aSmrg hostnamebuf[0] = '\0'; 145473143b9aSmrg (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf); 145573143b9aSmrg host = hostnamebuf; 145673143b9aSmrg } 145773143b9aSmrg 145873143b9aSmrg#ifdef X11_t 145973143b9aSmrg /* 146073143b9aSmrg * X has a well known port, that is transport dependent. It is easier 146173143b9aSmrg * to handle it here, than try and come up with a transport independent 146273143b9aSmrg * representation that can be passed in and resolved the usual way. 146373143b9aSmrg * 146473143b9aSmrg * The port that is passed here is really a string containing the idisplay 146573143b9aSmrg * from ConnectDisplay(). 146673143b9aSmrg */ 146773143b9aSmrg 146873143b9aSmrg if (is_numeric (port)) 146973143b9aSmrg { 147073143b9aSmrg tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10); 147173143b9aSmrg sprintf (portbuf, "%lu", tmpport); 147273143b9aSmrg port = portbuf; 147373143b9aSmrg } 147473143b9aSmrg#endif 147573143b9aSmrg 147673143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 1477b53e5eeaSmrg { 147873143b9aSmrg if (addrlist != NULL) { 147973143b9aSmrg if (strcmp(host,addrlist->host) || strcmp(port,addrlist->port)) { 148073143b9aSmrg if (addrlist->firstaddr) 148173143b9aSmrg freeaddrinfo(addrlist->firstaddr); 148273143b9aSmrg addrlist->firstaddr = NULL; 148373143b9aSmrg } 148473143b9aSmrg } else { 148573143b9aSmrg addrlist = malloc(sizeof(struct addrlist)); 148673143b9aSmrg addrlist->firstaddr = NULL; 148773143b9aSmrg } 148873143b9aSmrg 148973143b9aSmrg if (addrlist->firstaddr == NULL) { 149073143b9aSmrg strncpy(addrlist->port, port, sizeof(addrlist->port)); 149173143b9aSmrg addrlist->port[sizeof(addrlist->port) - 1] = '\0'; 149273143b9aSmrg strncpy(addrlist->host, host, sizeof(addrlist->host)); 149373143b9aSmrg addrlist->host[sizeof(addrlist->host) - 1] = '\0'; 149473143b9aSmrg 149573143b9aSmrg bzero(&hints,sizeof(hints)); 149673143b9aSmrg hints.ai_socktype = Sockettrans2devtab[ciptr->index].devcotsname; 149773143b9aSmrg 149873143b9aSmrg res = getaddrinfo(host,port,&hints,&addrlist->firstaddr); 149973143b9aSmrg if (res != 0) { 150073143b9aSmrg PRMSG (1, "SocketINETConnect() can't get address " 150173143b9aSmrg "for %s:%s: %s\n", host, port, gai_strerror(res)); 150273143b9aSmrg ESET(EINVAL); 150373143b9aSmrg return TRANS_CONNECT_FAILED; 150473143b9aSmrg } 150573143b9aSmrg for (res = 0, addrlist->addr = addrlist->firstaddr; 150673143b9aSmrg addrlist->addr ; res++) { 150773143b9aSmrg addrlist->addr = addrlist->addr->ai_next; 150873143b9aSmrg } 150973143b9aSmrg PRMSG(4,"Got New Address list with %d addresses\n", res, 0, 0); 151073143b9aSmrg res = 0; 151173143b9aSmrg addrlist->addr = NULL; 151273143b9aSmrg } 151373143b9aSmrg 151473143b9aSmrg while (socketaddr == NULL) { 151573143b9aSmrg if (addrlist->addr == NULL) { 151673143b9aSmrg if (resetonce) { 151773143b9aSmrg /* Already checked entire list - no usable addresses */ 151873143b9aSmrg PRMSG (1, "SocketINETConnect() no usable address " 151973143b9aSmrg "for %s:%s\n", host, port, 0); 152073143b9aSmrg return TRANS_CONNECT_FAILED; 152173143b9aSmrg } else { 152273143b9aSmrg /* Go back to beginning of list */ 152373143b9aSmrg resetonce = 1; 152473143b9aSmrg addrlist->addr = addrlist->firstaddr; 152573143b9aSmrg } 152673143b9aSmrg } 152773143b9aSmrg 152873143b9aSmrg socketaddr = addrlist->addr->ai_addr; 152973143b9aSmrg socketaddrlen = addrlist->addr->ai_addrlen; 153073143b9aSmrg 153173143b9aSmrg if (addrlist->addr->ai_family == AF_INET) { 153273143b9aSmrg struct sockaddr_in *sin = (struct sockaddr_in *) socketaddr; 153373143b9aSmrg 153473143b9aSmrg PRMSG (4,"SocketINETConnect() sockname.sin_addr = %s\n", 153573143b9aSmrg inet_ntop(addrlist->addr->ai_family,&sin->sin_addr, 153673143b9aSmrg ntopbuf,sizeof(ntopbuf)), 0, 0); 153773143b9aSmrg 153873143b9aSmrg PRMSG (4,"SocketINETConnect() sockname.sin_port = %d\n", 153973143b9aSmrg ntohs(sin->sin_port), 0, 0); 154073143b9aSmrg 154173143b9aSmrg if (Sockettrans2devtab[ciptr->index].family == AF_INET6) { 154273143b9aSmrg if (strcmp(Sockettrans2devtab[ciptr->index].transname, 154373143b9aSmrg "tcp") == 0) { 154473143b9aSmrg XtransConnInfo newciptr; 154573143b9aSmrg 154673143b9aSmrg /* 154773143b9aSmrg * Our socket is an IPv6 socket, but the address is 154873143b9aSmrg * IPv4. Close it and get an IPv4 socket. This is 154973143b9aSmrg * needed for IPv4 connections to work on platforms 155073143b9aSmrg * that don't allow IPv4 over IPv6 sockets. 155173143b9aSmrg */ 155273143b9aSmrg TRANS(SocketINETClose)(ciptr); 155373143b9aSmrg newciptr = TRANS(SocketOpenCOTSClientBase)( 155473143b9aSmrg "tcp", "tcp", host, port, ciptr->index); 155573143b9aSmrg if (newciptr) 155673143b9aSmrg ciptr->fd = newciptr->fd; 155773143b9aSmrg if (!newciptr || 155873143b9aSmrg Sockettrans2devtab[newciptr->index].family != 155973143b9aSmrg AF_INET) { 156073143b9aSmrg socketaddr = NULL; 156173143b9aSmrg PRMSG (4,"SocketINETConnect() Cannot get IPv4 " 156273143b9aSmrg " socketfor IPv4 address\n", 0,0,0); 156373143b9aSmrg } 156473143b9aSmrg if (newciptr) 156573143b9aSmrg xfree(newciptr); 156673143b9aSmrg } else { 156773143b9aSmrg socketaddr = NULL; 156873143b9aSmrg PRMSG (4,"SocketINETConnect Skipping IPv4 address\n", 156973143b9aSmrg 0,0,0); 157073143b9aSmrg } 157173143b9aSmrg } 157273143b9aSmrg } else if (addrlist->addr->ai_family == AF_INET6) { 157373143b9aSmrg struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) socketaddr; 157473143b9aSmrg 157573143b9aSmrg PRMSG (4,"SocketINETConnect() sockname.sin6_addr = %s\n", 157673143b9aSmrg inet_ntop(addrlist->addr->ai_family, 157773143b9aSmrg &sin6->sin6_addr,ntopbuf,sizeof(ntopbuf)), 157873143b9aSmrg 0, 0); 157973143b9aSmrg PRMSG (4,"SocketINETConnect() sockname.sin6_port = %d\n", 158073143b9aSmrg ntohs(sin6->sin6_port), 0, 0); 158173143b9aSmrg 158273143b9aSmrg if (Sockettrans2devtab[ciptr->index].family == AF_INET) { 158373143b9aSmrg if (strcmp(Sockettrans2devtab[ciptr->index].transname, 158473143b9aSmrg "tcp") == 0) { 158573143b9aSmrg XtransConnInfo newciptr; 158673143b9aSmrg 158773143b9aSmrg /* 158873143b9aSmrg * Close the IPv4 socket and try to open an IPv6 socket. 158973143b9aSmrg */ 159073143b9aSmrg TRANS(SocketINETClose)(ciptr); 159173143b9aSmrg newciptr = TRANS(SocketOpenCOTSClientBase)( 159273143b9aSmrg "tcp", "tcp", host, port, -1); 159373143b9aSmrg if (newciptr) 159473143b9aSmrg ciptr->fd = newciptr->fd; 159573143b9aSmrg if (!newciptr || 159673143b9aSmrg Sockettrans2devtab[newciptr->index].family != 159773143b9aSmrg AF_INET6) { 159873143b9aSmrg socketaddr = NULL; 159973143b9aSmrg PRMSG (4,"SocketINETConnect() Cannot get IPv6 " 160073143b9aSmrg "socket for IPv6 address\n", 0,0,0); 160173143b9aSmrg } 160273143b9aSmrg if (newciptr) 160373143b9aSmrg xfree(newciptr); 160473143b9aSmrg } 160573143b9aSmrg else 160673143b9aSmrg { 160773143b9aSmrg socketaddr = NULL; 160873143b9aSmrg PRMSG (4,"SocketINETConnect() Skipping IPv6 address\n", 160973143b9aSmrg 0,0,0); 161073143b9aSmrg } 161173143b9aSmrg } 161273143b9aSmrg } else { 161373143b9aSmrg socketaddr = NULL; /* Unsupported address type */ 161473143b9aSmrg } 161573143b9aSmrg if (socketaddr == NULL) { 161673143b9aSmrg addrlist->addr = addrlist->addr->ai_next; 161773143b9aSmrg } 161873143b9aSmrg } 1619b53e5eeaSmrg } 1620b53e5eeaSmrg#else 162173143b9aSmrg { 162273143b9aSmrg /* 162373143b9aSmrg * Build the socket name. 162473143b9aSmrg */ 162573143b9aSmrg 162673143b9aSmrg#ifdef BSD44SOCKETS 162773143b9aSmrg sockname.sin_len = sizeof (struct sockaddr_in); 162873143b9aSmrg#endif 162973143b9aSmrg sockname.sin_family = AF_INET; 163073143b9aSmrg 163173143b9aSmrg /* 163273143b9aSmrg * fill in sin_addr 163373143b9aSmrg */ 163473143b9aSmrg 163573143b9aSmrg#ifndef INADDR_NONE 163673143b9aSmrg#define INADDR_NONE ((in_addr_t) 0xffffffff) 163773143b9aSmrg#endif 163873143b9aSmrg 163973143b9aSmrg /* check for ww.xx.yy.zz host string */ 164073143b9aSmrg 164173143b9aSmrg if (isascii (host[0]) && isdigit (host[0])) { 164273143b9aSmrg tmpaddr = inet_addr (host); /* returns network byte order */ 164373143b9aSmrg } else { 164473143b9aSmrg tmpaddr = INADDR_NONE; 164573143b9aSmrg } 164673143b9aSmrg 164773143b9aSmrg PRMSG (4,"SocketINETConnect() inet_addr(%s) = %x\n", host, tmpaddr, 0); 164873143b9aSmrg 164973143b9aSmrg if (tmpaddr == INADDR_NONE) { 165073143b9aSmrg if ((hostp = _XGethostbyname(host,hparams)) == NULL) { 165173143b9aSmrg PRMSG (1,"SocketINETConnect: Can't get address for %s\n", 165273143b9aSmrg host, 0, 0); 165373143b9aSmrg ESET(EINVAL); 165473143b9aSmrg return TRANS_CONNECT_FAILED; 165573143b9aSmrg } 165673143b9aSmrg if (hostp->h_addrtype != AF_INET) { /* is IP host? */ 165773143b9aSmrg PRMSG (1,"SocketINETConnect: not INET host%s\n", host, 0, 0); 165873143b9aSmrg ESET(EPROTOTYPE); 165973143b9aSmrg return TRANS_CONNECT_FAILED; 166073143b9aSmrg } 166173143b9aSmrg 166273143b9aSmrg memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr, 166373143b9aSmrg sizeof (sockname.sin_addr)); 166473143b9aSmrg 166573143b9aSmrg } else { 166673143b9aSmrg sockname.sin_addr.s_addr = tmpaddr; 166773143b9aSmrg } 166873143b9aSmrg 166973143b9aSmrg /* 167073143b9aSmrg * fill in sin_port 167173143b9aSmrg */ 167273143b9aSmrg 167373143b9aSmrg /* Check for number in the port string */ 167473143b9aSmrg 167573143b9aSmrg if (!is_numeric (port)) { 167673143b9aSmrg if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) { 167773143b9aSmrg PRMSG (1,"SocketINETConnect: can't get service for %s\n", 167873143b9aSmrg port, 0, 0); 167973143b9aSmrg return TRANS_CONNECT_FAILED; 168073143b9aSmrg } 168173143b9aSmrg sockname.sin_port = htons (servp->s_port); 168273143b9aSmrg } else { 168373143b9aSmrg tmpport = strtol (port, (char**)NULL, 10); 168473143b9aSmrg if (tmpport < 1024 || tmpport > USHRT_MAX) 168573143b9aSmrg return TRANS_CONNECT_FAILED; 168673143b9aSmrg sockname.sin_port = htons (((unsigned short) tmpport)); 168773143b9aSmrg } 168873143b9aSmrg 168973143b9aSmrg PRMSG (4,"SocketINETConnect: sockname.sin_port = %d\n", 169073143b9aSmrg ntohs(sockname.sin_port), 0, 0); 169173143b9aSmrg socketaddr = (struct sockaddr *) &sockname; 169273143b9aSmrg socketaddrlen = sizeof(sockname); 169373143b9aSmrg } 1694b53e5eeaSmrg#endif 169573143b9aSmrg 169673143b9aSmrg /* 169773143b9aSmrg * Turn on socket keepalive so the client process will eventually 169873143b9aSmrg * be notified with a SIGPIPE signal if the display server fails 169973143b9aSmrg * to respond to a periodic transmission of messages 170073143b9aSmrg * on the connected socket. 170173143b9aSmrg * This is useful to avoid hung application processes when the 170273143b9aSmrg * processes are not spawned from the xdm session and 170373143b9aSmrg * the display server terminates abnormally. 170473143b9aSmrg * (Someone turned off the power switch.) 170573143b9aSmrg */ 170673143b9aSmrg 170773143b9aSmrg { 170873143b9aSmrg int tmp = 1; 170973143b9aSmrg setsockopt (ciptr->fd, SOL_SOCKET, SO_KEEPALIVE, 171073143b9aSmrg (char *) &tmp, sizeof (int)); 171173143b9aSmrg } 171273143b9aSmrg 171373143b9aSmrg /* 171473143b9aSmrg * Do the connect() 171573143b9aSmrg */ 171673143b9aSmrg 171773143b9aSmrg if (connect (ciptr->fd, socketaddr, socketaddrlen ) < 0) 171873143b9aSmrg { 171973143b9aSmrg#ifdef WIN32 172073143b9aSmrg int olderrno = WSAGetLastError(); 172173143b9aSmrg#else 172273143b9aSmrg int olderrno = errno; 172373143b9aSmrg#endif 172473143b9aSmrg 172573143b9aSmrg /* 172673143b9aSmrg * If the error was ECONNREFUSED, the server may be overloaded 172773143b9aSmrg * and we should try again. 172873143b9aSmrg * 172973143b9aSmrg * If the error was EWOULDBLOCK or EINPROGRESS then the socket 173073143b9aSmrg * was non-blocking and we should poll using select 173173143b9aSmrg * 173273143b9aSmrg * If the error was EINTR, the connect was interrupted and we 173373143b9aSmrg * should try again. 173473143b9aSmrg * 173573143b9aSmrg * If multiple addresses are found for a host then we should 173673143b9aSmrg * try to connect again with a different address for a larger 173773143b9aSmrg * number of errors that made us quit before, since those 173873143b9aSmrg * could be caused by trying to use an IPv6 address to contact 173973143b9aSmrg * a machine with an IPv4-only server or other reasons that 174073143b9aSmrg * only affect one of a set of addresses. 174173143b9aSmrg */ 174273143b9aSmrg 174373143b9aSmrg if (olderrno == ECONNREFUSED || olderrno == EINTR 174473143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 1745b53e5eeaSmrg || (((addrlist->addr->ai_next != NULL) || 174673143b9aSmrg (addrlist->addr != addrlist->firstaddr)) && 174773143b9aSmrg (olderrno == ENETUNREACH || olderrno == EAFNOSUPPORT || 174873143b9aSmrg olderrno == EADDRNOTAVAIL || olderrno == ETIMEDOUT 174973143b9aSmrg#if defined(EHOSTDOWN) 175073143b9aSmrg || olderrno == EHOSTDOWN 175173143b9aSmrg#endif 175273143b9aSmrg )) 175373143b9aSmrg#endif 175473143b9aSmrg ) 175573143b9aSmrg res = TRANS_TRY_CONNECT_AGAIN; 175673143b9aSmrg else if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS) 175773143b9aSmrg res = TRANS_IN_PROGRESS; 175873143b9aSmrg else 175973143b9aSmrg { 176073143b9aSmrg PRMSG (2,"SocketINETConnect: Can't connect: errno = %d\n", 176173143b9aSmrg olderrno,0, 0); 176273143b9aSmrg 176373143b9aSmrg res = TRANS_CONNECT_FAILED; 176473143b9aSmrg } 176573143b9aSmrg } else { 176673143b9aSmrg res = 0; 176773143b9aSmrg 176873143b9aSmrg 176973143b9aSmrg /* 177073143b9aSmrg * Sync up the address fields of ciptr. 177173143b9aSmrg */ 177273143b9aSmrg 177373143b9aSmrg if (TRANS(SocketINETGetAddr) (ciptr) < 0) 177473143b9aSmrg { 177573143b9aSmrg PRMSG (1, 177673143b9aSmrg "SocketINETConnect: ...SocketINETGetAddr() failed:\n", 177773143b9aSmrg 0, 0, 0); 177873143b9aSmrg res = TRANS_CONNECT_FAILED; 177973143b9aSmrg } 178073143b9aSmrg 178173143b9aSmrg else if (TRANS(SocketINETGetPeerAddr) (ciptr) < 0) 178273143b9aSmrg { 178373143b9aSmrg PRMSG (1, 178473143b9aSmrg "SocketINETConnect: ...SocketINETGetPeerAddr() failed:\n", 178573143b9aSmrg 0, 0, 0); 178673143b9aSmrg res = TRANS_CONNECT_FAILED; 178773143b9aSmrg } 178873143b9aSmrg } 178973143b9aSmrg 179073143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 1791b53e5eeaSmrg if (res != 0) { 179273143b9aSmrg addrlist->addr = addrlist->addr->ai_next; 179373143b9aSmrg } 179473143b9aSmrg#endif 179573143b9aSmrg 179673143b9aSmrg return res; 179773143b9aSmrg} 179873143b9aSmrg 179973143b9aSmrg#endif /* TCPCONN */ 180073143b9aSmrg 180173143b9aSmrg 180273143b9aSmrg 180373143b9aSmrg#ifdef UNIXCONN 180473143b9aSmrg 180573143b9aSmrg/* 180673143b9aSmrg * Make sure 'host' is really local. 180773143b9aSmrg */ 180873143b9aSmrg 180973143b9aSmrgstatic int 181073143b9aSmrgUnixHostReallyLocal (char *host) 181173143b9aSmrg 181273143b9aSmrg{ 181373143b9aSmrg char hostnamebuf[256]; 181473143b9aSmrg 181573143b9aSmrg TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf)); 181673143b9aSmrg 181773143b9aSmrg if (strcmp (hostnamebuf, host) == 0) 181873143b9aSmrg { 181973143b9aSmrg return (1); 1820b53e5eeaSmrg } else { 182173143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 182273143b9aSmrg struct addrinfo *localhostaddr; 182373143b9aSmrg struct addrinfo *otherhostaddr; 182473143b9aSmrg struct addrinfo *i, *j; 182573143b9aSmrg int equiv = 0; 182673143b9aSmrg 182773143b9aSmrg if (getaddrinfo(hostnamebuf, NULL, NULL, &localhostaddr) != 0) 182873143b9aSmrg return 0; 182973143b9aSmrg if (getaddrinfo(host, NULL, NULL, &otherhostaddr) != 0) { 183073143b9aSmrg freeaddrinfo(localhostaddr); 183173143b9aSmrg return 0; 183273143b9aSmrg } 183373143b9aSmrg 183473143b9aSmrg for (i = localhostaddr; i != NULL && equiv == 0; i = i->ai_next) { 183573143b9aSmrg for (j = otherhostaddr; j != NULL && equiv == 0; j = j->ai_next) { 183673143b9aSmrg if (i->ai_family == j->ai_family) { 183773143b9aSmrg if (i->ai_family == AF_INET) { 183873143b9aSmrg struct sockaddr_in *sinA 183973143b9aSmrg = (struct sockaddr_in *) i->ai_addr; 184073143b9aSmrg struct sockaddr_in *sinB 184173143b9aSmrg = (struct sockaddr_in *) j->ai_addr; 184273143b9aSmrg struct in_addr *A = &sinA->sin_addr; 184373143b9aSmrg struct in_addr *B = &sinB->sin_addr; 184473143b9aSmrg 184573143b9aSmrg if (memcmp(A,B,sizeof(struct in_addr)) == 0) { 184673143b9aSmrg equiv = 1; 184773143b9aSmrg } 184873143b9aSmrg } else if (i->ai_family == AF_INET6) { 184973143b9aSmrg struct sockaddr_in6 *sinA 185073143b9aSmrg = (struct sockaddr_in6 *) i->ai_addr; 185173143b9aSmrg struct sockaddr_in6 *sinB 185273143b9aSmrg = (struct sockaddr_in6 *) j->ai_addr; 185373143b9aSmrg struct in6_addr *A = &sinA->sin6_addr; 185473143b9aSmrg struct in6_addr *B = &sinB->sin6_addr; 185573143b9aSmrg 185673143b9aSmrg if (memcmp(A,B,sizeof(struct in6_addr)) == 0) { 185773143b9aSmrg equiv = 1; 185873143b9aSmrg } 185973143b9aSmrg } 186073143b9aSmrg } 186173143b9aSmrg } 186273143b9aSmrg } 186373143b9aSmrg 186473143b9aSmrg freeaddrinfo(localhostaddr); 186573143b9aSmrg freeaddrinfo(otherhostaddr); 186673143b9aSmrg return equiv; 1867b53e5eeaSmrg#else 186873143b9aSmrg /* 186973143b9aSmrg * A host may have more than one network address. If any of the 187073143b9aSmrg * network addresses of 'host' (specified to the connect call) 187173143b9aSmrg * match any of the network addresses of 'hostname' (determined 187273143b9aSmrg * by TRANS(GetHostname)), then the two hostnames are equivalent, 187373143b9aSmrg * and we know that 'host' is really a local host. 187473143b9aSmrg */ 187573143b9aSmrg char specified_local_addr_list[10][4]; 187673143b9aSmrg int scount, equiv, i, j; 187773143b9aSmrg#ifdef XTHREADS_NEEDS_BYNAMEPARAMS 187873143b9aSmrg _Xgethostbynameparams hparams; 187973143b9aSmrg#endif 188073143b9aSmrg struct hostent *hostp; 188173143b9aSmrg 188273143b9aSmrg if ((hostp = _XGethostbyname (host,hparams)) == NULL) 188373143b9aSmrg return (0); 188473143b9aSmrg 188573143b9aSmrg scount = 0; 188673143b9aSmrg while (hostp->h_addr_list[scount] && scount <= 8) 188773143b9aSmrg { 188873143b9aSmrg /* 188973143b9aSmrg * The 2nd call to gethostname() overrides the data 189073143b9aSmrg * from the 1st call, so we must save the address list. 189173143b9aSmrg */ 189273143b9aSmrg 189373143b9aSmrg specified_local_addr_list[scount][0] = 189473143b9aSmrg hostp->h_addr_list[scount][0]; 189573143b9aSmrg specified_local_addr_list[scount][1] = 189673143b9aSmrg hostp->h_addr_list[scount][1]; 189773143b9aSmrg specified_local_addr_list[scount][2] = 189873143b9aSmrg hostp->h_addr_list[scount][2]; 189973143b9aSmrg specified_local_addr_list[scount][3] = 190073143b9aSmrg hostp->h_addr_list[scount][3]; 190173143b9aSmrg scount++; 190273143b9aSmrg } 190373143b9aSmrg if ((hostp = _XGethostbyname (hostnamebuf,hparams)) == NULL) 190473143b9aSmrg return (0); 190573143b9aSmrg 190673143b9aSmrg equiv = 0; 190773143b9aSmrg i = 0; 190873143b9aSmrg 190973143b9aSmrg while (i < scount && !equiv) 191073143b9aSmrg { 191173143b9aSmrg j = 0; 191273143b9aSmrg 191373143b9aSmrg while (hostp->h_addr_list[j]) 191473143b9aSmrg { 191573143b9aSmrg if ((specified_local_addr_list[i][0] == 191673143b9aSmrg hostp->h_addr_list[j][0]) && 191773143b9aSmrg (specified_local_addr_list[i][1] == 191873143b9aSmrg hostp->h_addr_list[j][1]) && 191973143b9aSmrg (specified_local_addr_list[i][2] == 192073143b9aSmrg hostp->h_addr_list[j][2]) && 192173143b9aSmrg (specified_local_addr_list[i][3] == 192273143b9aSmrg hostp->h_addr_list[j][3])) 192373143b9aSmrg { 192473143b9aSmrg /* They're equal, so we're done */ 192573143b9aSmrg 192673143b9aSmrg equiv = 1; 192773143b9aSmrg break; 192873143b9aSmrg } 192973143b9aSmrg 193073143b9aSmrg j++; 193173143b9aSmrg } 193273143b9aSmrg 193373143b9aSmrg i++; 193473143b9aSmrg } 193573143b9aSmrg return (equiv); 1936b53e5eeaSmrg#endif 193773143b9aSmrg } 193873143b9aSmrg} 193973143b9aSmrg 194073143b9aSmrgstatic int 194173143b9aSmrgTRANS(SocketUNIXConnect) (XtransConnInfo ciptr, char *host, char *port) 194273143b9aSmrg 194373143b9aSmrg{ 194473143b9aSmrg struct sockaddr_un sockname; 194573143b9aSmrg SOCKLEN_T namelen; 194673143b9aSmrg 194773143b9aSmrg 194873143b9aSmrg int abstract = 0; 194973143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 195073143b9aSmrg abstract = ciptr->transptr->flags & TRANS_ABSTRACT; 195173143b9aSmrg#endif 195273143b9aSmrg 195373143b9aSmrg PRMSG (2,"SocketUNIXConnect(%d,%s,%s)\n", ciptr->fd, host, port); 195473143b9aSmrg 195573143b9aSmrg /* 195673143b9aSmrg * Make sure 'host' is really local. If not, we return failure. 195773143b9aSmrg * The reason we make this check is because a process may advertise 195873143b9aSmrg * a "local" network ID for which it can accept connections, but if 195973143b9aSmrg * a process on a remote machine tries to connect to this network ID, 196073143b9aSmrg * we know for sure it will fail. 196173143b9aSmrg */ 196273143b9aSmrg 196373143b9aSmrg if (host && *host && host[0]!='/' && strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host)) 196473143b9aSmrg { 196573143b9aSmrg PRMSG (1, 196673143b9aSmrg "SocketUNIXConnect: Cannot connect to non-local host %s\n", 196773143b9aSmrg host, 0, 0); 196873143b9aSmrg return TRANS_CONNECT_FAILED; 196973143b9aSmrg } 197073143b9aSmrg 197173143b9aSmrg 197273143b9aSmrg /* 197373143b9aSmrg * Check the port. 197473143b9aSmrg */ 197573143b9aSmrg 197673143b9aSmrg if (!port || !*port) 197773143b9aSmrg { 197873143b9aSmrg PRMSG (1,"SocketUNIXConnect: Missing port specification\n", 197973143b9aSmrg 0, 0, 0); 198073143b9aSmrg return TRANS_CONNECT_FAILED; 198173143b9aSmrg } 198273143b9aSmrg 198373143b9aSmrg /* 198473143b9aSmrg * Build the socket name. 198573143b9aSmrg */ 198673143b9aSmrg 198773143b9aSmrg sockname.sun_family = AF_UNIX; 198873143b9aSmrg 198973143b9aSmrg if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) { 199073143b9aSmrg PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0); 199173143b9aSmrg return TRANS_CONNECT_FAILED; 199273143b9aSmrg } 199373143b9aSmrg 19948d4c0f7bSmrg#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) 199573143b9aSmrg sockname.sun_len = strlen (sockname.sun_path); 199673143b9aSmrg#endif 199773143b9aSmrg 199873143b9aSmrg#if defined(BSD44SOCKETS) || defined(SUN_LEN) 199973143b9aSmrg namelen = SUN_LEN (&sockname); 200073143b9aSmrg#else 200173143b9aSmrg namelen = strlen (sockname.sun_path) + offsetof(struct sockaddr_un, sun_path); 200273143b9aSmrg#endif 200373143b9aSmrg 200473143b9aSmrg 200573143b9aSmrg 200673143b9aSmrg /* 200773143b9aSmrg * Adjust the socket path if using abstract sockets. 200873143b9aSmrg * Done here because otherwise all the strlen() calls above would fail. 200973143b9aSmrg */ 201073143b9aSmrg 201173143b9aSmrg if (abstract) { 201273143b9aSmrg sockname.sun_path[0] = '\0'; 201373143b9aSmrg } 201473143b9aSmrg 201573143b9aSmrg /* 201673143b9aSmrg * Do the connect() 201773143b9aSmrg */ 201873143b9aSmrg 201973143b9aSmrg if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0) 202073143b9aSmrg { 202173143b9aSmrg int olderrno = errno; 202273143b9aSmrg int connected = 0; 202373143b9aSmrg 202473143b9aSmrg if (!connected) 202573143b9aSmrg { 202673143b9aSmrg errno = olderrno; 202773143b9aSmrg 202873143b9aSmrg /* 202973143b9aSmrg * If the error was ENOENT, the server may be starting up; we used 203073143b9aSmrg * to suggest to try again in this case with 203173143b9aSmrg * TRANS_TRY_CONNECT_AGAIN, but this introduced problems for 203273143b9aSmrg * processes still referencing stale sockets in their environment. 203373143b9aSmrg * Hence, we now return a hard error, TRANS_CONNECT_FAILED, and it 203473143b9aSmrg * is suggested that higher level stacks handle retries on their 203573143b9aSmrg * level when they face a slow starting server. 203673143b9aSmrg * 203773143b9aSmrg * If the error was EWOULDBLOCK or EINPROGRESS then the socket 203873143b9aSmrg * was non-blocking and we should poll using select 203973143b9aSmrg * 204073143b9aSmrg * If the error was EINTR, the connect was interrupted and we 204173143b9aSmrg * should try again. 204273143b9aSmrg */ 204373143b9aSmrg 204473143b9aSmrg if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS) 204573143b9aSmrg return TRANS_IN_PROGRESS; 204673143b9aSmrg else if (olderrno == EINTR) 204773143b9aSmrg return TRANS_TRY_CONNECT_AGAIN; 20488d4c0f7bSmrg else if (olderrno == ENOENT || olderrno == ECONNREFUSED) { 204973143b9aSmrg /* If opening as abstract socket failed, try again normally */ 205073143b9aSmrg if (abstract) { 205173143b9aSmrg ciptr->transptr->flags &= ~(TRANS_ABSTRACT); 205273143b9aSmrg return TRANS_TRY_CONNECT_AGAIN; 205373143b9aSmrg } else { 205473143b9aSmrg return TRANS_CONNECT_FAILED; 205573143b9aSmrg } 205673143b9aSmrg } else { 205773143b9aSmrg PRMSG (2,"SocketUNIXConnect: Can't connect: errno = %d\n", 205873143b9aSmrg EGET(),0, 0); 205973143b9aSmrg 206073143b9aSmrg return TRANS_CONNECT_FAILED; 206173143b9aSmrg } 206273143b9aSmrg } 206373143b9aSmrg } 206473143b9aSmrg 206573143b9aSmrg /* 206673143b9aSmrg * Get the socket name and the peer name from the connect socket, 206773143b9aSmrg * since this is unix domain. 206873143b9aSmrg */ 206973143b9aSmrg 207073143b9aSmrg if ((ciptr->addr = (char *) xalloc(namelen)) == NULL || 207173143b9aSmrg (ciptr->peeraddr = (char *) xalloc(namelen)) == NULL) 207273143b9aSmrg { 207373143b9aSmrg PRMSG (1, 207473143b9aSmrg "SocketUNIXCreateListener: Can't allocate space for the addr\n", 207573143b9aSmrg 0, 0, 0); 207673143b9aSmrg return TRANS_CONNECT_FAILED; 207773143b9aSmrg } 207873143b9aSmrg 207973143b9aSmrg if (abstract) 208073143b9aSmrg sockname.sun_path[0] = '@'; 208173143b9aSmrg 208273143b9aSmrg ciptr->family = AF_UNIX; 208373143b9aSmrg ciptr->addrlen = namelen; 208473143b9aSmrg ciptr->peeraddrlen = namelen; 208573143b9aSmrg memcpy (ciptr->addr, &sockname, ciptr->addrlen); 208673143b9aSmrg memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen); 208773143b9aSmrg 208873143b9aSmrg return 0; 208973143b9aSmrg} 209073143b9aSmrg 209173143b9aSmrg#endif /* UNIXCONN */ 209273143b9aSmrg 209373143b9aSmrg#endif /* TRANS_CLIENT */ 209473143b9aSmrg 209573143b9aSmrg 209673143b9aSmrgstatic int 209773143b9aSmrgTRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) 209873143b9aSmrg 209973143b9aSmrg{ 210073143b9aSmrg PRMSG (2,"SocketBytesReadable(%p,%d,%p)\n", 210173143b9aSmrg ciptr, ciptr->fd, pend); 210273143b9aSmrg#ifdef WIN32 210373143b9aSmrg { 210473143b9aSmrg int ret = ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend); 210573143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 210673143b9aSmrg return ret; 210773143b9aSmrg } 210873143b9aSmrg#else 21098d4c0f7bSmrg#if defined(__i386__) && defined(SYSV) && !defined(SCO325) 211073143b9aSmrg return ioctl (ciptr->fd, I_NREAD, (char *) pend); 211173143b9aSmrg#else 211273143b9aSmrg return ioctl (ciptr->fd, FIONREAD, (char *) pend); 211373143b9aSmrg#endif /* __i386__ && SYSV || _SEQUENT_ && _SOCKET_VERSION == 1 */ 211473143b9aSmrg#endif /* WIN32 */ 211573143b9aSmrg} 211673143b9aSmrg 211773143b9aSmrg 211873143b9aSmrgstatic int 211973143b9aSmrgTRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size) 212073143b9aSmrg 212173143b9aSmrg{ 212273143b9aSmrg PRMSG (2,"SocketRead(%d,%p,%d)\n", ciptr->fd, buf, size); 212373143b9aSmrg 21248d4c0f7bSmrg#if defined(WIN32) 212573143b9aSmrg { 212673143b9aSmrg int ret = recv ((SOCKET)ciptr->fd, buf, size, 0); 212773143b9aSmrg#ifdef WIN32 212873143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 212973143b9aSmrg#endif 213073143b9aSmrg return ret; 213173143b9aSmrg } 213273143b9aSmrg#else 213373143b9aSmrg return read (ciptr->fd, buf, size); 213473143b9aSmrg#endif /* WIN32 */ 213573143b9aSmrg} 213673143b9aSmrg 213773143b9aSmrg 213873143b9aSmrgstatic int 213973143b9aSmrgTRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size) 214073143b9aSmrg 214173143b9aSmrg{ 214273143b9aSmrg PRMSG (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size); 214373143b9aSmrg 21448d4c0f7bSmrg#if defined(WIN32) 214573143b9aSmrg { 214673143b9aSmrg int ret = send ((SOCKET)ciptr->fd, buf, size, 0); 214773143b9aSmrg#ifdef WIN32 214873143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 214973143b9aSmrg#endif 215073143b9aSmrg return ret; 215173143b9aSmrg } 215273143b9aSmrg#else 215373143b9aSmrg return write (ciptr->fd, buf, size); 215473143b9aSmrg#endif /* WIN32 */ 215573143b9aSmrg} 215673143b9aSmrg 215773143b9aSmrg 215873143b9aSmrgstatic int 215973143b9aSmrgTRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size) 216073143b9aSmrg 216173143b9aSmrg{ 216273143b9aSmrg PRMSG (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size); 216373143b9aSmrg 216473143b9aSmrg return READV (ciptr, buf, size); 216573143b9aSmrg} 216673143b9aSmrg 216773143b9aSmrg 216873143b9aSmrgstatic int 216973143b9aSmrgTRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) 217073143b9aSmrg 217173143b9aSmrg{ 217273143b9aSmrg PRMSG (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size); 217373143b9aSmrg 217473143b9aSmrg return WRITEV (ciptr, buf, size); 217573143b9aSmrg} 217673143b9aSmrg 217773143b9aSmrg 217873143b9aSmrgstatic int 217973143b9aSmrgTRANS(SocketDisconnect) (XtransConnInfo ciptr) 218073143b9aSmrg 218173143b9aSmrg{ 218273143b9aSmrg PRMSG (2,"SocketDisconnect(%p,%d)\n", ciptr, ciptr->fd, 0); 218373143b9aSmrg 218473143b9aSmrg#ifdef WIN32 218573143b9aSmrg { 218673143b9aSmrg int ret = shutdown (ciptr->fd, 2); 218773143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 218873143b9aSmrg return ret; 218973143b9aSmrg } 219073143b9aSmrg#else 219173143b9aSmrg return shutdown (ciptr->fd, 2); /* disallow further sends and receives */ 219273143b9aSmrg#endif 219373143b9aSmrg} 219473143b9aSmrg 219573143b9aSmrg 219673143b9aSmrg#ifdef TCPCONN 219773143b9aSmrgstatic int 219873143b9aSmrgTRANS(SocketINETClose) (XtransConnInfo ciptr) 219973143b9aSmrg 220073143b9aSmrg{ 220173143b9aSmrg PRMSG (2,"SocketINETClose(%p,%d)\n", ciptr, ciptr->fd, 0); 220273143b9aSmrg 220373143b9aSmrg#ifdef WIN32 220473143b9aSmrg { 220573143b9aSmrg int ret = close (ciptr->fd); 220673143b9aSmrg if (ret == SOCKET_ERROR) errno = WSAGetLastError(); 220773143b9aSmrg return ret; 220873143b9aSmrg } 220973143b9aSmrg#else 221073143b9aSmrg return close (ciptr->fd); 221173143b9aSmrg#endif 221273143b9aSmrg} 221373143b9aSmrg 221473143b9aSmrg#endif /* TCPCONN */ 221573143b9aSmrg 221673143b9aSmrg 221773143b9aSmrg#ifdef UNIXCONN 221873143b9aSmrgstatic int 221973143b9aSmrgTRANS(SocketUNIXClose) (XtransConnInfo ciptr) 222073143b9aSmrg{ 222173143b9aSmrg /* 222273143b9aSmrg * If this is the server side, then once the socket is closed, 222373143b9aSmrg * it must be unlinked to completely close it 222473143b9aSmrg */ 222573143b9aSmrg 222673143b9aSmrg struct sockaddr_un *sockname = (struct sockaddr_un *) ciptr->addr; 222773143b9aSmrg int ret; 222873143b9aSmrg 222973143b9aSmrg PRMSG (2,"SocketUNIXClose(%p,%d)\n", ciptr, ciptr->fd, 0); 223073143b9aSmrg 223173143b9aSmrg ret = close(ciptr->fd); 223273143b9aSmrg 223373143b9aSmrg if (ciptr->flags 223473143b9aSmrg && sockname 223573143b9aSmrg && sockname->sun_family == AF_UNIX 223673143b9aSmrg && sockname->sun_path[0]) 223773143b9aSmrg { 223873143b9aSmrg if (!(ciptr->flags & TRANS_NOUNLINK 223973143b9aSmrg || ciptr->transptr->flags & TRANS_ABSTRACT)) 224073143b9aSmrg unlink (sockname->sun_path); 224173143b9aSmrg } 224273143b9aSmrg 224373143b9aSmrg return ret; 224473143b9aSmrg} 224573143b9aSmrg 224673143b9aSmrgstatic int 224773143b9aSmrgTRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr) 224873143b9aSmrg 224973143b9aSmrg{ 225073143b9aSmrg /* 225173143b9aSmrg * Don't unlink path. 225273143b9aSmrg */ 225373143b9aSmrg 225473143b9aSmrg int ret; 225573143b9aSmrg 225673143b9aSmrg PRMSG (2,"SocketUNIXCloseForCloning(%p,%d)\n", 225773143b9aSmrg ciptr, ciptr->fd, 0); 225873143b9aSmrg 225973143b9aSmrg ret = close(ciptr->fd); 226073143b9aSmrg 226173143b9aSmrg return ret; 226273143b9aSmrg} 226373143b9aSmrg 226473143b9aSmrg#endif /* UNIXCONN */ 226573143b9aSmrg 226673143b9aSmrg 226773143b9aSmrg#ifdef TCPCONN 226873143b9aSmrg# ifdef TRANS_SERVER 226973143b9aSmrgstatic char* tcp_nolisten[] = { 227073143b9aSmrg "inet", 227173143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 227273143b9aSmrg "inet6", 227373143b9aSmrg#endif 227473143b9aSmrg NULL 227573143b9aSmrg}; 227673143b9aSmrg# endif 227773143b9aSmrg 227873143b9aSmrgXtransport TRANS(SocketTCPFuncs) = { 227973143b9aSmrg /* Socket Interface */ 228073143b9aSmrg "tcp", 228173143b9aSmrg TRANS_ALIAS, 228273143b9aSmrg#ifdef TRANS_CLIENT 228373143b9aSmrg TRANS(SocketOpenCOTSClient), 228473143b9aSmrg#endif /* TRANS_CLIENT */ 228573143b9aSmrg#ifdef TRANS_SERVER 228673143b9aSmrg tcp_nolisten, 228773143b9aSmrg TRANS(SocketOpenCOTSServer), 228873143b9aSmrg#endif /* TRANS_SERVER */ 228973143b9aSmrg#ifdef TRANS_CLIENT 229073143b9aSmrg TRANS(SocketOpenCLTSClient), 229173143b9aSmrg#endif /* TRANS_CLIENT */ 229273143b9aSmrg#ifdef TRANS_SERVER 229373143b9aSmrg TRANS(SocketOpenCLTSServer), 229473143b9aSmrg#endif /* TRANS_SERVER */ 229573143b9aSmrg#ifdef TRANS_REOPEN 229673143b9aSmrg TRANS(SocketReopenCOTSServer), 229773143b9aSmrg TRANS(SocketReopenCLTSServer), 229873143b9aSmrg#endif 229973143b9aSmrg TRANS(SocketSetOption), 230073143b9aSmrg#ifdef TRANS_SERVER 230173143b9aSmrg TRANS(SocketINETCreateListener), 230273143b9aSmrg NULL, /* ResetListener */ 230373143b9aSmrg TRANS(SocketINETAccept), 230473143b9aSmrg#endif /* TRANS_SERVER */ 230573143b9aSmrg#ifdef TRANS_CLIENT 230673143b9aSmrg TRANS(SocketINETConnect), 230773143b9aSmrg#endif /* TRANS_CLIENT */ 230873143b9aSmrg TRANS(SocketBytesReadable), 230973143b9aSmrg TRANS(SocketRead), 231073143b9aSmrg TRANS(SocketWrite), 231173143b9aSmrg TRANS(SocketReadv), 231273143b9aSmrg TRANS(SocketWritev), 231373143b9aSmrg TRANS(SocketDisconnect), 231473143b9aSmrg TRANS(SocketINETClose), 231573143b9aSmrg TRANS(SocketINETClose), 231673143b9aSmrg }; 231773143b9aSmrg 231873143b9aSmrgXtransport TRANS(SocketINETFuncs) = { 231973143b9aSmrg /* Socket Interface */ 232073143b9aSmrg "inet", 232173143b9aSmrg 0, 232273143b9aSmrg#ifdef TRANS_CLIENT 232373143b9aSmrg TRANS(SocketOpenCOTSClient), 232473143b9aSmrg#endif /* TRANS_CLIENT */ 232573143b9aSmrg#ifdef TRANS_SERVER 232673143b9aSmrg NULL, 232773143b9aSmrg TRANS(SocketOpenCOTSServer), 232873143b9aSmrg#endif /* TRANS_SERVER */ 232973143b9aSmrg#ifdef TRANS_CLIENT 233073143b9aSmrg TRANS(SocketOpenCLTSClient), 233173143b9aSmrg#endif /* TRANS_CLIENT */ 233273143b9aSmrg#ifdef TRANS_SERVER 233373143b9aSmrg TRANS(SocketOpenCLTSServer), 233473143b9aSmrg#endif /* TRANS_SERVER */ 233573143b9aSmrg#ifdef TRANS_REOPEN 233673143b9aSmrg TRANS(SocketReopenCOTSServer), 233773143b9aSmrg TRANS(SocketReopenCLTSServer), 233873143b9aSmrg#endif 233973143b9aSmrg TRANS(SocketSetOption), 234073143b9aSmrg#ifdef TRANS_SERVER 234173143b9aSmrg TRANS(SocketINETCreateListener), 234273143b9aSmrg NULL, /* ResetListener */ 234373143b9aSmrg TRANS(SocketINETAccept), 234473143b9aSmrg#endif /* TRANS_SERVER */ 234573143b9aSmrg#ifdef TRANS_CLIENT 234673143b9aSmrg TRANS(SocketINETConnect), 234773143b9aSmrg#endif /* TRANS_CLIENT */ 234873143b9aSmrg TRANS(SocketBytesReadable), 234973143b9aSmrg TRANS(SocketRead), 235073143b9aSmrg TRANS(SocketWrite), 235173143b9aSmrg TRANS(SocketReadv), 235273143b9aSmrg TRANS(SocketWritev), 235373143b9aSmrg TRANS(SocketDisconnect), 235473143b9aSmrg TRANS(SocketINETClose), 235573143b9aSmrg TRANS(SocketINETClose), 235673143b9aSmrg }; 235773143b9aSmrg 235873143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 235973143b9aSmrgXtransport TRANS(SocketINET6Funcs) = { 236073143b9aSmrg /* Socket Interface */ 236173143b9aSmrg "inet6", 236273143b9aSmrg 0, 236373143b9aSmrg#ifdef TRANS_CLIENT 236473143b9aSmrg TRANS(SocketOpenCOTSClient), 236573143b9aSmrg#endif /* TRANS_CLIENT */ 236673143b9aSmrg#ifdef TRANS_SERVER 236773143b9aSmrg NULL, 236873143b9aSmrg TRANS(SocketOpenCOTSServer), 236973143b9aSmrg#endif /* TRANS_SERVER */ 237073143b9aSmrg#ifdef TRANS_CLIENT 237173143b9aSmrg TRANS(SocketOpenCLTSClient), 237273143b9aSmrg#endif /* TRANS_CLIENT */ 237373143b9aSmrg#ifdef TRANS_SERVER 237473143b9aSmrg TRANS(SocketOpenCLTSServer), 237573143b9aSmrg#endif /* TRANS_SERVER */ 237673143b9aSmrg#ifdef TRANS_REOPEN 237773143b9aSmrg TRANS(SocketReopenCOTSServer), 237873143b9aSmrg TRANS(SocketReopenCLTSServer), 237973143b9aSmrg#endif 238073143b9aSmrg TRANS(SocketSetOption), 238173143b9aSmrg#ifdef TRANS_SERVER 238273143b9aSmrg TRANS(SocketINETCreateListener), 238373143b9aSmrg NULL, /* ResetListener */ 238473143b9aSmrg TRANS(SocketINETAccept), 238573143b9aSmrg#endif /* TRANS_SERVER */ 238673143b9aSmrg#ifdef TRANS_CLIENT 238773143b9aSmrg TRANS(SocketINETConnect), 238873143b9aSmrg#endif /* TRANS_CLIENT */ 238973143b9aSmrg TRANS(SocketBytesReadable), 239073143b9aSmrg TRANS(SocketRead), 239173143b9aSmrg TRANS(SocketWrite), 239273143b9aSmrg TRANS(SocketReadv), 239373143b9aSmrg TRANS(SocketWritev), 239473143b9aSmrg TRANS(SocketDisconnect), 239573143b9aSmrg TRANS(SocketINETClose), 239673143b9aSmrg TRANS(SocketINETClose), 239773143b9aSmrg }; 239873143b9aSmrg#endif /* IPv6 */ 239973143b9aSmrg#endif /* TCPCONN */ 240073143b9aSmrg 240173143b9aSmrg#ifdef UNIXCONN 240273143b9aSmrg#if !defined(LOCALCONN) 240373143b9aSmrgXtransport TRANS(SocketLocalFuncs) = { 240473143b9aSmrg /* Socket Interface */ 240573143b9aSmrg "local", 240673143b9aSmrg#ifdef HAVE_ABSTRACT_SOCKETS 240773143b9aSmrg TRANS_ABSTRACT, 240873143b9aSmrg#else 240973143b9aSmrg 0, 241073143b9aSmrg#endif 241173143b9aSmrg#ifdef TRANS_CLIENT 241273143b9aSmrg TRANS(SocketOpenCOTSClient), 241373143b9aSmrg#endif /* TRANS_CLIENT */ 241473143b9aSmrg#ifdef TRANS_SERVER 241573143b9aSmrg NULL, 241673143b9aSmrg TRANS(SocketOpenCOTSServer), 241773143b9aSmrg#endif /* TRANS_SERVER */ 241873143b9aSmrg#ifdef TRANS_CLIENT 241973143b9aSmrg TRANS(SocketOpenCLTSClient), 242073143b9aSmrg#endif /* TRANS_CLIENT */ 242173143b9aSmrg#ifdef TRANS_SERVER 242273143b9aSmrg TRANS(SocketOpenCLTSServer), 242373143b9aSmrg#endif /* TRANS_SERVER */ 242473143b9aSmrg#ifdef TRANS_REOPEN 242573143b9aSmrg TRANS(SocketReopenCOTSServer), 242673143b9aSmrg TRANS(SocketReopenCLTSServer), 242773143b9aSmrg#endif 242873143b9aSmrg TRANS(SocketSetOption), 242973143b9aSmrg#ifdef TRANS_SERVER 243073143b9aSmrg TRANS(SocketUNIXCreateListener), 243173143b9aSmrg TRANS(SocketUNIXResetListener), 243273143b9aSmrg TRANS(SocketUNIXAccept), 243373143b9aSmrg#endif /* TRANS_SERVER */ 243473143b9aSmrg#ifdef TRANS_CLIENT 243573143b9aSmrg TRANS(SocketUNIXConnect), 243673143b9aSmrg#endif /* TRANS_CLIENT */ 243773143b9aSmrg TRANS(SocketBytesReadable), 243873143b9aSmrg TRANS(SocketRead), 243973143b9aSmrg TRANS(SocketWrite), 244073143b9aSmrg TRANS(SocketReadv), 244173143b9aSmrg TRANS(SocketWritev), 244273143b9aSmrg TRANS(SocketDisconnect), 244373143b9aSmrg TRANS(SocketUNIXClose), 244473143b9aSmrg TRANS(SocketUNIXCloseForCloning), 244573143b9aSmrg }; 244673143b9aSmrg#endif /* !LOCALCONN */ 244773143b9aSmrg# ifdef TRANS_SERVER 244873143b9aSmrg# if !defined(LOCALCONN) 244973143b9aSmrgstatic char* unix_nolisten[] = { "local" , NULL }; 245073143b9aSmrg# endif 245173143b9aSmrg# endif 245273143b9aSmrg 245373143b9aSmrgXtransport TRANS(SocketUNIXFuncs) = { 245473143b9aSmrg /* Socket Interface */ 245573143b9aSmrg "unix", 245673143b9aSmrg#if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS) 245773143b9aSmrg TRANS_ALIAS, 245873143b9aSmrg#else 245973143b9aSmrg 0, 246073143b9aSmrg#endif 246173143b9aSmrg#ifdef TRANS_CLIENT 246273143b9aSmrg TRANS(SocketOpenCOTSClient), 246373143b9aSmrg#endif /* TRANS_CLIENT */ 246473143b9aSmrg#ifdef TRANS_SERVER 246573143b9aSmrg#if !defined(LOCALCONN) 246673143b9aSmrg unix_nolisten, 246773143b9aSmrg#else 246873143b9aSmrg NULL, 246973143b9aSmrg#endif 247073143b9aSmrg TRANS(SocketOpenCOTSServer), 247173143b9aSmrg#endif /* TRANS_SERVER */ 247273143b9aSmrg#ifdef TRANS_CLIENT 247373143b9aSmrg TRANS(SocketOpenCLTSClient), 247473143b9aSmrg#endif /* TRANS_CLIENT */ 247573143b9aSmrg#ifdef TRANS_SERVER 247673143b9aSmrg TRANS(SocketOpenCLTSServer), 247773143b9aSmrg#endif /* TRANS_SERVER */ 247873143b9aSmrg#ifdef TRANS_REOPEN 247973143b9aSmrg TRANS(SocketReopenCOTSServer), 248073143b9aSmrg TRANS(SocketReopenCLTSServer), 248173143b9aSmrg#endif 248273143b9aSmrg TRANS(SocketSetOption), 248373143b9aSmrg#ifdef TRANS_SERVER 248473143b9aSmrg TRANS(SocketUNIXCreateListener), 248573143b9aSmrg TRANS(SocketUNIXResetListener), 248673143b9aSmrg TRANS(SocketUNIXAccept), 248773143b9aSmrg#endif /* TRANS_SERVER */ 248873143b9aSmrg#ifdef TRANS_CLIENT 248973143b9aSmrg TRANS(SocketUNIXConnect), 249073143b9aSmrg#endif /* TRANS_CLIENT */ 249173143b9aSmrg TRANS(SocketBytesReadable), 249273143b9aSmrg TRANS(SocketRead), 249373143b9aSmrg TRANS(SocketWrite), 249473143b9aSmrg TRANS(SocketReadv), 249573143b9aSmrg TRANS(SocketWritev), 249673143b9aSmrg TRANS(SocketDisconnect), 249773143b9aSmrg TRANS(SocketUNIXClose), 249873143b9aSmrg TRANS(SocketUNIXCloseForCloning), 249973143b9aSmrg }; 250073143b9aSmrg 250173143b9aSmrg#endif /* UNIXCONN */ 2502