Skip to content

Commit

Permalink
Various lookaside cache fixes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
greghudson committed Jan 26, 2012
1 parent d91163e commit 548f846
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions src/kdc/dispatch.c
Expand Up @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 548f846

Please sign in to comment.