mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Support AF_UNIX listening sockets on Windows.
Not all Windows toolchains have this yet, so we have to put the whole lot under #ifdef.
This commit is contained in:
parent
3d15342fe8
commit
018236da29
@ -8,6 +8,7 @@
|
||||
#cmakedefine01 HAVE_WINRES_H
|
||||
#cmakedefine01 HAVE_WIN_H
|
||||
#cmakedefine01 HAVE_NO_STDINT_H
|
||||
#cmakedefine01 HAVE_AFUNIX_H
|
||||
#cmakedefine01 HAVE_GCP_RESULTSW
|
||||
#cmakedefine01 HAVE_ADDDLLDIRECTORY
|
||||
#cmakedefine01 HAVE_GETNAMEDPIPECLIENTPROCESSID
|
||||
|
@ -41,6 +41,8 @@ define_negation(NO_MULTIMON HAVE_MULTIMON_H)
|
||||
check_include_files("windows.h;htmlhelp.h" HAVE_HTMLHELP_H)
|
||||
define_negation(NO_HTMLHELP HAVE_HTMLHELP_H)
|
||||
|
||||
check_include_files("winsock2.h;afunix.h" HAVE_AFUNIX_H)
|
||||
|
||||
check_symbol_exists(strtoumax "inttypes.h" HAVE_STRTOUMAX)
|
||||
check_symbol_exists(AddDllDirectory "windows.h" HAVE_ADDDLLDIRECTORY)
|
||||
check_symbol_exists(SetDefaultDllDirectories "windows.h"
|
||||
|
@ -20,6 +20,10 @@
|
||||
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#if HAVE_AFUNIX_H
|
||||
#include <afunix.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_IPV6
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
@ -83,13 +87,17 @@ struct NetSocket {
|
||||
* Top-level discriminator for SockAddr.
|
||||
*
|
||||
* UNRESOLVED means a host name not yet put through DNS; IP means a
|
||||
* resolved IP address (or list of them); NAMEDPIPE indicates that
|
||||
* resolved IP address (or list of them); UNIX indicates the AF_UNIX
|
||||
* network family (which Windows also has); NAMEDPIPE indicates that
|
||||
* this SockAddr is phony, holding a Windows named pipe pathname
|
||||
* instead of any address WinSock can understand.
|
||||
*/
|
||||
typedef enum SuperFamily {
|
||||
UNRESOLVED,
|
||||
IP,
|
||||
#if HAVE_AFUNIX_H
|
||||
UNIX,
|
||||
#endif
|
||||
NAMEDPIPE
|
||||
} SuperFamily;
|
||||
|
||||
@ -107,9 +115,9 @@ struct SockAddr {
|
||||
|
||||
/*
|
||||
* Which address family this address belongs to. AF_INET for IPv4;
|
||||
* AF_INET6 for IPv6; AF_UNSPEC indicates that name resolution has
|
||||
* not been done and a simple host name is held in this SockAddr
|
||||
* structure.
|
||||
* AF_INET6 for IPv6; AF_UNIX for Unix-domain sockets; AF_UNSPEC
|
||||
* indicates that name resolution has not been done and a simple host
|
||||
* name is held in this SockAddr structure.
|
||||
*/
|
||||
static inline int sockaddr_family(SockAddr *addr, SockAddrStep step)
|
||||
{
|
||||
@ -120,6 +128,10 @@ static inline int sockaddr_family(SockAddr *addr, SockAddrStep step)
|
||||
return step.ai->ai_family;
|
||||
#endif
|
||||
return AF_INET;
|
||||
#if HAVE_AFUNIX_H
|
||||
case UNIX:
|
||||
return AF_UNIX;
|
||||
#endif
|
||||
default:
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
@ -586,6 +598,13 @@ SockAddr *sk_namedpipe_addr(const char *pipename)
|
||||
return sk_special_addr(NAMEDPIPE, pipename);
|
||||
}
|
||||
|
||||
#if HAVE_AFUNIX_H
|
||||
SockAddr *sk_unix_addr(const char *sockpath)
|
||||
{
|
||||
return sk_special_addr(UNIX, sockpath);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool sk_nextaddr(SockAddr *addr, SockAddrStep *step)
|
||||
{
|
||||
#ifndef NO_IPV6
|
||||
@ -670,7 +689,11 @@ static SockAddr sk_extractaddr_tmp(
|
||||
|
||||
bool sk_addr_needs_port(SockAddr *addr)
|
||||
{
|
||||
return addr->superfamily != NAMEDPIPE;
|
||||
return addr->superfamily != NAMEDPIPE
|
||||
#if HAVE_AFUNIX_H
|
||||
&& addr->superfamily != UNIX
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
bool sk_hostname_is_local(const char *name)
|
||||
@ -1132,10 +1155,13 @@ Socket *sk_newlistener_internal(const char *srcaddr, int port, Plug *plug,
|
||||
bool local_host_only, int orig_address_family)
|
||||
{
|
||||
SOCKET s;
|
||||
SOCKADDR_IN a;
|
||||
#ifndef NO_IPV6
|
||||
SOCKADDR_IN6 a6;
|
||||
#endif
|
||||
SOCKADDR_IN a;
|
||||
#if HAVE_AFUNIX_H
|
||||
SOCKADDR_UN au;
|
||||
#endif
|
||||
struct sockaddr *bindaddr;
|
||||
unsigned bindsize;
|
||||
|
||||
@ -1189,6 +1215,9 @@ Socket *sk_newlistener_internal(const char *srcaddr, int port, Plug *plug,
|
||||
|
||||
ret->oobinline = false;
|
||||
|
||||
#if HAVE_AFUNIX_H
|
||||
if (address_family != AF_UNIX)
|
||||
#endif
|
||||
{
|
||||
BOOL on = true;
|
||||
p_setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
|
||||
@ -1261,6 +1290,15 @@ Socket *sk_newlistener_internal(const char *srcaddr, int port, Plug *plug,
|
||||
bindsize = sizeof(a);
|
||||
break;
|
||||
}
|
||||
#if HAVE_AFUNIX_H
|
||||
case AF_UNIX: {
|
||||
au.sun_family = AF_UNIX;
|
||||
strncpy(au.sun_path, srcaddr, sizeof(au.sun_path));
|
||||
bindaddr = (struct sockaddr *)&au;
|
||||
bindsize = sizeof(au);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
unreachable("bad address family in sk_newlistener_internal");
|
||||
}
|
||||
@ -1337,6 +1375,16 @@ Socket *sk_newlistener(const char *srcaddr, int port, Plug *plug,
|
||||
address_family);
|
||||
}
|
||||
|
||||
Socket *sk_newlistener_unix(const char *path, Plug *plug)
|
||||
{
|
||||
#if HAVE_AFUNIX_H
|
||||
return sk_newlistener_internal(path, 0, plug, false, AF_UNIX);
|
||||
#else
|
||||
return new_error_socket_fmt(
|
||||
plug, "AF_UNIX support not compiled into this program");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void sk_net_close(Socket *sock)
|
||||
{
|
||||
NetSocket *s = container_of(sock, NetSocket, sock);
|
||||
@ -1676,7 +1724,7 @@ void select_result(WPARAM wParam, LPARAM lParam)
|
||||
#ifdef NO_IPV6
|
||||
struct sockaddr_in isa;
|
||||
#else
|
||||
struct sockaddr_storage isa;
|
||||
struct sockaddr_storage isa; // FIXME: also if Unix and no IPv6
|
||||
#endif
|
||||
int addrlen = sizeof(isa);
|
||||
SOCKET t; /* socket of connection */
|
||||
@ -1732,7 +1780,7 @@ static SocketPeerInfo *sk_net_peer_info(Socket *sock)
|
||||
#ifdef NO_IPV6
|
||||
struct sockaddr_in addr;
|
||||
#else
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_storage addr; // FIXME: also if Unix and no IPv6
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
#endif
|
||||
int addrlen = sizeof(addr);
|
||||
@ -1851,7 +1899,7 @@ SockAddr *platform_get_x11_unix_address(const char *display, int displaynum)
|
||||
{
|
||||
SockAddr *ret = snew(SockAddr);
|
||||
memset(ret, 0, sizeof(SockAddr));
|
||||
ret->error = "unix sockets not supported on this platform";
|
||||
ret->error = "unix sockets for X11 not supported on this platform";
|
||||
ret->refcount = 1;
|
||||
return ret;
|
||||
}
|
||||
|
@ -293,6 +293,7 @@ void socket_reselect_all(void);
|
||||
SockAddr *sk_namedpipe_addr(const char *pipename);
|
||||
/* Turn a WinSock error code into a string. */
|
||||
const char *winsock_error_string(int error);
|
||||
Socket *sk_newlistener_unix(const char *socketpath, Plug *plug);
|
||||
|
||||
/*
|
||||
* network.c dynamically loads WinSock 2 or WinSock 1 depending on
|
||||
|
Loading…
Reference in New Issue
Block a user