Stop proxying connections to localhost by default; should fix
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 18 Dec 2002 12:18:54 +0000 (12:18 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 18 Dec 2002 12:18:54 +0000 (12:18 +0000)
`x11-proxy-crash'.

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

doc/config.but
network.h
proxy.c
putty.h
settings.c
unix/uxnet.c
windlg.c
winnet.c

index bbe8495..dfe7da5 100644 (file)
@@ -1,4 +1,4 @@
-\versionid $Id: config.but,v 1.45 2002/12/18 11:39:25 simon Exp $
+\versionid $Id: config.but,v 1.46 2002/12/18 12:18:54 simon Exp $
 
 \C{config} Configuring PuTTY
 
@@ -1439,6 +1439,12 @@ from proxying.
 
 This excludes both of the above ranges at once.
 
+Connections to the local host (the host name \c{localhost}, and any
+loopback IP address) are never proxied, even if the proxy exclude
+list does not explicitly contain them. It is very unlikely that this
+behaviour would ever cause problems, but if it does you can change
+it by enabling \q{Consider proxying local host connections}.
+
 \S{config-proxy-auth} Username and password
 
 \cfg{winhelp-topic}{proxy.auth}
index 744492f..17a7321 100644 (file)
--- a/network.h
+++ b/network.h
@@ -76,6 +76,8 @@ void sk_cleanup(void);                       /* called just before program exit */
 
 SockAddr sk_namelookup(char *host, char **canonicalname);
 void sk_getaddr(SockAddr addr, char *buf, int buflen);
+int sk_hostname_is_local(char *name);
+int sk_address_is_local(SockAddr addr);
 enum { ADDRTYPE_IPV4, ADDRTYPE_IPV6 };
 int sk_addrtype(SockAddr addr);
 void sk_addrcopy(SockAddr addr, char *buf);
diff --git a/proxy.c b/proxy.c
index 83bb19f..7c608c9 100644 (file)
--- a/proxy.c
+++ b/proxy.c
@@ -247,6 +247,14 @@ static int proxy_for_destination (SockAddr addr, char * hostname, int port)
     int hostip_len, hostname_len;
     char * exclude_list;
 
+    /*
+     * Check the host name and IP against the hard-coded
+     * representations of `localhost'.
+     */
+    if (!cfg.even_proxy_localhost &&
+       (sk_hostname_is_local(hostname) || sk_address_is_local(addr)))
+       return 0;                      /* do not proxy */
+
     /* we want a string representation of the IP address for comparisons */
     sk_getaddr(addr, hostip, 64);
 
diff --git a/putty.h b/putty.h
index 95f263b..144ed06 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -214,6 +214,7 @@ struct config_tag {
     int tcp_nodelay;
     /* Proxy options */
     char proxy_exclude_list[512];
+    int even_proxy_localhost;
     enum { PROXY_NONE, PROXY_HTTP, PROXY_SOCKS, PROXY_TELNET } proxy_type;
     char proxy_host[512];
     int proxy_port;
index 28b44c0..fe90f11 100644 (file)
@@ -150,6 +150,7 @@ void save_settings(char *section, int do_host, Config * cfg)
 
     /* proxy settings */
     write_setting_s(sesskey, "ProxyExcludeList", cfg->proxy_exclude_list);
+    write_setting_i(sesskey, "ProxyLocalhost", cfg->even_proxy_localhost);
     write_setting_i(sesskey, "ProxyType", cfg->proxy_type);
     write_setting_s(sesskey, "ProxyHost", cfg->proxy_host);
     write_setting_i(sesskey, "ProxyPort", cfg->proxy_port);
@@ -383,6 +384,7 @@ void load_settings(char *section, int do_host, Config * cfg)
     /* proxy settings */
     gpps(sesskey, "ProxyExcludeList", "", cfg->proxy_exclude_list,
         sizeof(cfg->proxy_exclude_list));
+    gppi(sesskey, "ProxyLocalhost", 0, &cfg->even_proxy_localhost);
     gppi(sesskey, "ProxyType", PROXY_NONE, &i); cfg->proxy_type = i;
     gpps(sesskey, "ProxyHost", "proxy", cfg->proxy_host,
         sizeof(cfg->proxy_host));
index 7a9630a..cad943a 100644 (file)
@@ -209,6 +209,26 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen)
 #endif
 }
 
+int sk_hostname_is_local(char *name)
+{
+    return !strcmp(name, "localhost");
+}
+
+int sk_address_is_local(SockAddr addr)
+{
+#ifdef IPV6
+    if (addr->family == AF_INET) {
+#endif
+       struct in_addr a;
+       a.s_addr = htonl(addr->address);
+       return ipv4_is_loopback(a);
+#ifdef IPV6
+    } else {
+       FIXME;  /* someone who can compile for IPV6 had better do this bit */
+    }
+#endif
+}
+
 int sk_addrtype(SockAddr addr)
 {
     return (addr->family == AF_INET ? ADDRTYPE_IPV4 : ADDRTYPE_IPV6);
index 89ead9a..40880ec 100644 (file)
--- a/windlg.c
+++ b/windlg.c
@@ -454,6 +454,7 @@ enum { IDCX_ABOUT =
     IDC_PROXYPORTEDIT,
     IDC_PROXYEXCLUDESTATIC,
     IDC_PROXYEXCLUDEEDIT,
+    IDC_PROXYLOCALHOST,
     IDC_PROXYUSERSTATIC,
     IDC_PROXYUSEREDIT,
     IDC_PROXYPASSSTATIC,
@@ -882,6 +883,7 @@ char *help_context_cmd(int id)
         return "JI(`',`proxy.main')";
       case IDC_PROXYEXCLUDESTATIC:
       case IDC_PROXYEXCLUDEEDIT:
+      case IDC_PROXYLOCALHOST:
         return "JI(`',`proxy.exclude')";
       case IDC_PROXYUSERSTATIC:
       case IDC_PROXYUSEREDIT:
@@ -1349,6 +1351,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess)
     SetDlgItemText(hwnd, IDC_PROXYHOSTEDIT, cfg.proxy_host);
     SetDlgItemInt(hwnd, IDC_PROXYPORTEDIT, cfg.proxy_port, FALSE);
     SetDlgItemText(hwnd, IDC_PROXYEXCLUDEEDIT, cfg.proxy_exclude_list);
+    CheckDlgButton(hwnd, IDC_PROXYLOCALHOST, cfg.even_proxy_localhost);
     SetDlgItemText(hwnd, IDC_PROXYTELNETCMDEDIT, cfg.proxy_telnet_command);
     SetDlgItemText(hwnd, IDC_PROXYUSEREDIT, cfg.proxy_username);
     SetDlgItemText(hwnd, IDC_PROXYPASSEDIT, cfg.proxy_password);
@@ -1868,6 +1871,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
            multiedit(&cp,
                      "&Exclude Hosts/IPs", IDC_PROXYEXCLUDESTATIC,
                      IDC_PROXYEXCLUDEEDIT, 100, NULL);
+           checkbox(&cp, "Consider pro&xying local host connections",
+                    IDC_PROXYLOCALHOST);
            staticedit(&cp, "&Username", IDC_PROXYUSERSTATIC,
                       IDC_PROXYUSEREDIT, 60);
            staticpassedit(&cp, "Pass&word", IDC_PROXYPASSSTATIC,
@@ -3023,6 +3028,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
                        IsDlgButtonChecked(hwnd, IDC_PROXYSOCKSVER4) ? 4 : 5;
                }
                break;
+             case IDC_PROXYLOCALHOST:
+               if (HIWORD(wParam) == BN_CLICKED ||
+                   HIWORD(wParam) == BN_DOUBLECLICKED)
+                   cfg.even_proxy_localhost =
+                   IsDlgButtonChecked(hwnd, IDC_PROXYLOCALHOST);
+               break;
              case IDC_PROXYTYPENONE:
              case IDC_PROXYTYPEHTTP:
              case IDC_PROXYTYPESOCKS:
index 9d3f66c..b66cde6 100644 (file)
--- a/winnet.c
+++ b/winnet.c
@@ -371,6 +371,26 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen)
 #endif
 }
 
+int sk_hostname_is_local(char *name)
+{
+    return !strcmp(name, "localhost");
+}
+
+int sk_address_is_local(SockAddr addr)
+{
+#ifdef IPV6
+    if (addr->family == AF_INET) {
+#endif
+       struct in_addr a;
+       a.s_addr = htonl(addr->address);
+       return ipv4_is_loopback(a);
+#ifdef IPV6
+    } else {
+       FIXME;  /* someone who can compile for IPV6 had better do this bit */
+    }
+#endif
+}
+
 int sk_addrtype(SockAddr addr)
 {
     return (addr->family == AF_INET ? ADDRTYPE_IPV4 : ADDRTYPE_IPV6);