1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Allow sockets to retrieve their local endpoint info.

The peer_info method in the Socket vtable is replaced with
endpoint_info, which takes a boolean indicating which end you're
asking about.

sk_peer_info still exists, as a wrapper on the new sk_endpoint_info.
This commit is contained in:
Simon Tatham 2024-06-26 06:47:53 +01:00
parent f454c84a23
commit 23b15dbc77
9 changed files with 61 additions and 24 deletions

View File

@ -39,7 +39,7 @@ static const char *sk_error_socket_error(Socket *s)
return es->error; return es->error;
} }
static SocketEndpointInfo *sk_error_peer_info(Socket *s) static SocketEndpointInfo *sk_error_endpoint_info(Socket *s, bool peer)
{ {
return NULL; return NULL;
} }
@ -48,7 +48,7 @@ static const SocketVtable ErrorSocket_sockvt = {
.plug = sk_error_plug, .plug = sk_error_plug,
.close = sk_error_close, .close = sk_error_close,
.socket_error = sk_error_socket_error, .socket_error = sk_error_socket_error,
.peer_info = sk_error_peer_info, .endpoint_info = sk_error_endpoint_info,
/* other methods are NULL */ /* other methods are NULL */
}; };

View File

@ -34,7 +34,7 @@ struct SocketVtable {
void (*set_frozen) (Socket *s, bool is_frozen); void (*set_frozen) (Socket *s, bool is_frozen);
/* ignored by tcp, but vital for ssl */ /* ignored by tcp, but vital for ssl */
const char *(*socket_error) (Socket *s); const char *(*socket_error) (Socket *s);
SocketEndpointInfo *(*peer_info) (Socket *s); SocketEndpointInfo *(*endpoint_info) (Socket *s, bool peer);
}; };
typedef union { void *p; int i; } accept_ctx_t; typedef union { void *p; int i; } accept_ctx_t;
@ -297,8 +297,10 @@ static inline void sk_set_frozen(Socket *s, bool is_frozen)
* not NULL, then it is dynamically allocated, and should be freed by * not NULL, then it is dynamically allocated, and should be freed by
* a call to sk_free_endpoint_info(). See below for the definition. * a call to sk_free_endpoint_info(). See below for the definition.
*/ */
static inline SocketEndpointInfo *sk_endpoint_info(Socket *s, bool peer)
{ return s->vt->endpoint_info(s, peer); }
static inline SocketEndpointInfo *sk_peer_info(Socket *s) static inline SocketEndpointInfo *sk_peer_info(Socket *s)
{ return s->vt->peer_info(s); } { return sk_endpoint_info(s, true); }
/* /*
* The structure returned from sk_endpoint_info, and a function to free * The structure returned from sk_endpoint_info, and a function to free

View File

@ -415,6 +415,19 @@ SockAddr *name_lookup(const char *host, int port, char **canonicalname,
} }
} }
static SocketEndpointInfo *sk_proxy_endpoint_info(Socket *s, bool peer)
{
ProxySocket *ps = container_of(s, ProxySocket, sock);
/* We can't reliably find out where we ended up connecting _to_:
* that's at the far end of the proxy, and might be anything. */
if (peer)
return NULL;
/* But we can at least tell where we're coming _from_. */
return sk_endpoint_info(ps->sub_socket, false);
}
static const SocketVtable ProxySocket_sockvt = { static const SocketVtable ProxySocket_sockvt = {
.plug = sk_proxy_plug, .plug = sk_proxy_plug,
.close = sk_proxy_close, .close = sk_proxy_close,
@ -423,7 +436,7 @@ static const SocketVtable ProxySocket_sockvt = {
.write_eof = sk_proxy_write_eof, .write_eof = sk_proxy_write_eof,
.set_frozen = sk_proxy_set_frozen, .set_frozen = sk_proxy_set_frozen,
.socket_error = sk_proxy_socket_error, .socket_error = sk_proxy_socket_error,
.peer_info = NULL, .endpoint_info = sk_proxy_endpoint_info,
}; };
static const PlugVtable ProxySocket_plugvt = { static const PlugVtable ProxySocket_plugvt = {

View File

@ -123,7 +123,7 @@ static const char *sshproxy_socket_error(Socket *s)
return sp->errmsg; return sp->errmsg;
} }
static SocketEndpointInfo *sshproxy_peer_info(Socket *s) static SocketEndpointInfo *sshproxy_endpoint_info(Socket *s, bool peer)
{ {
return NULL; return NULL;
} }
@ -136,7 +136,7 @@ static const SocketVtable SshProxy_sock_vt = {
.write_eof = sshproxy_write_eof, .write_eof = sshproxy_write_eof,
.set_frozen = sshproxy_set_frozen, .set_frozen = sshproxy_set_frozen,
.socket_error = sshproxy_socket_error, .socket_error = sshproxy_socket_error,
.peer_info = sshproxy_peer_info, .endpoint_info = sshproxy_endpoint_info,
}; };
static void sshproxy_eventlog(LogPolicy *lp, const char *event) static void sshproxy_eventlog(LogPolicy *lp, const char *event)

View File

@ -315,6 +315,11 @@ static void fdsocket_select_result_input_error(int fd, int event)
} }
} }
static SocketEndpointInfo *fdsocket_endpoint_info(Socket *s, bool peer)
{
return NULL;
}
static const SocketVtable FdSocket_sockvt = { static const SocketVtable FdSocket_sockvt = {
.plug = fdsocket_plug, .plug = fdsocket_plug,
.close = fdsocket_close, .close = fdsocket_close,
@ -323,7 +328,7 @@ static const SocketVtable FdSocket_sockvt = {
.write_eof = fdsocket_write_eof, .write_eof = fdsocket_write_eof,
.set_frozen = fdsocket_set_frozen, .set_frozen = fdsocket_set_frozen,
.socket_error = fdsocket_socket_error, .socket_error = fdsocket_socket_error,
.peer_info = NULL, .endpoint_info = fdsocket_endpoint_info,
}; };
static void fdsocket_connect_success_callback(void *ctx) static void fdsocket_connect_success_callback(void *ctx)

View File

@ -488,7 +488,7 @@ static size_t sk_net_write(Socket *s, const void *data, size_t len);
static size_t sk_net_write_oob(Socket *s, const void *data, size_t len); static size_t sk_net_write_oob(Socket *s, const void *data, size_t len);
static void sk_net_write_eof(Socket *s); static void sk_net_write_eof(Socket *s);
static void sk_net_set_frozen(Socket *s, bool is_frozen); static void sk_net_set_frozen(Socket *s, bool is_frozen);
static SocketEndpointInfo *sk_net_peer_info(Socket *s); static SocketEndpointInfo *sk_net_endpoint_info(Socket *s, bool peer);
static const char *sk_net_socket_error(Socket *s); static const char *sk_net_socket_error(Socket *s);
static const SocketVtable NetSocket_sockvt = { static const SocketVtable NetSocket_sockvt = {
@ -499,7 +499,7 @@ static const SocketVtable NetSocket_sockvt = {
.write_eof = sk_net_write_eof, .write_eof = sk_net_write_eof,
.set_frozen = sk_net_set_frozen, .set_frozen = sk_net_set_frozen,
.socket_error = sk_net_socket_error, .socket_error = sk_net_socket_error,
.peer_info = sk_net_peer_info, .endpoint_info = sk_net_endpoint_info,
}; };
static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug) static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug)
@ -1494,7 +1494,7 @@ static void sk_net_set_frozen(Socket *sock, bool is_frozen)
uxsel_tell(s); uxsel_tell(s);
} }
static SocketEndpointInfo *sk_net_peer_info(Socket *sock) static SocketEndpointInfo *sk_net_endpoint_info(Socket *sock, bool peer)
{ {
NetSocket *s = container_of(sock, NetSocket, sock); NetSocket *s = container_of(sock, NetSocket, sock);
union sockaddr_union addr; union sockaddr_union addr;
@ -1504,8 +1504,12 @@ static SocketEndpointInfo *sk_net_peer_info(Socket *sock)
#endif #endif
SocketEndpointInfo *pi; SocketEndpointInfo *pi;
if (getpeername(s->s, &addr.sa, &addrlen) < 0) {
int retd = (peer ? getpeername(s->s, &addr.sa, &addrlen) :
getsockname(s->s, &addr.sa, &addrlen));
if (retd < 0)
return NULL; return NULL;
}
pi = snew(SocketEndpointInfo); pi = snew(SocketEndpointInfo);
pi->addressfamily = ADDRTYPE_UNSPEC; pi->addressfamily = ADDRTYPE_UNSPEC;

View File

@ -296,7 +296,7 @@ static const char *sk_handle_socket_error(Socket *s)
return hs->error; return hs->error;
} }
static SocketEndpointInfo *sk_handle_peer_info(Socket *s) static SocketEndpointInfo *sk_handle_endpoint_info(Socket *s, bool peer)
{ {
HandleSocket *hs = container_of(s, HandleSocket, sock); HandleSocket *hs = container_of(s, HandleSocket, sock);
ULONG pid; ULONG pid;
@ -304,6 +304,9 @@ static SocketEndpointInfo *sk_handle_peer_info(Socket *s)
DECL_WINDOWS_FUNCTION(static, BOOL, GetNamedPipeClientProcessId, DECL_WINDOWS_FUNCTION(static, BOOL, GetNamedPipeClientProcessId,
(HANDLE, PULONG)); (HANDLE, PULONG));
if (!peer)
return NULL;
if (!kernel32_module) { if (!kernel32_module) {
kernel32_module = load_system32_dll("kernel32.dll"); kernel32_module = load_system32_dll("kernel32.dll");
#if !HAVE_GETNAMEDPIPECLIENTPROCESSID #if !HAVE_GETNAMEDPIPECLIENTPROCESSID
@ -345,7 +348,7 @@ static const SocketVtable HandleSocket_sockvt = {
.write_eof = sk_handle_write_eof, .write_eof = sk_handle_write_eof,
.set_frozen = sk_handle_set_frozen, .set_frozen = sk_handle_set_frozen,
.socket_error = sk_handle_socket_error, .socket_error = sk_handle_socket_error,
.peer_info = sk_handle_peer_info, .endpoint_info = sk_handle_endpoint_info,
}; };
static void sk_handle_connect_success_callback(void *ctx) static void sk_handle_connect_success_callback(void *ctx)
@ -431,7 +434,8 @@ static void sk_handle_deferred_set_frozen(Socket *s, bool is_frozen)
hs->frozen = is_frozen; hs->frozen = is_frozen;
} }
static SocketEndpointInfo *sk_handle_deferred_peer_info(Socket *s) static SocketEndpointInfo *sk_handle_deferred_endpoint_info(
Socket *s, bool peer)
{ {
return NULL; return NULL;
} }
@ -444,7 +448,7 @@ static const SocketVtable HandleSocket_deferred_sockvt = {
.write_eof = sk_handle_deferred_write_eof, .write_eof = sk_handle_deferred_write_eof,
.set_frozen = sk_handle_deferred_set_frozen, .set_frozen = sk_handle_deferred_set_frozen,
.socket_error = sk_handle_socket_error, .socket_error = sk_handle_socket_error,
.peer_info = sk_handle_deferred_peer_info, .endpoint_info = sk_handle_deferred_endpoint_info,
}; };
Socket *make_deferred_handle_socket(DeferredSocketOpener *opener, Socket *make_deferred_handle_socket(DeferredSocketOpener *opener,

View File

@ -63,7 +63,8 @@ static const char *sk_namedpipeserver_socket_error(Socket *s)
return ps->error; return ps->error;
} }
static SocketEndpointInfo *sk_namedpipeserver_peer_info(Socket *s) static SocketEndpointInfo *sk_namedpipeserver_endpoint_info(
Socket *s, bool peer)
{ {
return NULL; return NULL;
} }
@ -196,7 +197,7 @@ static const SocketVtable NamedPipeServerSocket_sockvt = {
.plug = sk_namedpipeserver_plug, .plug = sk_namedpipeserver_plug,
.close = sk_namedpipeserver_close, .close = sk_namedpipeserver_close,
.socket_error = sk_namedpipeserver_socket_error, .socket_error = sk_namedpipeserver_socket_error,
.peer_info = sk_namedpipeserver_peer_info, .endpoint_info = sk_namedpipeserver_endpoint_info,
}; };
Socket *new_named_pipe_listener(const char *pipename, Plug *plug) Socket *new_named_pipe_listener(const char *pipename, Plug *plug)

View File

@ -209,6 +209,8 @@ DECL_WINDOWS_FUNCTION(static, SOCKET, accept,
(SOCKET, struct sockaddr FAR *, int FAR *)); (SOCKET, struct sockaddr FAR *, int FAR *));
DECL_WINDOWS_FUNCTION(static, int, getpeername, DECL_WINDOWS_FUNCTION(static, int, getpeername,
(SOCKET, struct sockaddr FAR *, int FAR *)); (SOCKET, struct sockaddr FAR *, int FAR *));
DECL_WINDOWS_FUNCTION(static, int, getsockname,
(SOCKET, struct sockaddr FAR *, int FAR *));
DECL_WINDOWS_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int)); DECL_WINDOWS_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int));
DECL_WINDOWS_FUNCTION(static, int, WSAIoctl, DECL_WINDOWS_FUNCTION(static, int, WSAIoctl,
(SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, (SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD,
@ -332,6 +334,7 @@ void sk_init(void)
GET_WINDOWS_FUNCTION(winsock_module, ioctlsocket); GET_WINDOWS_FUNCTION(winsock_module, ioctlsocket);
GET_WINDOWS_FUNCTION(winsock_module, accept); GET_WINDOWS_FUNCTION(winsock_module, accept);
GET_WINDOWS_FUNCTION(winsock_module, getpeername); GET_WINDOWS_FUNCTION(winsock_module, getpeername);
GET_WINDOWS_FUNCTION(winsock_module, getsockname);
GET_WINDOWS_FUNCTION(winsock_module, recv); GET_WINDOWS_FUNCTION(winsock_module, recv);
GET_WINDOWS_FUNCTION(winsock_module, WSAIoctl); GET_WINDOWS_FUNCTION(winsock_module, WSAIoctl);
@ -821,7 +824,7 @@ static size_t sk_net_write_oob(Socket *s, const void *data, size_t len);
static void sk_net_write_eof(Socket *s); static void sk_net_write_eof(Socket *s);
static void sk_net_set_frozen(Socket *s, bool is_frozen); static void sk_net_set_frozen(Socket *s, bool is_frozen);
static const char *sk_net_socket_error(Socket *s); static const char *sk_net_socket_error(Socket *s);
static SocketEndpointInfo *sk_net_peer_info(Socket *s); static SocketEndpointInfo *sk_net_endpoint_info(Socket *s, bool peer);
static const SocketVtable NetSocket_sockvt = { static const SocketVtable NetSocket_sockvt = {
.plug = sk_net_plug, .plug = sk_net_plug,
@ -831,7 +834,7 @@ static const SocketVtable NetSocket_sockvt = {
.write_eof = sk_net_write_eof, .write_eof = sk_net_write_eof,
.set_frozen = sk_net_set_frozen, .set_frozen = sk_net_set_frozen,
.socket_error = sk_net_socket_error, .socket_error = sk_net_socket_error,
.peer_info = sk_net_peer_info, .endpoint_info = sk_net_endpoint_info,
}; };
static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug) static Socket *sk_net_accept(accept_ctx_t ctx, Plug *plug)
@ -1747,7 +1750,7 @@ static const char *sk_net_socket_error(Socket *sock)
return s->error; return s->error;
} }
static SocketEndpointInfo *sk_net_peer_info(Socket *sock) static SocketEndpointInfo *sk_net_endpoint_info(Socket *sock, bool peer)
{ {
NetSocket *s = container_of(sock, NetSocket, sock); NetSocket *s = container_of(sock, NetSocket, sock);
#ifdef NO_IPV6 #ifdef NO_IPV6
@ -1759,8 +1762,13 @@ static SocketEndpointInfo *sk_net_peer_info(Socket *sock)
int addrlen = sizeof(addr); int addrlen = sizeof(addr);
SocketEndpointInfo *pi; SocketEndpointInfo *pi;
if (p_getpeername(s->s, (struct sockaddr *)&addr, &addrlen) < 0) {
int retd = (peer ?
p_getpeername(s->s, (struct sockaddr *)&addr, &addrlen) :
p_getsockname(s->s, (struct sockaddr *)&addr, &addrlen));
if (retd < 0)
return NULL; return NULL;
}
pi = snew(SocketEndpointInfo); pi = snew(SocketEndpointInfo);
pi->addressfamily = ADDRTYPE_UNSPEC; pi->addressfamily = ADDRTYPE_UNSPEC;