ALT Linux repositórios
S: | 1.21.2-alt1 |
5.0: | 1.6.3-alt6.M50.2 |
4.1: | 1.6.3-alt3.M41.4 |
4.0: | 1.5.1-alt4.M40.5 |
+updates: | 1.5.1-alt4.M40.5 |
3.0: | 1.4.1-alt1 |
Group :: Sistema/Bibliotecas
RPM: krb5
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: krb5-1.4-rh-server-sort.patch
Download
Download
Keep track of which KDC answered the previous request for a given library
context. When we want to send data to a KDC for a realm, if the one which
answered last time is in the list of servers which might be consulted, move
it to the top of the list.
The aim is to compensate for servers which aren't responding, or which are
taking so much time to respond, that a server to which we sent the request
more than a second later responded before it. An artifact of this approach is
that if the first server responds before we transmit to a second server, the
behavior doesn't changed.
Removing unresponsive servers from the list could, on pathological networks,
leave us with no servers in the list, so we won't do that.
--- krb5-1.4/src/include/k5-int.h 2004-12-08 15:20:12.000000000 -0500
+++ krb5-1.4/src/include/k5-int.h 2005-02-21 14:57:08.000000000 -0500
@@ -1047,6 +1047,8 @@
#ifdef KRB5_DNS_LOOKUP
krb5_boolean profile_in_memory;
#endif /* KRB5_DNS_LOOKUP */
+
+ krb5_data *previous_kdc, *previous_master_kdc;
};
/* could be used in a table to find an etype and initialize a block */
--- krb5-1.4/src/lib/krb4/send_to_kdc.c 2004-02-27 00:24:38.000000000 -0500
+++ krb5-1.4/src/lib/krb4/send_to_kdc.c 2005-02-21 15:51:27.000000000 -0500
@@ -47,6 +47,7 @@
/* These are really defaults from getservbyname() or hardcoded. */
static int cached_krb_udp_port = 0;
static int cached_krbsec_udp_port = 0;
+static krb5_data *cached_kdc_address = NULL;
int krb4int_send_to_kdc_addr(KTEXT, KTEXT, char *,
struct sockaddr *, socklen_t *);
@@ -176,12 +177,50 @@
if (al.naddrs == 0) {
DEB (("%s: can't find any Kerberos host.\n", prog));
retval = SKDC_CANT;
+ } else {
+ int j, winner;
+ struct addrinfo *replier = NULL;
+ krb5_data *previous;
+
+ previous = cached_kdc_address;
+ if (previous)
+ for (j = 0; j < al.naddrs; j++)
+ if ((al.addrs[j]->ai_addrlen == previous->length) &&
+ (memcmp(al.addrs[j]->ai_addr, previous->data,
+ previous->length) == 0)) {
+ struct addrinfo *tmp;
+ tmp = al.addrs[0];
+ al.addrs[0] = al.addrs[j];
+ al.addrs[j] = tmp;
+ break;
+ }
+ message.length = pkt->length;
+ message.data = (char *)pkt->dat; /* XXX yuck */
+ winner = -1;
+ retval = internals.sendto_udp(NULL, &message, &al, &reply, addr,
+ addrlen, &winner);
+ if ((winner >= 0) && (winner < al.naddrs)) {
+ previous = (krb5_data *) malloc (sizeof(krb5_data));
+ replier = al.addrs[winner];
+ if (previous) {
+ previous->length = 0;
+ previous->data = malloc (replier->ai_addrlen);
+ if (previous->data == NULL) {
+ free (previous);
+ previous = NULL;
+ } else {
+ memcpy (previous->data, replier->ai_addr,
+ replier->ai_addrlen);
+ previous->length = replier->ai_addrlen;
+ }
+ }
+ if (cached_kdc_address) {
+ free(cached_kdc_address->data);
+ free(cached_kdc_address);
+ }
+ cached_kdc_address = previous;
+ }
}
-
- message.length = pkt->length;
- message.data = (char *)pkt->dat; /* XXX yuck */
- retval = internals.sendto_udp(NULL, &message, &al, &reply, addr,
- addrlen, NULL);
DEB(("sendto_udp returns %d\n", retval));
free_al:
internals.free_addrlist(&al);
--- krb5-1.4/src/lib/krb5/os/sendto_kdc.c 2004-08-27 20:25:24.000000000 -0400
+++ krb5-1.4/src/lib/krb5/os/sendto_kdc.c 2005-02-22 01:21:16.000000000 -0500
@@ -332,8 +332,53 @@
}
if (addrs.naddrs > 0) {
+ int j;
+ struct addrinfo *replier = NULL;
+ krb5_data *previous;
+
+ if (*use_master)
+ previous = context->previous_master_kdc;
+ else
+ previous = context->previous_kdc;
+ if (previous)
+ for (j = 0; j < addrs.naddrs; j++)
+ if ((addrs.addrs[j]->ai_addrlen == previous->length) &&
+ (memcmp(addrs.addrs[j]->ai_addr, previous->data,
+ previous->length) == 0)) {
+ struct addrinfo *tmp;
+ tmp = addrs.addrs[0];
+ addrs.addrs[0] = addrs.addrs[j];
+ addrs.addrs[j] = tmp;
+ break;
+ }
+ addr_used = -1;
retval = krb5int_sendto (context, message, &addrs, reply, 0, 0,
&addr_used);
+ if ((addr_used >= 0) && (addr_used < addrs.naddrs)) {
+ replier = addrs.addrs[addr_used];
+ previous = (krb5_data *) malloc(sizeof(krb5_data));
+ if (previous) {
+ previous->length = 0;
+ previous->data = malloc (replier->ai_addrlen);
+ if (previous->data == NULL) {
+ free (previous);
+ previous = NULL;
+ } else {
+ memcpy (previous->data, replier->ai_addr,
+ replier->ai_addrlen);
+ previous->length = replier->ai_addrlen;
+ }
+ }
+ if (*use_master) {
+ if (context->previous_master_kdc)
+ krb5_free_data (context, context->previous_master_kdc);
+ context->previous_master_kdc = previous;
+ } else {
+ if (context->previous_kdc)
+ krb5_free_data (context, context->previous_kdc);
+ context->previous_kdc = previous;
+ }
+ }
if (retval == 0) {
/*
* Set use_master to 1 if we ended up talking to a master when
--- krb5-1.4/src/lib/krb5/krb/init_ctx.c 2004-06-02 18:35:33.000000000 -0400
+++ krb5-1.4/src/lib/krb5/krb/init_ctx.c 2005-02-21 14:57:08.000000000 -0500
@@ -228,6 +228,10 @@
ctx->use_conf_ktypes = 0;
ctx->udp_pref_limit = -1;
+
+ ctx->previous_kdc = NULL;
+ ctx->previous_master_kdc = NULL;
+
*context = ctx;
return 0;
@@ -266,6 +270,11 @@
ctx->ser_ctx = 0;
}
+ if (ctx->previous_kdc)
+ krb5_free_data(ctx, ctx->previous_kdc);
+ if (ctx->previous_master_kdc)
+ krb5_free_data(ctx, ctx->previous_master_kdc);
+
ctx->magic = 0;
free(ctx);
}