]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/commitdiff
Replace the hacky 'OSSocket' type with a closure.
authorSimon Tatham <anakin@pobox.com>
Sun, 17 Nov 2013 14:03:55 +0000 (14:03 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 17 Nov 2013 14:03:55 +0000 (14:03 +0000)
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.

git-svn-id: http://svn.tartarus.org/sgt/putty@10068 cda61777-01e9-0310-a592-d414129be87e

network.h
portfwd.c
proxy.c
proxy.h
unix/unix.h
unix/uxnet.c
windows/winnet.c
x11fwd.c

index 5192529b0ab714c8756109f9c763a2d9686ceb06..d35ff00c03e0a0d9ebe7a42e9f98f076e365c314 100644 (file)
--- a/network.h
+++ b/network.h
@@ -25,10 +25,6 @@ typedef struct SockAddr_tag *SockAddr;
 typedef struct socket_function_table **Socket;
 typedef struct plug_function_table **Plug;
 
-#ifndef OSSOCKET_DEFINED
-typedef void *OSSocket;
-#endif
-
 struct socket_function_table {
     Plug(*plug) (Socket s, Plug p);
     /* use a different plug (return the old one) */
@@ -46,6 +42,9 @@ struct socket_function_table {
     const char *(*socket_error) (Socket s);
 };
 
+typedef union { void *p; int i; } accept_ctx_t;
+typedef Socket (*accept_fn_t)(accept_ctx_t ctx, Plug plug);
+
 struct plug_function_table {
     void (*log)(Plug p, int type, SockAddr addr, int port,
                const char *error_msg, int error_code);
@@ -83,9 +82,12 @@ struct plug_function_table {
      * on a socket is cleared or partially cleared. The new backlog
      * size is passed in the `bufsize' parameter.
      */
-    int (*accepting)(Plug p, OSSocket sock);
+    int (*accepting)(Plug p, accept_fn_t constructor, accept_ctx_t ctx);
     /*
-     * returns 0 if the host at address addr is a valid host for connecting or error
+     * `accepting' is called only on listener-type sockets, and is
+     * passed a constructor function+context that will create a fresh
+     * Socket describing the connection. It returns nonzero if it
+     * doesn't want the connection for some reason, or 0 on success.
      */
 };
 
@@ -136,8 +138,6 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
 
 Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, int address_family);
 
-Socket sk_register(OSSocket sock, Plug plug);
-
 #define sk_plug(s,p) (((*s)->plug) (s, p))
 #define sk_close(s) (((*s)->close) (s))
 #define sk_write(s,buf,len) (((*s)->write) (s, buf, len))
@@ -150,7 +150,7 @@ Socket sk_register(OSSocket sock, Plug plug);
 #define plug_closing(p,msg,code,callback) (((*p)->closing) (p, msg, code, callback))
 #define plug_receive(p,urgent,buf,len) (((*p)->receive) (p, urgent, buf, len))
 #define plug_sent(p,bufsize) (((*p)->sent) (p, bufsize))
-#define plug_accepting(p, sock) (((*p)->accepting)(p, sock))
+#define plug_accepting(p, constructor, ctx) (((*p)->accepting)(p, constructor, ctx))
 #endif
 
 /*
index a93bb0660b3e9efd758e3997df29e8acf27f9150..b14458b931e0ac0f639993f5f9ee18189eee4cd6 100644 (file)
--- a/portfwd.c
+++ b/portfwd.c
@@ -411,7 +411,7 @@ const char *pfd_newconnect(Socket *s, char *hostname, int port,
  called when someone connects to the local port
  */
 
-static int pfd_accepting(Plug p, OSSocket sock)
+static int pfd_accepting(Plug p, accept_fn_t constructor, accept_ctx_t ctx)
 {
     static const struct plug_function_table fn_table = {
        pfd_log,
@@ -431,7 +431,7 @@ static int pfd_accepting(Plug p, OSSocket sock)
     pr->c = NULL;
     pr->backhandle = org->backhandle;
 
-    pr->s = s = sk_register(sock, (Plug) pr);
+    pr->s = s = constructor(ctx, (Plug) pr);
     if ((err = sk_socket_error(s)) != NULL) {
        free_portfwd_private(pr);
        return err != NULL;
diff --git a/proxy.c b/proxy.c
index 8a146231036be4c51d7ba77319cb667160ab16af..01eaa34a2746bc1f8f4f87b24e516bda2bc51464 100644 (file)
--- a/proxy.c
+++ b/proxy.c
@@ -261,16 +261,18 @@ static void plug_proxy_sent (Plug p, int bufsize)
     plug_sent(ps->plug, bufsize);
 }
 
-static int plug_proxy_accepting (Plug p, OSSocket sock)
+static int plug_proxy_accepting(Plug p,
+                                accept_fn_t constructor, accept_ctx_t ctx)
 {
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
     if (ps->state != PROXY_STATE_ACTIVE) {
-       ps->accepting_sock = sock;
+       ps->accepting_constructor = constructor;
+       ps->accepting_ctx = ctx;
        return ps->negotiate(ps, PROXY_CHANGE_ACCEPTING);
     }
-    return plug_accepting(ps->plug, sock);
+    return plug_accepting(ps->plug, constructor, ctx);
 }
 
 /*
@@ -617,7 +619,8 @@ int proxy_http_negotiate (Proxy_Socket p, int change)
         * what should we do? close the socket with an appropriate
         * error message?
         */
-       return plug_accepting(p->plug, p->accepting_sock);
+       return plug_accepting(p->plug,
+                              p->accepting_constructor, p->accepting_ctx);
     }
 
     if (change == PROXY_CHANGE_RECEIVE) {
@@ -819,7 +822,8 @@ int proxy_socks4_negotiate (Proxy_Socket p, int change)
         * what should we do? close the socket with an appropriate
         * error message?
         */
-       return plug_accepting(p->plug, p->accepting_sock);
+       return plug_accepting(p->plug,
+                              p->accepting_constructor, p->accepting_ctx);
     }
 
     if (change == PROXY_CHANGE_RECEIVE) {
@@ -958,7 +962,8 @@ int proxy_socks5_negotiate (Proxy_Socket p, int change)
         * what should we do? close the socket with an appropriate
         * error message?
         */
-       return plug_accepting(p->plug, p->accepting_sock);
+       return plug_accepting(p->plug,
+                              p->accepting_constructor, p->accepting_ctx);
     }
 
     if (change == PROXY_CHANGE_RECEIVE) {
@@ -1496,7 +1501,8 @@ int proxy_telnet_negotiate (Proxy_Socket p, int change)
         * what should we do? close the socket with an appropriate
         * error message?
         */
-       return plug_accepting(p->plug, p->accepting_sock);
+       return plug_accepting(p->plug,
+                              p->accepting_constructor, p->accepting_ctx);
     }
 
     if (change == PROXY_CHANGE_RECEIVE) {
diff --git a/proxy.h b/proxy.h
index 10a8c67715d42892d3f93d8e369a226cbee8449f..12b47e16de88d3860faee4ab6d7639a07f77e780 100644 (file)
--- a/proxy.h
+++ b/proxy.h
@@ -78,7 +78,8 @@ struct Socket_proxy_tag {
     int sent_bufsize;
 
     /* accepting */
-    OSSocket accepting_sock;
+    accept_fn_t accepting_constructor;
+    accept_ctx_t accepting_ctx;
 
     /* configuration, used to look up proxy settings */
     Conf *conf;
index c2f9aeb1c3a7b6045aaf5451af7afa7cc3c95068..d43e0ae097a5f273e1b8233eae0b19fdf306bea8 100644 (file)
@@ -24,9 +24,6 @@ struct FontSpec *fontspec_new(const char *name);
 
 typedef void *Context;                 /* FIXME: probably needs changing */
 
-typedef int OSSocket;
-#define OSSOCKET_DEFINED              /* stop network.h using its default */
-
 extern Backend pty_backend;
 
 typedef uint32_t uint32; /* C99: uint32_t defined in stdint.h */
index 9fc649f75d6392a7f3451cba1b089c6f96074058..f15795cf98ad07286083dda3f0f878778aa5cb69 100644 (file)
@@ -490,8 +490,9 @@ static struct socket_function_table tcp_fn_table = {
     sk_tcp_socket_error
 };
 
-Socket sk_register(OSSocket sockfd, Plug plug)
+static Socket sk_tcp_accept(accept_ctx_t ctx, Plug plug)
 {
+    int sockfd = ctx.i;
     Actual_Socket ret;
 
     /*
@@ -1268,6 +1269,7 @@ static int net_select_result(int fd, int event)
             */
            union sockaddr_union su;
            socklen_t addrlen = sizeof(su);
+            accept_ctx_t actx;
            int t;  /* socket of connection */
 
            memset(&su, 0, addrlen);
@@ -1277,11 +1279,12 @@ static int net_select_result(int fd, int event)
            }
 
             nonblock(t);
+            actx.i = t;
 
            if (s->localhost_only &&
                !sockaddr_is_loopback(&su.sa)) {
                close(t);              /* someone let nonlocal through?! */
-           } else if (plug_accepting(s->plug, t)) {
+           } else if (plug_accepting(s->plug, sk_tcp_accept, actx)) {
                close(t);              /* denied or error */
            }
            break;
index 4069c5d8714e0d77b76bcd73b0274760d3cb0976..b6c9fa61a2ddaf3e004d869845fd90d6f2eadb0c 100644 (file)
@@ -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 */
            }
        }
index d848b218481744ab79159b20a73283470c53cdcc..ba729d1816f90a24642891a6197b7a3ac3946c0c 100644 (file)
--- a/x11fwd.c
+++ b/x11fwd.c
@@ -62,7 +62,7 @@ static int dummy_plug_closing
 static int dummy_plug_receive(Plug p, int urgent, char *data, int len)
 { return 1; }
 static void dummy_plug_sent(Plug p, int bufsize) { }
-static int dummy_plug_accepting(Plug p, OSSocket sock) { return 1; }
+static int dummy_plug_accepting(Plug p, accept_fn_t constructor, accept_ctx_t ctx) { return 1; }
 static const struct plug_function_table dummy_plug = {
     dummy_plug_log, dummy_plug_closing, dummy_plug_receive,
     dummy_plug_sent, dummy_plug_accepting