mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
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). [originally from svn r1215]
This commit is contained in:
parent
ac97a0cb1d
commit
4692974d7d
@ -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
|
||||
|
||||
/*
|
||||
|
11
portfwd.c
11
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;
|
||||
|
42
winnet.c
42
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 */
|
||||
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;
|
||||
}
|
||||
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
|
||||
}
|
||||
if (plug_accepting(s->plug, (void*)t)) {
|
||||
closesocket(t); /* denied or error */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user