Justin Bradford's proxy support patch. Currently supports only HTTP
[u/mdw/putty] / x11fwd.c
index 5be69b8..6f7be40 100644 (file)
--- a/x11fwd.c
+++ b/x11fwd.c
@@ -5,13 +5,6 @@
 #include "putty.h"
 #include "ssh.h"
 
-#ifndef FALSE
-#define FALSE 0
-#endif
-#ifndef TRUE
-#define TRUE 1
-#endif
-
 #define GET_32BIT_LSB_FIRST(cp) \
   (((unsigned long)(unsigned char)(cp)[0]) | \
   ((unsigned long)(unsigned char)(cp)[1] << 8) | \
@@ -58,9 +51,6 @@
 #define PUT_16BIT(endian, cp, val) \
   (endian=='B' ? PUT_16BIT_MSB_FIRST(cp, val) : PUT_16BIT_LSB_FIRST(cp, val))
 
-extern void sshfwd_close(void *);
-extern void sshfwd_write(void *, char *, int);
-
 struct X11Private {
     struct plug_function_table *fn;
     /* the above variable absolutely *must* be the first in this structure */
@@ -69,6 +59,7 @@ struct X11Private {
     unsigned char *auth_data;
     int data_read, auth_plen, auth_psize, auth_dlen, auth_dsize;
     int verified;
+    int throttled, throttle_override;
     void *c;                          /* data used by ssh.c */
     Socket s;
 };
@@ -127,10 +118,21 @@ static int x11_receive(Plug plug, int urgent, char *data, int len)
 {
     struct X11Private *pr = (struct X11Private *) plug;
 
-    sshfwd_write(pr->c, data, len);
+    if (sshfwd_write(pr->c, data, len) > 0) {
+       pr->throttled = 1;
+       sk_set_frozen(pr->s, 1);
+    }
+
     return 1;
 }
 
+static void x11_sent(Plug plug, int bufsize)
+{
+    struct X11Private *pr = (struct X11Private *) plug;
+
+    sshfwd_unthrottle(pr->c, bufsize);
+}
+
 /*
  * Called to set up the raw connection.
  * 
@@ -141,7 +143,9 @@ char *x11_init(Socket * s, char *display, void *c)
 {
     static struct plug_function_table fn_table = {
        x11_closing,
-       x11_receive
+       x11_receive,
+       x11_sent,
+       NULL
     };
 
     SockAddr addr;
@@ -181,9 +185,10 @@ char *x11_init(Socket * s, char *display, void *c)
     pr->auth_protocol = NULL;
     pr->verified = 0;
     pr->data_read = 0;
+    pr->throttled = pr->throttle_override = 0;
     pr->c = c;
 
-    pr->s = *s = sk_new(addr, port, 0, 1, (Plug) pr);
+    pr->s = *s = new_connection(addr, dummy_realhost, port, 0, 1, 0, (Plug) pr);
     if ((err = sk_socket_error(*s))) {
        sfree(pr);
        return err;
@@ -197,10 +202,9 @@ char *x11_init(Socket * s, char *display, void *c)
 void x11_close(Socket s)
 {
     struct X11Private *pr;
-    \rif (!s)
-       \rreturn;
-    \rpr = (struct X11Private *) sk_get_private_ptr(s);
-
+    if (!s)
+       return;
+    pr = (struct X11Private *) sk_get_private_ptr(s);
     if (pr->auth_protocol) {
        sfree(pr->auth_protocol);
        sfree(pr->auth_data);
@@ -211,15 +215,37 @@ void x11_close(Socket s)
     sk_close(s);
 }
 
+void x11_unthrottle(Socket s)
+{
+    struct X11Private *pr;
+    if (!s)
+       return;
+    pr = (struct X11Private *) sk_get_private_ptr(s);
+
+    pr->throttled = 0;
+    sk_set_frozen(s, pr->throttled || pr->throttle_override);
+}
+
+void x11_override_throttle(Socket s, int enable)
+{
+    struct X11Private *pr;
+    if (!s)
+       return;
+    pr = (struct X11Private *) sk_get_private_ptr(s);
+
+    pr->throttle_override = enable;
+    sk_set_frozen(s, pr->throttled || pr->throttle_override);
+}
+
 /*
  * Called to send data down the raw connection.
  */
-void x11_send(Socket s, char *data, int len)
+int x11_send(Socket s, char *data, int len)
 {
     struct X11Private *pr = (struct X11Private *) sk_get_private_ptr(s);
 
     if (s == NULL)
-       return;
+       return 0;
 
     /*
      * Read the first packet.
@@ -227,7 +253,7 @@ void x11_send(Socket s, char *data, int len)
     while (len > 0 && pr->data_read < 12)
        pr->firstpkt[pr->data_read++] = (unsigned char) (len--, *data++);
     if (pr->data_read < 12)
-       return;
+       return 0;
 
     /*
      * If we have not allocated the auth_protocol and auth_data
@@ -252,7 +278,7 @@ void x11_send(Socket s, char *data, int len)
        pr->auth_data[pr->data_read++ - 12 -
                      pr->auth_psize] = (unsigned char) (len--, *data++);
     if (pr->data_read < 12 + pr->auth_psize + pr->auth_dsize)
-       return;
+       return 0;
 
     /*
      * If we haven't verified the authentication, do so now.
@@ -275,13 +301,13 @@ void x11_send(Socket s, char *data, int len)
            reply[0] = 0;              /* failure */
            reply[1] = msglen;         /* length of reason string */
            memcpy(reply + 2, pr->firstpkt + 2, 4);     /* major/minor proto vsn */
-           PUT_16BIT(pr->firstpkt[0], reply + 6, msglen >> 2); /* data len */
+           PUT_16BIT(pr->firstpkt[0], reply + 6, msgsize >> 2);/* data len */
            memset(reply + 8, 0, msgsize);
            memcpy(reply + 8, message, msglen);
            sshfwd_write(pr->c, reply, 8 + msgsize);
            sshfwd_close(pr->c);
            x11_close(s);
-           return;
+           return 0;
        }
 
        /*
@@ -299,5 +325,5 @@ void x11_send(Socket s, char *data, int len)
      * After initialisation, just copy data simply.
      */
 
-    sk_write(s, data, len);
+    return sk_write(s, data, len);
 }