]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Updates to proxy support, both from me and from Justin Bradford.
authorSimon Tatham <anakin@pobox.com>
Wed, 27 Mar 2002 21:09:16 +0000 (21:09 +0000)
committerSimon Tatham <anakin@pobox.com>
Wed, 27 Mar 2002 21:09:16 +0000 (21:09 +0000)
Removed unnecessary spin locks, added a few comments, added support
for Telnet-type proxies, and wrote some documentation.

[originally from svn r1607]

LICENCE
doc/config.but
doc/licence.but
pageant.rc
proxy.c
proxy.h
puttygen.rc
settings.c
win_res.rc

diff --git a/LICENCE b/LICENCE
index f1c941678135067278cd044341af9275d7f17f05..a413db18c95319da98b5ef4f9487e017892e0587 100644 (file)
--- a/LICENCE
+++ b/LICENCE
@@ -2,7 +2,7 @@ PuTTY is copyright 1997-2001 Simon Tatham.
 
 Portions copyright Robert de Bath, Joris van Rantwijk, Delian
 Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
 
 Portions copyright Robert de Bath, Joris van Rantwijk, Delian
 Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
-and CORE SDI S.A.
+Justin Bradford, and CORE SDI S.A.
 
 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation files
 
 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation files
index 04dd0d01a892428684f504a687c7235ba5d736bd..84fe24af635ef6b32f2bf101ba11844ea5367d8a 100644 (file)
@@ -1,4 +1,4 @@
-\versionid $Id: config.but,v 1.29 2002/03/09 17:59:15 simon Exp $
+\versionid $Id: config.but,v 1.30 2002/03/27 21:09:16 simon Exp $
 
 \C{config} Configuring PuTTY
 
 
 \C{config} Configuring PuTTY
 
@@ -1357,6 +1357,96 @@ types of server.
 
 The Nagle algorithm is disabled by default.
 
 
 The Nagle algorithm is disabled by default.
 
+\H{config-proxy} The Proxy panel
+
+The Proxy panel allows you to configure PuTTY to use various types
+of proxy in order to make its network connections. The settings in
+this panel affect the primary network connection forming your PuTTY
+session, but also any extra connections made as a result of SSH port
+forwarding (see \k{using-port-forwarding}).
+
+\S{config-proxy-type} Setting the proxy type
+
+The \q{Proxy type} radio buttons allow you to configure what type of
+proxy you want PuTTY to use for its network connections. The default
+setting is \q{None}; in this mode no proxy is used for any
+connection.
+
+\b Selecting \q{HTTP} allows you to proxy your connections through a
+web server supporting the HTTP \cw{CONNECT} command, as documented
+in \W{http://www.ietf.org/rfc/rfc2817.txt}{RFC 2817}.
+
+\b Selecting \q{SOCKS} allows you to proxy your connections through
+a SOCKS server.
+
+\b Many firewalls implement a less formal type of proxy in which a
+user can make a Telnet connection directly to the firewall machine
+and enter a command such as \c{connect myhost.com 22} to connect
+through to an external host. Selecting \q{Telnet} allows you to tell
+PuTTY to use this type of proxy.
+
+Note [FIXME] that SOCKS is not yet supported, although it should be
+by the time we make our next release.
+
+\S{config-proxy-exclude} Excluding parts of the network from proxying
+
+Typically you will only need to use a proxy to connect to non-local
+parts of your network; for example, your proxy might be required for
+connections outside your company's internal network. In the
+\q{Exclude Hosts/IPs} box you can enter ranges of IP addresses, or
+ranges of DNS names, for which PuTTY will avoid using the proxy and
+make a direct connection instead.
+
+The \q{Exclude Hosts/IPs} box may contain more than one exclusion
+range, separated by commas. Each range can be an IP address or a DNS
+name, with a \c{*} character allowing wildcards. For example:
+
+\c *.example.com
+
+This excludes any host with a name ending in \c{.example.com} from
+proxying.
+
+\c 192.168.88.*
+
+This excludes any host with an IP address starting with 192.168.88
+from proxying.
+
+\c 192.168.88.*,*.example.com
+
+This excludes both of the above ranges at once.
+
+\S{config-proxy-auth} Username and password
+
+If your proxy requires authentication, you can enter a username and
+a password in the \q{Username} and \q{Password} boxes.
+
+Currently these boxes have no effect ( [FIXME] presumably they're
+for SOCKS only).
+
+\S{config-proxy-command} Specifying the Telnet proxy command
+
+If you are using the Telnet proxy type, the usual command required
+by the firewall's Telnet server is \c{connect}, followed by a host
+name and a port number. If your proxy needs a different command,
+you can enter an alternative here.
+
+In this string, you can use \c{\\n} to represent a new-line, \c{\\r}
+to represent a carriage return, \c{\\t} to represent a tab
+character, and \c{\\x} followed by two hex digits to represent any
+other character. \c{\\\\} is used to encode the \c{\\} character
+itself.
+
+Also, the special strings \c{%host} and \c{%port} will be replaced
+by the host name and port number you want to connect to. To get a
+literal \c{%} sign, enter \c{%%}.
+
+\S{config-proxy-socksver} Selecting the version of the SOCKS protocol
+
+SOCKS servers exist in two versions: version 5
+(\W{http://www.ietf.org/rfc/rfc1928.txt}{RFC 1928}) and the earlier
+version 4. The \q{SOCKS Version} radio buttons allow you to select
+which one to use, if you have selected the SOCKS proxy type.
+
 \H{config-telnet} The Telnet panel
 
 The Telnet panel allows you to configure options that only apply to
 \H{config-telnet} The Telnet panel
 
 The Telnet panel allows you to configure options that only apply to
index 9da42970bf97976af0c16a261714f99ce16b02ac..9cf901f87b60dfaa9e5ebba63582285d4020ddda 100644 (file)
@@ -1,4 +1,4 @@
-\versionid $Id: licence.but,v 1.3 2002/02/24 15:17:10 simon Exp $
+\versionid $Id: licence.but,v 1.4 2002/03/27 21:09:16 simon Exp $
 
 \A{licence} PuTTY Licence
 
 
 \A{licence} PuTTY Licence
 
@@ -6,7 +6,7 @@ PuTTY is copyright 1997-2002 Simon Tatham.
 
 Portions copyright Robert de Bath, Joris van Rantwijk, Delian
 Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
 
 Portions copyright Robert de Bath, Joris van Rantwijk, Delian
 Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
-and CORE SDI S.A.
+Justin Bradford, and CORE SDI S.A.
 
 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation files
 
 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation files
index 94d71f3455ae0bb583b90cfaae4b837840a75127..8bc76f4f548af91a01cf93ae7d3bae16b560c1a8 100644 (file)
@@ -66,7 +66,7 @@ BEGIN
 
     LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
     LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
 
     LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
     LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
-    LTEXT "Barry, and CORE SDI S.A.", 1003, 10, 42, 206, 8
+    LTEXT "Barry, Justin Bradford, and CORE SDI S.A.", 1003, 10, 42, 206, 8
 
     LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
     LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8
 
     LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
     LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8
diff --git a/proxy.c b/proxy.c
index b773f251497c06323381dafd73503fca193b9498..e8f0fdc58c1108816b841012d46ef8881ad3aadc 100644 (file)
--- a/proxy.c
+++ b/proxy.c
@@ -21,21 +21,12 @@ void proxy_activate (Proxy_Socket p)
     void *data;
     int len;
 
     void *data;
     int len;
 
-    p->lock_close =
-       p->lock_write =
-       p->lock_write_oob =
-       p->lock_receive =
-       p->lock_flush =
-       p->lock_closing =
-       p->lock_sent =
-       p->lock_accepting =
-       p->lock_freeze = 1;
-
     p->state = PROXY_STATE_ACTIVE;
 
     /* let's try to keep extra receive events from coming through */
     sk_set_frozen(p->sub_socket, 1);
 
     p->state = PROXY_STATE_ACTIVE;
 
     /* let's try to keep extra receive events from coming through */
     sk_set_frozen(p->sub_socket, 1);
 
+    /* send buffered OOB writes */
     while (bufchain_size(&p->pending_oob_output_data) > 0) {
        bufchain_prefix(&p->pending_oob_output_data, &data, &len);
        sk_write_oob(p->sub_socket, data, len);
     while (bufchain_size(&p->pending_oob_output_data) > 0) {
        bufchain_prefix(&p->pending_oob_output_data, &data, &len);
        sk_write_oob(p->sub_socket, data, len);
@@ -43,6 +34,7 @@ void proxy_activate (Proxy_Socket p)
     }
     bufchain_clear(&p->pending_oob_output_data);
 
     }
     bufchain_clear(&p->pending_oob_output_data);
 
+    /* send buffered normal writes */
     while (bufchain_size(&p->pending_output_data) > 0) {
        bufchain_prefix(&p->pending_output_data, &data, &len);
        sk_write(p->sub_socket, data, len);
     while (bufchain_size(&p->pending_output_data) > 0) {
        bufchain_prefix(&p->pending_output_data, &data, &len);
        sk_write(p->sub_socket, data, len);
@@ -50,28 +42,21 @@ void proxy_activate (Proxy_Socket p)
     }
     bufchain_clear(&p->pending_output_data);
 
     }
     bufchain_clear(&p->pending_output_data);
 
-    p->lock_write_oob = 0;
-    p->lock_write = 0;
-
+    /* if we were asked to flush the output during
+     * the proxy negotiation process, do so now.
+     */
     if (p->pending_flush) sk_flush(p->sub_socket);
     if (p->pending_flush) sk_flush(p->sub_socket);
-    p->lock_flush = 0;
 
 
+    /* forward buffered recv data to the backend */
     while (bufchain_size(&p->pending_input_data) > 0) {
        bufchain_prefix(&p->pending_input_data, &data, &len);
        plug_receive(p->plug, 0, data, len);
        bufchain_consume(&p->pending_input_data, len);
     }
     bufchain_clear(&p->pending_input_data);
     while (bufchain_size(&p->pending_input_data) > 0) {
        bufchain_prefix(&p->pending_input_data, &data, &len);
        plug_receive(p->plug, 0, data, len);
        bufchain_consume(&p->pending_input_data, len);
     }
     bufchain_clear(&p->pending_input_data);
-    p->lock_receive = 0;
 
     /* now set the underlying socket to whatever freeze state they wanted */
     sk_set_frozen(p->sub_socket, p->freeze);
 
     /* now set the underlying socket to whatever freeze state they wanted */
     sk_set_frozen(p->sub_socket, p->freeze);
-    p->lock_freeze = 0;
-
-    p->lock_sent = 0;
-    p->lock_accepting = 0;
-    p->lock_closing = 0;
-    p->lock_close = 0;
 }
 
 /* basic proxy socket functions */
 }
 
 /* basic proxy socket functions */
@@ -89,7 +74,6 @@ static void sk_proxy_close (Socket s)
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
-    while (ps->lock_close) ;
     sk_close(ps->sub_socket);
     sfree(ps);
 }
     sk_close(ps->sub_socket);
     sfree(ps);
 }
@@ -98,7 +82,6 @@ static int sk_proxy_write (Socket s, char *data, int len)
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
-    while (ps->lock_write) ;
     if (ps->state != PROXY_STATE_ACTIVE) {
        bufchain_add(&ps->pending_output_data, data, len);
        return bufchain_size(&ps->pending_output_data);
     if (ps->state != PROXY_STATE_ACTIVE) {
        bufchain_add(&ps->pending_output_data, data, len);
        return bufchain_size(&ps->pending_output_data);
@@ -110,7 +93,6 @@ static int sk_proxy_write_oob (Socket s, char *data, int len)
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
-    while (ps->lock_write_oob) ;
     if (ps->state != PROXY_STATE_ACTIVE) {
        bufchain_clear(&ps->pending_output_data);
        bufchain_clear(&ps->pending_oob_output_data);
     if (ps->state != PROXY_STATE_ACTIVE) {
        bufchain_clear(&ps->pending_output_data);
        bufchain_clear(&ps->pending_oob_output_data);
@@ -124,7 +106,6 @@ static void sk_proxy_flush (Socket s)
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
-    while (ps->lock_flush) ;
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->pending_flush = 1;
        return;
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->pending_flush = 1;
        return;
@@ -148,7 +129,6 @@ static void sk_proxy_set_frozen (Socket s, int is_frozen)
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
 {
     Proxy_Socket ps = (Proxy_Socket) s;
 
-    while (ps->lock_freeze) ;
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->freeze = is_frozen;
        return;
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->freeze = is_frozen;
        return;
@@ -173,7 +153,6 @@ static int plug_proxy_closing (Plug p, char *error_msg,
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
-    while (ps->lock_closing) ;
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->closing_error_msg = error_msg;
        ps->closing_error_code = error_code;
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->closing_error_msg = error_msg;
        ps->closing_error_code = error_code;
@@ -189,7 +168,6 @@ static int plug_proxy_receive (Plug p, int urgent, char *data, int len)
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
-    while (ps->lock_receive) ;
     if (ps->state != PROXY_STATE_ACTIVE) {
        /* we will lose the urgentness of this data, but since most,
         * if not all, of this data will be consumed by the negotiation
     if (ps->state != PROXY_STATE_ACTIVE) {
        /* we will lose the urgentness of this data, but since most,
         * if not all, of this data will be consumed by the negotiation
@@ -209,7 +187,6 @@ static void plug_proxy_sent (Plug p, int bufsize)
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
-    while (ps->lock_sent) ;
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->sent_bufsize = bufsize;
        ps->negotiate(ps, PROXY_CHANGE_SENT);
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->sent_bufsize = bufsize;
        ps->negotiate(ps, PROXY_CHANGE_SENT);
@@ -223,7 +200,6 @@ static int plug_proxy_accepting (Plug p, void *sock)
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
 
-    while (ps->lock_accepting) ;
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->accepting_sock = sock;
        return ps->negotiate(ps, PROXY_CHANGE_ACCEPTING);
     if (ps->state != PROXY_STATE_ACTIVE) {
        ps->accepting_sock = sock;
        return ps->negotiate(ps, PROXY_CHANGE_ACCEPTING);
@@ -340,15 +316,6 @@ Socket new_connection(SockAddr addr, char *hostname,
        bufchain_init(&ret->pending_output_data);
        bufchain_init(&ret->pending_oob_output_data);
 
        bufchain_init(&ret->pending_output_data);
        bufchain_init(&ret->pending_oob_output_data);
 
-       ret->lock_close =
-           ret->lock_write =
-           ret->lock_write_oob =
-           ret->lock_receive =
-           ret->lock_flush =
-           ret->lock_closing =
-           ret->lock_sent =
-           ret->lock_accepting = 0;
-
        ret->sub_socket = NULL;
        ret->state = PROXY_STATE_NEW;
 
        ret->sub_socket = NULL;
        ret->state = PROXY_STATE_NEW;
 
@@ -451,9 +418,9 @@ int proxy_http_negotiate (Proxy_Socket p, int change)
         * for this proxy method, it's just a simple HTTP
         * request
         */
         * for this proxy method, it's just a simple HTTP
         * request
         */
-       char buf[1024], dest[21];
+       char buf[256], dest[64];
 
 
-       sk_getaddr(p->remote_addr, dest, 20);
+       sk_getaddr(p->remote_addr, dest, 64);
 
        sprintf(buf, "CONNECT %s:%i HTTP/1.1\r\nHost: %s:%i\r\n\r\n",
                dest, p->remote_port, dest, p->remote_port);
 
        sprintf(buf, "CONNECT %s:%i HTTP/1.1\r\nHost: %s:%i\r\n\r\n",
                dest, p->remote_port, dest, p->remote_port);
@@ -579,7 +546,7 @@ int proxy_socks_negotiate (Proxy_Socket p, int change)
 }
 
 /* ----------------------------------------------------------------------
 }
 
 /* ----------------------------------------------------------------------
- * `Telnet' proxy type (as yet unimplemented).
+ * `Telnet' proxy type.
  *
  * (This is for ad-hoc proxies where you connect to the proxy's
  * telnet port and send a command such as `connect host port'. The
  *
  * (This is for ad-hoc proxies where you connect to the proxy's
  * telnet port and send a command such as `connect host port'. The
@@ -589,6 +556,206 @@ int proxy_socks_negotiate (Proxy_Socket p, int change)
 
 int proxy_telnet_negotiate (Proxy_Socket p, int change)
 {
 
 int proxy_telnet_negotiate (Proxy_Socket p, int change)
 {
-    p->error = "Network error: Telnet proxy implementation is incomplete";
+    if (p->state == PROXY_CHANGE_NEW) {
+
+       int so = 0, eo = 0;
+
+       /* we need to escape \\, \%, \r, \n, \t, \x??, \0???, 
+        * %%, %host, and %port 
+        */
+
+       while (cfg.proxy_telnet_command[eo] != 0) {
+
+           /* scan forward until we hit end-of-line, 
+            * or an escape character (\ or %) */
+           while (cfg.proxy_telnet_command[eo] != 0 &&
+                  cfg.proxy_telnet_command[eo] != '%' &&
+                  cfg.proxy_telnet_command[eo] != '\\') eo++;
+
+           /* if we hit eol, break out of our escaping loop */
+           if (cfg.proxy_telnet_command[eo] == 0) break;
+
+           /* if there was any unescaped text before the escape
+            * character, send that now */
+           if (eo != so) {
+               sk_write(p->sub_socket, 
+                        cfg.proxy_telnet_command + so, eo - so);
+           }
+
+           so = eo++;
+
+           /* if the escape character was the last character of
+            * the line, we'll just stop and send it. */
+           if (cfg.proxy_telnet_command[eo] == 0) break;
+
+           if (cfg.proxy_telnet_command[so] == '\\') {
+
+               /* we recognize \\, \%, \r, \n, \t, \x??. 
+                * anything else, we just send unescaped (including the \). 
+                */
+
+               switch (cfg.proxy_telnet_command[eo]) {
+
+                 case '\\':
+                   sk_write(p->sub_socket, "\\", 1);
+                   eo++;
+                   break;
+
+                 case '%':
+                   sk_write(p->sub_socket, "%%", 1);
+                   eo++;
+                   break;
+
+                 case 'r':
+                   sk_write(p->sub_socket, "\r", 1);
+                   eo++;
+                   break;
+
+                 case 'n':
+                   sk_write(p->sub_socket, "\n", 1);
+                   eo++;
+                   break;
+
+                 case 't':
+                   sk_write(p->sub_socket, "\t", 1);
+                   eo++;
+                   break;
+
+                 case 'x':
+                 case 'X':
+                   {
+                   /* escaped hexadecimal value (ie. \xff) */
+                   unsigned char v = 0;
+                   int i = 0;
+
+                   for (;;) {
+                       eo++;
+                       if (cfg.proxy_telnet_command[eo] >= '0' &&
+                           cfg.proxy_telnet_command[eo] <= '9')
+                           v += cfg.proxy_telnet_command[eo] - '0';
+                       else if (cfg.proxy_telnet_command[eo] >= 'a' &&
+                                cfg.proxy_telnet_command[eo] <= 'f')
+                           v += cfg.proxy_telnet_command[eo] - 'a' + 10;
+                       else if (cfg.proxy_telnet_command[eo] >= 'A' &&
+                                cfg.proxy_telnet_command[eo] <= 'F')
+                           v += cfg.proxy_telnet_command[eo] - 'A' + 10;
+                       else {
+                           /* non hex character, so we abort and just
+                            * send the whole thing unescaped (including \x)
+                            */
+                           sk_write(p->sub_socket, "\\", 1);
+                           eo = so + 1;
+                           break;
+                       }
+
+                       /* we only extract two hex characters */
+                       if (i == 1) {
+                           sk_write(p->sub_socket, &v, 1);
+                           eo++;
+                           break;
+                       }
+
+                       i++;
+                       v <<= 4;
+                   }
+                   }
+                   break;
+
+                 default:
+                   sk_write(p->sub_socket, 
+                            cfg.proxy_telnet_command + so, 2);
+                   eo++;
+                   break;
+               }
+           } else {
+
+               /* % escape. we recognize %%, %host, %port. anything else,
+                * we just send unescaped (including the %). */
+
+               if (cfg.proxy_telnet_command[eo] == '%') {
+                   sk_write(p->sub_socket, "%", 1);
+                   eo++;
+               } 
+               else if (strnicmp(cfg.proxy_telnet_command + eo,
+                                 "host", 4) == 0) {
+                   char dest[64];
+                   sk_getaddr(p->remote_addr, dest, 64);
+                   sk_write(p->sub_socket, dest, strlen(dest));
+                   eo += 4;
+               } 
+               else if (strnicmp(cfg.proxy_telnet_command + eo,
+                                 "port", 4) == 0) {
+                   char port[8];
+                   sprintf(port, "%i", p->remote_port);
+                   sk_write(p->sub_socket, port, strlen(port));
+                   eo += 4;
+               } 
+               else {
+                   /* we don't escape this, so send the % now, and
+                    * don't advance eo, so that we'll consider the
+                    * text immediately following the % as unescaped.
+                    */
+                   sk_write(p->sub_socket, "%", 1);
+               }
+           }
+
+           /* resume scanning for additional escapes after this one. */
+           so = eo;
+       }
+
+       /* if there is any unescaped text at the end of the line, send it */
+       if (eo != so) {
+           sk_write(p->sub_socket, cfg.proxy_telnet_command + so, eo - so);
+       }
+
+       p->state = 1;
+
+       return 0;
+    }
+
+    if (change == PROXY_CHANGE_CLOSING) {
+       /* if our proxy negotiation process involves closing and opening
+        * new sockets, then we would want to intercept this closing
+        * callback when we were expecting it. if we aren't anticipating
+        * a socket close, then some error must have occurred. we'll
+        * just pass those errors up to the backend.
+        */
+       return plug_closing(p->plug, p->closing_error_msg,
+                           p->closing_error_code,
+                           p->closing_calling_back);
+    }
+
+    if (change == PROXY_CHANGE_SENT) {
+       /* some (or all) of what we wrote to the proxy was sent.
+        * we don't do anything new, however, until we receive the
+        * proxy's response. we might want to set a timer so we can
+        * timeout the proxy negotiation after a while...
+        */
+       return 0;
+    }
+
+    if (change == PROXY_CHANGE_ACCEPTING) {
+       /* we should _never_ see this, as we are using our socket to
+        * connect to a proxy, not accepting inbound connections.
+        * what should we do? close the socket with an appropriate
+        * error message?
+        */
+       return plug_accepting(p->plug, p->accepting_sock);
+    }
+
+    if (change == PROXY_CHANGE_RECEIVE) {
+       /* we have received data from the underlying socket, which
+        * we'll need to parse, process, and respond to appropriately.
+        */
+
+       /* we're done */
+       proxy_activate(p);
+       /* proxy activate will have dealt with
+        * whatever is left of the buffer */
+       return 1;
+    }
+
+    plug_closing(p->plug, "Network error: Unexpected proxy error",
+                PROXY_ERROR_UNEXPECTED, 0);
     return 0;
 }
     return 0;
 }
diff --git a/proxy.h b/proxy.h
index 43d92cb0aa9c7f0a8d881d019315670eddc93f33..c74c89c8039bb341a7a79a1db5bd7c7a919d8383 100644 (file)
--- a/proxy.h
+++ b/proxy.h
@@ -80,24 +80,6 @@ struct Socket_proxy_tag {
     /* accepting */
     void *accepting_sock;
 
     /* accepting */
     void *accepting_sock;
 
-    /* spin locks, for the critical switch from negotiating
-     * to active state. we have to dump all of our pending
-     * buffers without new events (read, writes, etc) corrupting
-     * things. we should not have built up a large amount of
-     * pending data during negotiation, so hopefully this will
-     * not have a large effect on performance.
-     */
-
-    char lock_close;
-    char lock_write;
-    char lock_write_oob;
-    char lock_receive;
-    char lock_flush;
-    char lock_closing;
-    char lock_sent;
-    char lock_accepting;
-    char lock_freeze;
-
 };
 
 typedef struct Plug_proxy_tag * Proxy_Plug;
 };
 
 typedef struct Plug_proxy_tag * Proxy_Plug;
index 0da2ff9912bc0a44bc69a9a1d6cf9f76eb79783c..bc70a7f337b1c33276049f2d2c3d5e9921b5ca42 100644 (file)
@@ -59,7 +59,7 @@ BEGIN
 
     LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
     LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
 
     LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
     LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
-    LTEXT "Barry, and CORE SDI S.A.", 1003, 10, 42, 206, 8
+    LTEXT "Barry, Justin Bradford, and CORE SDI S.A.", 1003, 10, 42, 206, 8
 
     LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
     LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8
 
     LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
     LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8
index 8764bb323a3a29cd9ce8566a12fde23a01af03c7..febd95050e168473f9625d6c448398b0a6254e68 100644 (file)
@@ -366,7 +366,7 @@ void load_settings(char *section, int do_host, Config * cfg)
         sizeof(cfg->proxy_username));
     gpps(sesskey, "ProxyPassword", "", cfg->proxy_password,
         sizeof(cfg->proxy_password));
         sizeof(cfg->proxy_username));
     gpps(sesskey, "ProxyPassword", "", cfg->proxy_password,
         sizeof(cfg->proxy_password));
-    gpps(sesskey, "ProxyTelnetCommand", "connect %host %port",
+    gpps(sesskey, "ProxyTelnetCommand", "connect %host %port\\n",
         cfg->proxy_telnet_command, sizeof(cfg->proxy_telnet_command));
     gppi(sesskey, "ProxySOCKSVersion", 5, &cfg->proxy_socks_version);
 
         cfg->proxy_telnet_command, sizeof(cfg->proxy_telnet_command));
     gppi(sesskey, "ProxySOCKSVersion", 5, &cfg->proxy_socks_version);
 
index 90e421b103c832c8effb8094db0bd2eab4907ba4..2ae144b3153004ff6b1eb00bc0724aa4875be5f3 100644 (file)
@@ -87,7 +87,7 @@ BEGIN
 
     LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
     LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
 
     LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
     LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8
-    LTEXT "Barry, and CORE SDI S.A.", 1003, 10, 42, 206, 8
+    LTEXT "Barry, Justin Bradford, and CORE SDI S.A.", 1003, 10, 42, 206, 8
 
     LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
     LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8
 
     LTEXT "Permission is hereby granted, free of charge, to any person", 1004, 10, 58, 206, 8
     LTEXT "obtaining a copy of this software and associated documentation", 1005, 10, 66, 206, 8