From bcce45edf1a7576ca73d7841b1079dc1e35c8ff9 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 27 Aug 2001 15:59:37 +0000 Subject: [PATCH] Port forwarding update: local-host-only listening sockets are now done properly (by binding to INADDR_LOOPBACK) instead of hackishly (by binding to INADDR_ANY, looking at the peer address when a connection is accepted, and slamming the connection shut at that point). git-svn-id: svn://svn.tartarus.org/sgt/putty@1215 cda61777-01e9-0310-a592-d414129be87e --- network.h | 6 +++--- portfwd.c | 11 +++-------- winnet.c | 46 ++++++++++++++++++++++++++-------------------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/network.h b/network.h index 0e1420ac..4b7808a3 100644 --- a/network.h +++ b/network.h @@ -54,7 +54,7 @@ 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, struct sockaddr *addr, void *sock); + int (*accepting)(Plug p, void *sock); /* * returns 0 if the host at address addr is a valid host for connecting or error */ @@ -69,7 +69,7 @@ void sk_addr_free(SockAddr addr); Socket sk_new(SockAddr addr, int port, int privport, int oobinline, Plug p); -Socket sk_newlistenner(int port, Plug plug); +Socket sk_newlistener(int port, Plug plug, int local_host_only); Socket sk_register(void *sock, Plug plug); @@ -83,7 +83,7 @@ Socket sk_register(void *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, addr, sock) (((*p)->accepting)(p, addr, sock)) +#define plug_accepting(p, sock) (((*p)->accepting)(p, sock)) #endif /* diff --git a/portfwd.c b/portfwd.c index 43353988..00fc098f 100644 --- a/portfwd.c +++ b/portfwd.c @@ -153,9 +153,8 @@ char *pfd_newconnect(Socket *s, char *hostname, int port, void *c) called when someone connects to the local port */ -static int pfd_accepting(Plug p, struct sockaddr *addr, void *sock) +static int pfd_accepting(Plug p, void *sock) { - /* for now always accept this socket */ static struct plug_function_table fn_table = { pfd_closing, pfd_receive, @@ -163,13 +162,9 @@ static int pfd_accepting(Plug p, struct sockaddr *addr, void *sock) NULL }; struct PFwdPrivate *pr, *org; - struct sockaddr_in *sin = (struct sockaddr_in *)addr; Socket s; char *err; - if (ntohl(sin->sin_addr.s_addr) != 0x7F000001 && !cfg.lport_acceptall) - return 1; /* denied */ - org = (struct PFwdPrivate *)p; pr = (struct PFwdPrivate *) smalloc(sizeof(struct PFwdPrivate)); pr->fn = &fn_table; @@ -205,7 +200,7 @@ static int pfd_accepting(Plug p, struct sockaddr *addr, void *sock) /* Add a new forwarding from port -> desthost:destport - sets up a listenner on the local machine on port + sets up a listener on the local machine on port */ char *pfd_addforward(char *desthost, int destport, int port) { @@ -232,7 +227,7 @@ char *pfd_addforward(char *desthost, int destport, int port) pr->ready = 0; pr->waiting = NULL; - pr->s = s = sk_newlistenner(port, (Plug) pr); + pr->s = s = sk_newlistener(port, (Plug) pr, !cfg.lport_acceptall); if ((err = sk_socket_error(s))) { sfree(pr); return err; diff --git a/winnet.c b/winnet.c index ee2fc3a6..40f416d8 100644 --- a/winnet.c +++ b/winnet.c @@ -570,7 +570,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, return (Socket) ret; } -Socket sk_newlistenner(int port, Plug plug) +Socket sk_newlistener(int port, Plug plug, int local_host_only) { static struct socket_function_table fn_table = { sk_tcp_plug, @@ -627,13 +627,19 @@ Socket sk_newlistenner(int port, Plug plug) if (addr->family == AF_INET6) { memset(&a6, 0, sizeof(a6)); a6.sin6_family = AF_INET6; -/*a6.sin6_addr = in6addr_any; *//* == 0 */ + if (local_host_only) + a6.sin6_addr = in6addr_loopback; + else + a6.sin6_addr = in6addr_any; a6.sin6_port = htons(port); } else #endif { a.sin_family = AF_INET; - a.sin_addr.s_addr = htonl(INADDR_ANY); + if (local_host_only) + a.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + else + a.sin_addr.s_addr = htonl(INADDR_ANY); a.sin_port = htons((short)port); } #ifdef IPV6 @@ -909,23 +915,23 @@ int select_result(WPARAM wParam, LPARAM lParam) return open; case FD_ACCEPT: { - struct sockaddr isa; - int addrlen = sizeof(struct sockaddr); - SOCKET t; /* socket of connection */ - - memset(&isa, 0, sizeof(struct sockaddr)); - err = 0; - t = accept(s->s,&isa,&addrlen); - if (t == INVALID_SOCKET) - { - err = WSAGetLastError(); - if (err == WSATRY_AGAIN) - break; - } - - if (plug_accepting(s->plug, &isa, (void*)t)) { - closesocket(t); // denied or error - } + struct sockaddr isa; + int addrlen = sizeof(struct sockaddr); + SOCKET t; /* socket of connection */ + + memset(&isa, 0, sizeof(struct sockaddr)); + err = 0; + t = accept(s->s,&isa,&addrlen); + if (t == INVALID_SOCKET) + { + err = WSAGetLastError(); + if (err == WSATRY_AGAIN) + break; + } + + if (plug_accepting(s->plug, (void*)t)) { + closesocket(t); /* denied or error */ + } } } -- 2.11.0