[2203] in Kerberos-V5-bugs

home help back first fref pref prev next nref lref last post

krb5b6 krlogin(d) performance fix

daemon@ATHENA.MIT.EDU (Sam Hartman)
Mon Sep 2 12:18:34 1996

To: krb5-bugs@MIT.EDU
From: Sam Hartman <hartmans@MIT.EDU>
Date: 02 Sep 1996 12:18:24 -0400


	The indentifying information has been removed from the
following at the user's request.  I will be happy to release the
original message to any krbcore members who ask. 

	Jhawk and I looked at a rlogin session with tcpdump and
confirmed that two packets were sent for each character, and the
second packet was sent only after the first was acknowledged.  This is
a serious performance issue, especially for rlogin over modem links.  

	Patch to be committed shortly, but I wanted a
transaction in krb5-bugs to refer to in the CVS log.


------- Start of forwarded message -------
To: hartmans@MIT.EDU
Subject: krb5b6 krlogin(d) performance fix
Date: Wed, 28 Aug 1996 02:21:01 +0200

Sorry for sending this to you privately. But since I really shouldn't 
have kerberos in the first place, I do it just in case.

I've sent this together with a bunch of other patches once earlier
to tytso@MIT.EDU however it didn't get into krb5b6 so I guess it
has dissapeared somewhere on the road. More or less everything else
I had patched is fixed in beta 6 though.

The problem is mainly with TCP/IP implementation that piggy backs ack's 
(using Nagels algoritm I guess, there is a RFC out there describing it if 
you don't know it), but does improve perfomance on any machine I've tried 
it on.

The problem is that krlogin(d) sends twice as many packets as needed.
It first sends the length of the encrypted data and then the data. 
Due to the algorithm mentioned above, the other host will try to hold
back the ack for piggy backing, while the sender wont send the next packet
until the ack is recieved (it's not always that bad, it depends on 
several other factors), but it slows down things considerably. Have
a look at a tcpdump from a HPUX machine vs. a NetBSD machine and
you should see the differnce easily.

The situation might be improved by setting TCP_NODELAY but it dosn't
really fix the problem.

Both krlogin and krlogind needs a patch. My current source isn't 
very suitable for diffs due to local modifications so I'll have just 
include the few lines of code of interest at the bottom of the mail.
Also notice that the patch dosn't alter the protocol itself and
introduces no compatibility problems at all.

First, just a quick question.
I'm manily just using the kr* tools together with DCE and when I moved a 
keytab file made on our HP DCE server to a little endian machine for
the first time I got into trouble.

It seems like there are (at least) two versions of the keytab files
and only version 2 is stored in network byte order. Any special reason
for this? Is it a bug or is it a historical fuck up?

Luckily I was able to get DCE to produce v2 keytab by setting some 
configuration options, but not until digging through the kerberos 
source (yet another time) to find the problem, which indeed looked 
quite simple to fix in the kerberos libs as well.

Hope you find the krlogin patch usable. At least here, it actually makes
encrypted session workable (no noticable speed difference between 
encrypted and plain text sessions even on old 16Mhz 68020 machines
and VAX'es).


------------------------ krlogind.c ---- v5_des_write() --------------
int
v5_des_write(fd, buf, len)
     int fd;
     char *buf;
     int len;
{
    /* Make place for both data and the data lenght in the buffer we 
       are about to send - TNM */
    unsigned char len_buf[2*BUFSIZ+4];
    
    if (!do_encrypt)
      return(write(fd, buf, len));
    
    
    desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry);
    if (desoutbuf.length > sizeof(des_outbuf)){
        syslog(LOG_ERR,"Write size problem.");
        return(-1);
    }
    if ((krb5_encrypt(bsd_context, (krb5_pointer)buf,
                      desoutbuf.data,
                      len,
                      &eblock,
                      0))){
        syslog(LOG_ERR,"Write encrypt problem.");
        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);

    /* By making sure that both the length of the data, and the data itself
       is send in the same package with a memcpy and one write instead of
       two writes, we might increase interactive responce considerably.   
       - TNM
     */ 
     
    memcpy(&len_buf[4], desoutbuf.data, desoutbuf.length);

    if (write(fd, len_buf, desoutbuf.length + 4) != desoutbuf.length + 4 ){
        syslog(LOG_ERR,"Could not write out all data.");
        return(-1);
    }
    else return(len);
}

------------------------ krlogin.c ---- v5_des_write() --------------
int des_write(fd, buf, len)
     int fd;
     char *buf;
     int len;
{

    /* Make place for both data and the data lenght in the buffer we 
       are about to send - TNM */
    unsigned char len_buf[2*BUFSIZ+4];
    
    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");
        return(-1);
    }
    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);

    /* By making sure that both the length of the data, and the data itself
       is send in the same package with a memcpy and one write instead of
       two writes, we might increase interactive responce considerably. 
       - TNM 
    */ 

     memcpy(&len_buf[4], desoutbuf.data, desoutbuf.length);
 
     if (write(fd, len_buf, desoutbuf.length + 4) != desoutbuf.length + 4 ){
         fprintf(stderr,"Could not write out all data.");
        }       
     else return(len); 
}


------- End of forwarded message -------

home help back first fref pref prev next nref lref last post