Enhancing the The Keytab read routines

Brian brianslist at apple.com
Tue Aug 12 15:11:17 EDT 2003


I do have large  entries (ex 500 or > ) in the keytab file on the AS  
server side. and when the server does a verification it takes at least  
3 to 5 seconds for and accept_sec context to go through ( verify) .  
Then we noticed that the read routine  on  ktfile.c reads bytes by  
bytes and this makes it slower  this how a ktrace looks like (Mac OS X  
10.2.6)

"S"
  21343 verify   RET   read 1
  21343 verify   CALL  read(0x3,0xa0006b8b,0x1)
  21343 verify   GIO   fd 3 read 1 byte
        "O"
  21343 verify   RET   read 1
  21343 verify   CALL  read(0x3,0xa0006b8b,0x1)
  21343 verify   GIO   fd 3 read 1 byte
        "U"
  21343 verify   RET   read 1
  21343 verify   CALL  read(0x3,0xa0006b8b,0x1)
  21343 verify   GIO   fd 3 read 1 byte
        "T"
  21343 verify   RET   read 1
  21343 verify   CALL  read(0x3,0xa0006b8b,0x1)
  21343 verify   GIO   fd 3 read 1 byte
        "H"
  21343 verify   RET   read 1
  21343 verify   CALL  read(0x3,0xa0006b8b,0x1)
  21343 verify   GIO   fd 3 read 1 byte
        "P"
  21343 verify   RET   read 1
  21343 verify   CALL  read(0x3,0xa0006b8b,0x1)
  21343 verify   GIO   fd 3 read 1 byte
        "A"
  21343 verify   RET   read 1
  21343 verify   CALL  read(0x3,0xa0006b8b,0x1)
  21343 verify   GIO   fd 3 read 1 byte
        "R"
  21343 verify   RET   read 1
  21343 verify   CALL  read(0x3,0xa0006b8b,0x1)
  21343 verify   GIO   fd 3 read 1 byte

   found out that  the xfread read 1byte of data multiple times,I  
changed this implementation to the read API and made read to perform  
block reads. Now the performance has significantly improved to a sec or  
less , Now my question is was the earlier byte by byte read done for a  
reason? will the change that I did have any other effect etc ? below is  
the change that I did


krb5_error_code
krb5_ktfileint_internal_read_entry(krb5_context context, krb5_keytab  
id, krb5_keytab_entry *ret_entry, krb5_int32 *delete_point)
  ....


     for (i = 0; i < count; i++) {
	princ = krb5_princ_component(context, ret_entry->principal, i);
	if (!xfread(&princ_size, sizeof(princ_size), 1, KTFILEP(id))) {
	    error = KRB5_KT_END;
	    goto fail;
         }
	if (KTVERSION(id) != KRB5_KT_VNO_1)
	    princ_size = ntohs(princ_size);
	if (!princ_size || (princ_size < 0)) {
	    error = KRB5_KT_END;
	    goto fail;
         }

	u_princ_size = princ_size;
	princ->length = u_princ_size;
	princ->data = malloc(u_princ_size+1);
	if (!princ->data) {
	    error = ENOMEM;
	    goto fail;
         }
	
	// Brian Change Here read more faster
	//fread(tmpdata,u_princ_size ,1, KTFILEP(id)
	
	read( KTFILEP(id)->_file,princ->data,u_princ_size);
	
	princ->data[princ_size] = 0; /* Null terminate */
     }

     /* read in the principal type, if we can get it */

     if (KTVERSION(id) != KRB5_KT_VNO_1) {

               //Brian
	     if  
(read(KTFILEP(id)->_file,&ret_entry->principal->type,sizeof(ret_entry- 
 >principal->type))==-1)
	     //if  
(!xfread(&ret_entry->principal->type,sizeof(ret_entry->principal- 
 >type), 1, KTFILEP(id)))
	     {
			
		    error = KRB5_KT_END;
		    goto fail;
	     }
	    ret_entry->principal->type = ntohl(ret_entry->principal->type);
     }


     /* read in the timestamp */
     if (read(KTFILEP(id)->_file,&ret_entry->timestamp,  
sizeof(ret_entry->timestamp))==-1)
     {
     //if (!xfread(&ret_entry->timestamp, sizeof(ret_entry->timestamp),  
1, KTFILEP(id))) {
	error = KRB5_KT_END;
	goto fail;
     }

     if (KTVERSION(id) != KRB5_KT_VNO_1)
	ret_entry->timestamp = ntohl(ret_entry->timestamp);

     /* read in the version number */
     if (read(KTFILEP(id)->_file,&vno,sizeof(vno))==-1)
     {
     //if (!xfread(&vno, sizeof(vno), 1, KTFILEP(id))) {
	error = KRB5_KT_END;
	goto fail;
     }
     ret_entry->vno = (krb5_kvno)vno;

     /* key type */
     if (read(KTFILEP(id)->_file,&enctype,sizeof(enctype))==-1)
     {
     //if (!xfread(&enctype, sizeof(enctype), 1, KTFILEP(id))) {
	error = KRB5_KT_END;
	goto fail;
     }
     ret_entry->key.enctype = (krb5_enctype)enctype;

     if (KTVERSION(id) != KRB5_KT_VNO_1)
	ret_entry->key.enctype = ntohs(ret_entry->key.enctype);

     /* key contents */
     ret_entry->key.magic = KV5M_KEYBLOCK;

     if (read(KTFILEP(id)->_file,&count,sizeof(count))==-1)
     {
     //if (!xfread(&count, sizeof(count), 1, KTFILEP(id))) {
	error = KRB5_KT_END;
	goto fail;
     }

     if (KTVERSION(id) != KRB5_KT_VNO_1)
	count = ntohs(count);
     if (!count || (count < 0)) {
	error = KRB5_KT_END;
	goto fail;
     }

     u_count = count;
     ret_entry->key.length = u_count;

     ret_entry->key.contents = (krb5_octet *)malloc(u_count);
     if (!ret_entry->key.contents) {
	error = ENOMEM;
	goto fail;
     }

     //Brian
     if  
(read(KTFILEP(id)->_file,ret_entry- 
 >key.contents,sizeof(krb5_octet)*count)==-1)				
     //if (!xfread(ret_entry->key.contents, sizeof(krb5_octet),  
count,KTFILEP(id)))
     {
	error = KRB5_KT_END;
	goto fail;
     }










More information about the krbdev mailing list