From: Tom Yu Date: Fri, 10 Feb 2012 21:19:07 +0000 (+0000) Subject: Pull up r25660 from trunk X-Git-Tag: krb5-1.10.1-final~14 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=72e9558135f4e0eabdb6aa1139c6dc59ea24b9fe;p=krb5.git Pull up r25660 from trunk ------------------------------------------------------------------------ r25660 | ghudson | 2012-01-26 16:56:16 -0500 (Thu, 26 Jan 2012) | 22 lines ticket: 7082 subject: Various lookaside cache fixes target_version: 1.10 tags: pullup Don't touch the lookaside cache if we're responding with a lookaside cache entry. Also, leave the null entry behind if we're deliberately dropping a request (a rare case) so that we don't have to process it again. Fixes several lookaside problems in 1.10: * When dropping a request because it was already being processed, we were erroneously removing the null entry, causing us to process the request again upon a second retransmit. * When responding to a finished request with a lookaside entry, we were removing and re-adding the entry to the cache, resetting its time and performing unnecessary work. * We were not caching responses we couldn't deliver because they were too big for UDP, causing us to re-process the request when it came in again via TCP instead of simply delivering the cached response. ticket: 7082 version_fixed: 1.10.1 status: resolved git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-10@25681 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c index 75e6f0a60..efb54ed64 100644 --- a/src/kdc/dispatch.c +++ b/src/kdc/dispatch.c @@ -44,20 +44,11 @@ struct dispatch_state { }; static void -finish_dispatch(void *arg, krb5_error_code code, krb5_data *response) +finish_dispatch(struct dispatch_state *state, krb5_error_code code, + krb5_data *response) { - struct dispatch_state *state = arg; - loop_respond_fn oldrespond; - void *oldarg; - - assert(state); - oldrespond = state->respond; - oldarg = state->arg; - -#ifndef NOCACHE - /* Remove our NULL cache entry to indicate request completion. */ - kdc_remove_lookaside(kdc_context, state->request); -#endif + loop_respond_fn oldrespond = state->respond; + void *oldarg = state->arg; if (state->is_tcp == 0 && response && response->length > max_dgram_reply_size) { @@ -70,14 +61,27 @@ finish_dispatch(void *arg, krb5_error_code code, krb5_data *response) error_message(code)); } + free(state); + (*oldrespond)(oldarg, code, response); +} + +static void +finish_dispatch_cache(void *arg, krb5_error_code code, krb5_data *response) +{ + struct dispatch_state *state = arg; + #ifndef NOCACHE - /* put the response into the lookaside buffer */ - else if (!code && response) + /* Remove the null cache entry unless we actually want to discard this + * request. */ + if (code != KRB5KDC_ERR_DISCARD) + kdc_remove_lookaside(kdc_context, state->request); + + /* Put the response into the lookaside buffer (if we produced one). */ + if (code == 0 && response != NULL) kdc_insert_lookaside(state->request, response); #endif - free(state); - (*oldrespond)(oldarg, code, response); + finish_dispatch(state, code, response); } void @@ -167,7 +171,7 @@ dispatch(void *cb, struct sockaddr *local_saddr, * process_as_req frees the request if it is called */ if (!(retval = setup_server_realm(as_req->server))) { - process_as_req(as_req, pkt, from, vctx, finish_dispatch, + process_as_req(as_req, pkt, from, vctx, finish_dispatch_cache, state); return; }