mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 11:32:48 -05:00
Replace the hacky 'OSSocket' type with a closure.
The mechanism for constructing a new connection-type Socket when a listening one receives an incoming connection previously worked by passing a platform-specific 'OSSocket' type to the plug_accepting function, which would then call sk_register to wrap it with a proper Socket instance. This is less flexible than ideal, because it presumes that only one kind of OS object might ever need to be turned into a Socket. So I've replaced OSSocket throughout the code base with a pair of parameters consisting of a function pointer and a context such that passing the latter to the former returns the appropriate Socket; this will permit different classes of listening Socket to pass different function pointers. In deference to the reality that OSSockets tend to be small integers or pointer-sized OS handles, I've made the context parameter an int/pointer union that can hold either of those directly, rather than the usual approach of making it a plain 'void *' and requiring a context structure to be dynamically allocated every time. [originally from svn r10068]
This commit is contained in:
@ -835,7 +835,7 @@ static const char *sk_tcp_socket_error(Socket s);
|
||||
|
||||
extern char *do_select(SOCKET skt, int startup);
|
||||
|
||||
Socket sk_register(void *sock, Plug plug)
|
||||
static Socket sk_tcp_accept(accept_ctx_t ctx, Plug plug)
|
||||
{
|
||||
static const struct socket_function_table fn_table = {
|
||||
sk_tcp_plug,
|
||||
@ -872,7 +872,7 @@ Socket sk_register(void *sock, Plug plug)
|
||||
ret->parent = ret->child = NULL;
|
||||
ret->addr = NULL;
|
||||
|
||||
ret->s = (SOCKET)sock;
|
||||
ret->s = (SOCKET)ctx.p;
|
||||
|
||||
if (ret->s == INVALID_SOCKET) {
|
||||
err = p_WSAGetLastError();
|
||||
@ -1660,6 +1660,7 @@ int select_result(WPARAM wParam, LPARAM lParam)
|
||||
#endif
|
||||
int addrlen = sizeof(isa);
|
||||
SOCKET t; /* socket of connection */
|
||||
accept_ctx_t actx;
|
||||
|
||||
memset(&isa, 0, sizeof(isa));
|
||||
err = 0;
|
||||
@ -1670,6 +1671,9 @@ int select_result(WPARAM wParam, LPARAM lParam)
|
||||
if (err == WSATRY_AGAIN)
|
||||
break;
|
||||
}
|
||||
|
||||
actx.p = (void *)t;
|
||||
|
||||
#ifndef NO_IPV6
|
||||
if (isa.ss_family == AF_INET &&
|
||||
s->localhost_only &&
|
||||
@ -1679,7 +1683,7 @@ int select_result(WPARAM wParam, LPARAM lParam)
|
||||
#endif
|
||||
{
|
||||
p_closesocket(t); /* dodgy WinSock let nonlocal through */
|
||||
} else if (plug_accepting(s->plug, (void*)t)) {
|
||||
} else if (plug_accepting(s->plug, sk_tcp_accept, actx)) {
|
||||
p_closesocket(t); /* denied or error */
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user