From f683399de200ebf53d3a1eba401fdef8f779a52c Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Mon, 2 Sep 1996 16:30:36 +0000 Subject: [PATCH] TCP performance fix (see 2203 in krb5-bugs): write out encrypted data 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 | 8 +++++++ src/appl/bsd/krlogin.c | 47 ++++++++++++++++++++++++----------------- src/appl/bsd/krlogind.c | 30 +++++++++++++++----------- 3 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index 59754e787..6eda77c17 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,3 +1,11 @@ +Mon Sep 2 12:03:53 1996 Sam Hartman + + * 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 * krcp.c (source): Cast stb.st_size to a long before printing it. diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c index 831806c62..5507ed329 100644 --- a/src/appl/bsd/krlogin.c +++ b/src/appl/bsd/krlogin.c @@ -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); } diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c index ac83cccb0..2327ba85a 100644 --- a/src/appl/bsd/krlogind.c +++ b/src/appl/bsd/krlogind.c @@ -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); } -- 2.26.2