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