TCP performance fix (see 2203 in krb5-bugs): write out encrypted data
authorSam Hartman <hartmans@mit.edu>
Mon, 2 Sep 1996 16:30:36 +0000 (16:30 +0000)
committerSam Hartman <hartmans@mit.edu>
Mon, 2 Sep 1996 16:30:36 +0000 (16:30 +0000)
and length as one packet, not with two calls to write.

This should also happen to rsh, rcp, and possibly telnet.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@9020 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/bsd/ChangeLog
src/appl/bsd/krlogin.c
src/appl/bsd/krlogind.c

index 59754e7874bd5e358989388ca16b1c0b02c118b8..6eda77c1720b04becdb46a52d0c4df5de46e684e 100644 (file)
@@ -1,3 +1,11 @@
+Mon Sep  2 12:03:53 1996  Sam Hartman  <hartmans@mit.edu>
+
+       * krlogind.c rlogin.c (v5_des_write): Write out length plus
+       encrypted data as one packet; this reduces latency by one RTT for
+       interactive traffic with kernels that support schemes similar to
+       RFC896, and reduces the number of packets with most other TCP
+       stacks.
+
 Sat Aug 10 16:22:34 1996  Sam Hartman  <hartmans@mit.edu>
 
        * krcp.c (source): Cast stb.st_size to a long before printing it.
index 831806c626742a9734a6be68d13480dc06893b5c..5507ed329c746f74392188e64d6e912ecb0ac1d0 100644 (file)
@@ -138,10 +138,18 @@ char copyright[] =
 #include "com_err.h"
 #include "defines.h"
      
-#define RLOGIN_BUFSIZ 4096
-     
+#define RLOGIN_BUFSIZ 5120
+     /*
+ * Note that the encrypted rlogin packets take the form of a four-byte
+ *length followed by encrypted data.  On writing the data out, a significant
+ * performance penalty is suffered (at least one RTT per character, two if we
+ * are waiting for a shell to echo) by writing the data separately from the 
+ * length.  So, unlike the input buffer, which just contains the output
+ * data, the output buffer represents the entire packet.
+ */
+
 char des_inbuf[2*RLOGIN_BUFSIZ];       /* needs to be > largest read size */
-char des_outbuf[2*RLOGIN_BUFSIZ];      /* needs to be > largest write size */
+char des_outpkt[2*RLOGIN_BUFSIZ+4];      /* needs to be > largest write size */
 krb5_data desinbuf,desoutbuf;
 krb5_encrypt_block eblock;      /* eblock for encrypt/decrypt */
 
@@ -467,7 +475,7 @@ main(argc, argv)
     krb5_init_context(&bsd_context);
     krb5_init_ets(bsd_context);
     desinbuf.data = des_inbuf;
-    desoutbuf.data = des_outbuf;       /* Set up des buffers */
+    desoutbuf.data = des_outpkt+4;     /* Set up des buffers */
 #endif
 
 
@@ -1691,35 +1699,36 @@ int des_write(fd, buf, len)
      char *buf;
      int len;
 {
-    unsigned char len_buf[4];
+  unsigned char *len_buf = (unsigned char *) des_outpkt;
     
-    if (!encrypt_flag)
+  if (!encrypt_flag)
       return(write(fd, buf, len));
     
+    
     desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry);
-    if (desoutbuf.length > sizeof(des_outbuf)){
-       fprintf(stderr,"Write size problem.\n");
+    if (desoutbuf.length > sizeof(des_outpkt)-4){
+       fprintf(stderr,"Write size problem.\n");
        return(-1);
     }
-    if (( krb5_encrypt(bsd_context, (krb5_pointer)buf,
-                      desoutbuf.data,
-                      len,
-                      &eblock,
-                      0))){
-       fprintf(stderr,"Write encrypt problem.\n");
+    if ((krb5_encrypt(bsd_context, (krb5_pointer)buf,
+                     desoutbuf.data,
+                     len,
+                     &eblock,
+                     0))){
+       fprintf(stderr,"Write encrypt problem.\n");
        return(-1);
     }
-    
+
     len_buf[0] = (len & 0xff000000) >> 24;
     len_buf[1] = (len & 0xff0000) >> 16;
     len_buf[2] = (len & 0xff00) >> 8;
     len_buf[3] = (len & 0xff);
-    (void) write(fd, len_buf, 4);
-    if (write(fd, desoutbuf.data,desoutbuf.length) != desoutbuf.length){
-       fprintf(stderr,"Could not write out all data.\n");
+
+    if (write(fd, des_outpkt,desoutbuf.length+4) != desoutbuf.length+4){
+      fprintf(stderr,"Could not write out all data\n");
        return(-1);
     }
-    else return(len); 
+    else return(len);
 }
 
 
index ac83cccb0673475b810288f2369d4342fc70b274..2327ba85a73955bea977adc50ee21efbb868417b 100644 (file)
@@ -229,10 +229,17 @@ int v5_des_read(), v5_des_write();
 #include "com_err.h"
      
 #define SECURE_MESSAGE  "This rlogin session is using DES encryption for all data transmissions.\r\n"
-
-int (*des_read)(), (*des_write)();
+/*
+ * Note that the encrypted rlogin packets take the form of a four-byte
+ *length followed by encrypted data.  On writing the data out, a significant
+ * performance penalty is suffered (at least one RTT per character, two if we
+ * are waiting for a shell to echo) by writing the data separately from the 
+ * length.  So, unlike the input buffer, which just contains the output
+ * data, the output buffer represents the entire packet.
+ */
+ int (*des_read)(), (*des_write)();
 char des_inbuf[2*RLOGIND_BUFSIZ]; /* needs to be > largest read size */
-char des_outbuf[2*RLOGIND_BUFSIZ];/* needs to be > largest write size */
+char des_outpkt[2*RLOGIND_BUFSIZ+4];/* needs to be > largest write size */
 krb5_data desinbuf,desoutbuf;
 krb5_encrypt_block eblock;        /* eblock for encrypt/decrypt */
 
@@ -553,7 +560,7 @@ int syncpipe[2];
 
        /* setup des buffers */
     desinbuf.data = des_inbuf;
-    desoutbuf.data = des_outbuf;    /* Set up des buffers */
+    desoutbuf.data = des_outpkt+4;    /* Set up des buffers */
 
     /* Must come from privileged port when .rhosts is being looked into */
     if ((auth_ok&AUTH_RHOSTS) 
@@ -1312,14 +1319,14 @@ v5_des_write(fd, buf, len)
      char *buf;
      int len;
 {
-    unsigned char len_buf[4];
+  unsigned char *len_buf = (unsigned char *) des_outpkt;
     
     if (!do_encrypt)
       return(write(fd, buf, len));
     
     
     desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry);
-    if (desoutbuf.length > sizeof(des_outbuf)){
+    if (desoutbuf.length > sizeof(des_outpkt)-4){
        syslog(LOG_ERR,"Write size problem.");
        return(-1);
     }
@@ -1336,8 +1343,8 @@ v5_des_write(fd, buf, len)
     len_buf[1] = (len & 0xff0000) >> 16;
     len_buf[2] = (len & 0xff00) >> 8;
     len_buf[3] = (len & 0xff);
-    (void) write(fd, len_buf, 4);
-    if (write(fd, desoutbuf.data,desoutbuf.length) != desoutbuf.length){
+
+    if (write(fd, des_outpkt,desoutbuf.length+4) != desoutbuf.length+4){
        syslog(LOG_ERR,"Could not write out all data.");
        return(-1);
     }
@@ -1710,7 +1717,7 @@ char *buf;
 int len;
 {
        static char garbage_buf[8];
-       unsigned char len_buf[4];
+       unsigned char *len_buf = (unsigned char *) des_outpkt;
 
        if (!do_encrypt)
                return(write(fd, buf, len));
@@ -1738,7 +1745,7 @@ int len;
                (void) memcpy(garbage_buf + 8 - len, buf, len);
        }
        (void) pcbc_encrypt((len < 8) ? garbage_buf : buf,
-                           des_outbuf,
+                           des_outpkt+4,
                            (len < 8) ? 8 : len,
                            v4_schedule,
                            v4_kdata->session,
@@ -1750,8 +1757,7 @@ int len;
        len_buf[1] = (len & 0xff0000) >> 16;
        len_buf[2] = (len & 0xff00) >> 8;
        len_buf[3] = (len & 0xff);
-       (void) write(fd, len_buf, 4);
-       (void) write(fd, des_outbuf, roundup(len,8));
+       (void) write(fd, des_outpkt, roundup(len,8)+4);
        return(len);
 }