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