diff options
author | Greg Hudson <ghudson@mit.edu> | 2012-01-26 21:56:16 +0000 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2012-01-26 21:56:16 +0000 |
commit | 548f8461c75c5638f0c24ca86364a17f59619b89 (patch) | |
tree | 80d9505fbd554b0a328e778dd4a2ebe3af402146 /src/kdc/dispatch.c | |
parent | d91163e40b15252e8189d0593e3125519b351c9c (diff) | |
download | krb5-548f8461c75c5638f0c24ca86364a17f59619b89.tar.gz krb5-548f8461c75c5638f0c24ca86364a17f59619b89.tar.xz krb5-548f8461c75c5638f0c24ca86364a17f59619b89.zip |
Various lookaside cache fixes
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
target_version: 1.10
tags: pullup
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25660 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kdc/dispatch.c')
-rw-r--r-- | src/kdc/dispatch.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c index b4c02f3247..efe7098814 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; } |