#define INCLUDE_RXKAD_PRIVATE_DECLS
-RCSID
- ("$Header$");
#ifdef KERNEL
#ifndef UKERNEL
#include "afs/stds.h"
#include "afs/afs_osi.h"
-#ifdef AFS_AIX_ENV
+#if defined(AFS_AIX_ENV) || defined(AFS_AUX_ENV) || defined(AFS_SUN5_ENV)
#include "h/systm.h"
#endif
-#ifdef AFS_DARWIN60_ENV
+#if defined(AFS_DARWIN60_ENV) || defined(AFS_OBSD_ENV)
#include "h/kernel.h"
#endif
#include "h/types.h"
#else /* KERNEL */
#include <afs/stds.h>
#include <sys/types.h>
+#include <string.h>
#include <time.h>
#ifdef AFS_NT40_ENV
#include <winsock2.h>
#endif
#include <rx/rx.h>
#include <rx/xdr.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
+#include <afs/afsutil.h>
#endif /* KERNEL */
+#include <des/stats.h>
#include "private_data.h"
#define XPRT_RXKAD_COMMON
#endif
/* variable initialization for the benefit of darwin compiler; if it causes
problems elsewhere, conditionalize for darwin or fc_test compile breaks */
-struct rxkad_stats rxkad_stats = { 0 };
+#ifdef AFS_PTHREAD_ENV
+struct rxkad_global_stats rxkad_global_stats = { 0 };
+pthread_mutex_t rxkad_global_stats_lock;
+pthread_key_t rxkad_stats_key;
+#else /* AFS_PTHREAD_ENV */
+#if defined(KERNEL) && !defined(UKERNEL)
+struct rxkad_stats rxkad_stats = { { 0 } };
+#else
+/* Move delaration of this to des/key_sched.c */
+#endif
+#endif /* AFS_PTHREAD_ENV */
+
+#ifdef AFS_PTHREAD_ENV
+/* rxkad_stats related stuff */
+
+/*
+ * Macro to insert an element at the tail of a doubly linked list
+ */
+#define DLL_INSERT_TAIL(ptr,head,tail,next,prev) \
+ do { \
+ (ptr)->next = NULL; \
+ (ptr)->prev = (tail); \
+ (tail) = (ptr); \
+ if ((ptr)->prev) \
+ (ptr)->prev->next = (ptr); \
+ else \
+ (head) = (ptr); \
+ assert((head) && ((head)->prev == NULL)); \
+ } while(0)
+
+void rxkad_global_stats_init(void) {
+ assert(pthread_mutex_init(&rxkad_global_stats_lock, (const pthread_mutexattr_t *)0) == 0);
+ assert(pthread_key_create(&rxkad_stats_key, NULL) == 0);
+ memset(&rxkad_global_stats, 0, sizeof(rxkad_global_stats));
+}
+
+rxkad_stats_t *
+rxkad_thr_stats_init(void) {
+ rxkad_stats_t * rxkad_stats;
+ rxkad_stats = (rxkad_stats_t *)malloc(sizeof(rxkad_stats_t));
+ assert(rxkad_stats != NULL && pthread_setspecific(rxkad_stats_key,rxkad_stats) == 0);
+ memset(rxkad_stats,0,sizeof(rxkad_stats_t));
+ RXKAD_GLOBAL_STATS_LOCK;
+ DLL_INSERT_TAIL(rxkad_stats, rxkad_global_stats.first, rxkad_global_stats.last, next, prev);
+ RXKAD_GLOBAL_STATS_UNLOCK;
+ return rxkad_stats;
+}
+
+int rxkad_stats_agg(rxkad_stats_t * rxkad_stats) {
+ rxkad_stats_t * thr_stats;
+ assert(rxkad_stats != NULL);
+ memset(rxkad_stats, 0, sizeof(rxkad_stats_t));
+ RXKAD_GLOBAL_STATS_LOCK;
+ for (thr_stats = rxkad_global_stats.first; thr_stats != NULL; thr_stats = thr_stats->next) {
+ rxkad_stats->connections[0] += thr_stats->connections[0];
+ rxkad_stats->connections[1] += thr_stats->connections[1];
+ rxkad_stats->connections[2] += thr_stats->connections[2];
+ rxkad_stats->destroyObject += thr_stats->destroyObject;
+ rxkad_stats->destroyClient += thr_stats->destroyClient;
+ rxkad_stats->destroyUnused += thr_stats->destroyUnused;
+ rxkad_stats->destroyUnauth += thr_stats->destroyUnauth;
+ rxkad_stats->destroyConn[0] += thr_stats->destroyConn[0];
+ rxkad_stats->destroyConn[1] += thr_stats->destroyConn[1];
+ rxkad_stats->destroyConn[2] += thr_stats->destroyConn[2];
+ rxkad_stats->expired += thr_stats->expired;
+ rxkad_stats->challengesSent += thr_stats->challengesSent;
+ rxkad_stats->challenges[0] += thr_stats->challenges[0];
+ rxkad_stats->challenges[1] += thr_stats->challenges[1];
+ rxkad_stats->challenges[2] += thr_stats->challenges[2];
+ rxkad_stats->responses[0] += thr_stats->responses[0];
+ rxkad_stats->responses[1] += thr_stats->responses[1];
+ rxkad_stats->responses[2] += thr_stats->responses[2];
+ rxkad_stats->preparePackets[0] += thr_stats->preparePackets[0];
+ rxkad_stats->preparePackets[1] += thr_stats->preparePackets[1];
+ rxkad_stats->preparePackets[2] += thr_stats->preparePackets[2];
+ rxkad_stats->preparePackets[3] += thr_stats->preparePackets[3];
+ rxkad_stats->preparePackets[4] += thr_stats->preparePackets[4];
+ rxkad_stats->preparePackets[5] += thr_stats->preparePackets[5];
+ rxkad_stats->checkPackets[0] += thr_stats->checkPackets[0];
+ rxkad_stats->checkPackets[1] += thr_stats->checkPackets[1];
+ rxkad_stats->checkPackets[2] += thr_stats->checkPackets[2];
+ rxkad_stats->checkPackets[3] += thr_stats->checkPackets[3];
+ rxkad_stats->checkPackets[4] += thr_stats->checkPackets[4];
+ rxkad_stats->checkPackets[5] += thr_stats->checkPackets[5];
+ rxkad_stats->bytesEncrypted[0] += thr_stats->bytesEncrypted[0];
+ rxkad_stats->bytesEncrypted[1] += thr_stats->bytesEncrypted[1];
+ rxkad_stats->bytesDecrypted[0] += thr_stats->bytesDecrypted[0];
+ rxkad_stats->bytesDecrypted[1] += thr_stats->bytesDecrypted[1];
+ rxkad_stats->fc_encrypts[0] += thr_stats->fc_encrypts[0];
+ rxkad_stats->fc_encrypts[1] += thr_stats->fc_encrypts[1];
+ rxkad_stats->fc_key_scheds += thr_stats->fc_key_scheds;
+ rxkad_stats->des_encrypts[0] += thr_stats->des_encrypts[0];
+ rxkad_stats->des_encrypts[1] += thr_stats->des_encrypts[1];
+ rxkad_stats->des_key_scheds += thr_stats->des_key_scheds;
+ rxkad_stats->des_randoms += thr_stats->des_randoms;
+ rxkad_stats->clientObjects += thr_stats->clientObjects;
+ rxkad_stats->serverObjects += thr_stats->serverObjects;
+ rxkad_stats->spares[0] += thr_stats->spares[0];
+ rxkad_stats->spares[1] += thr_stats->spares[1];
+ rxkad_stats->spares[2] += thr_stats->spares[2];
+ rxkad_stats->spares[3] += thr_stats->spares[3];
+ rxkad_stats->spares[4] += thr_stats->spares[4];
+ rxkad_stats->spares[5] += thr_stats->spares[5];
+ rxkad_stats->spares[6] += thr_stats->spares[6];
+ rxkad_stats->spares[7] += thr_stats->spares[7];
+ }
+ RXKAD_GLOBAL_STATS_UNLOCK;
+ return 0;
+}
+#endif /* AFS_PTHREAD_ENV */
/* static prototypes */
static afs_int32 ComputeSum(struct rx_packet *apacket,
rxkad_SetupEndpoint(aconnp, &tendpoint);
memcpy((void *)xor, aivec, 2 * sizeof(afs_int32));
- fc_cbc_encrypt(&tendpoint, &tendpoint, sizeof(tendpoint), aschedule, xor,
+ fc_cbc_encrypt(&tendpoint, &tendpoint, sizeof(tendpoint), *aschedule, xor,
ENCRYPT);
memcpy(aresult,
((char *)&tendpoint) + sizeof(tendpoint) - ENCRYPTIONBLOCKSIZE,
word[0] ^= aivec[0];
word[1] ^= aivec[1];
/* encrypts word as if it were a character string */
- fc_ecb_encrypt(word, word, aschedule, ENCRYPT);
+ fc_ecb_encrypt(word, word, *aschedule, ENCRYPT);
t = ntohl(word[1]);
t = (t >> 16) & 0xffff;
if (t == 0)
tcp = (struct rxkad_cprivate *)aobj->privateData;
rxi_Free(aobj, sizeof(struct rx_securityClass));
if (tcp->type & rxkad_client) {
- rxi_Free(tcp, sizeof(struct rxkad_cprivate));
+ afs_int32 psize = PDATA_SIZE(tcp->ticketLen);
+ rxi_Free(tcp, psize);
} else if (tcp->type & rxkad_server) {
rxi_Free(tcp, sizeof(struct rxkad_sprivate));
} else {
return RXKADINCONSISTENCY;
} /* unknown type */
- LOCK_RXKAD_STATS;
- rxkad_stats.destroyObject++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(destroyObject);
return 0;
}
return RXKADINCONSISTENCY;
rxkad_SetLevel(aconn, tcp->level); /* set header and trailer sizes */
rxkad_AllocCID(aobj, aconn); /* CHANGES cid AND epoch!!!! */
- rxkad_DeriveXORInfo(aconn, tcp->keysched, tcp->ivec, tccp->preSeq);
- LOCK_RXKAD_STATS;
- rxkad_stats.connections[rxkad_LevelIndex(tcp->level)]++;
- UNLOCK_RXKAD_STATS;
+ rxkad_DeriveXORInfo(aconn, (fc_KeySchedule *)tcp->keysched, (char *)tcp->ivec, (char *)tccp->preSeq);
+ INC_RXKAD_STATS(connections[rxkad_LevelIndex(tcp->level)]);
}
aobj->refCount++; /* attached connection */
sconn = (struct rxkad_sconn *)aconn->securityData;
if (sconn) {
aconn->securityData = 0;
- LOCK_RXKAD_STATS;
if (sconn->authenticated)
- rxkad_stats.destroyConn[rxkad_LevelIndex(sconn->level)]++;
+ INC_RXKAD_STATS(destroyConn[rxkad_LevelIndex(sconn->level)]);
else
- rxkad_stats.destroyUnauth++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(destroyUnauth);
rock = sconn->rock;
if (rock)
rxi_Free(rock, sizeof(struct rxkad_serverinfo));
rxi_Free(sconn, sizeof(struct rxkad_sconn));
} else {
- LOCK_RXKAD_STATS;
- rxkad_stats.destroyUnused++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(destroyUnused);
}
} else { /* client */
struct rxkad_cconn *cconn;
aconn->securityData = 0;
rxi_Free(cconn, sizeof(struct rxkad_cconn));
}
- LOCK_RXKAD_STATS;
- rxkad_stats.destroyClient++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(destroyClient);
}
aobj->refCount--; /* decrement connection counter */
if (aobj->refCount <= 0) {
{
struct rx_connection *tconn;
rxkad_level level;
- fc_KeySchedule *schedule;
+ const fc_KeySchedule *schedule;
fc_InitializationVector *ivec;
int len;
- int nlen;
+ int nlen = 0;
u_int word; /* so we get unsigned right-shift */
int checkCksum;
afs_int32 *preSeq;
if (sconn && sconn->authenticated
&& (osi_Time() < sconn->expirationTime)) {
level = sconn->level;
- LOCK_RXKAD_STATS;
- rxkad_stats.checkPackets[rxkad_StatIndex(rxkad_server, level)]++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(checkPackets[rxkad_StatIndex(rxkad_server, level)]);
sconn->stats.packetsReceived++;
sconn->stats.bytesReceived += len;
- schedule = (fc_KeySchedule *) sconn->keysched;
+ schedule = (const fc_KeySchedule *) sconn->keysched;
ivec = (fc_InitializationVector *) sconn->ivec;
} else {
- LOCK_RXKAD_STATS;
- rxkad_stats.expired++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(expired);
return RXKADEXPIRED;
}
preSeq = sconn->preSeq;
if (!(tcp->type & rxkad_client))
return RXKADINCONSISTENCY;
level = tcp->level;
- LOCK_RXKAD_STATS;
- rxkad_stats.checkPackets[rxkad_StatIndex(rxkad_client, level)]++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(checkPackets[rxkad_StatIndex(rxkad_client, level)]);
cconn->stats.packetsReceived++;
cconn->stats.bytesReceived += len;
preSeq = cconn->preSeq;
- schedule = (fc_KeySchedule *) tcp->keysched;
+ schedule = (const fc_KeySchedule *) tcp->keysched;
ivec = (fc_InitializationVector *) tcp->ivec;
}
if (checkCksum) {
- code = ComputeSum(apacket, schedule, preSeq);
+ code = ComputeSum(apacket, (fc_KeySchedule *)schedule, preSeq);
if (code != rx_GetPacketCksum(apacket))
return RXKADSEALEDINCON;
}
return 0; /* shouldn't happen */
case rxkad_auth:
rx_Pullup(apacket, 8); /* the following encrypts 8 bytes only */
- fc_ecb_encrypt(rx_DataOf(apacket), rx_DataOf(apacket), schedule,
+ fc_ecb_encrypt(rx_DataOf(apacket), rx_DataOf(apacket), *schedule,
DECRYPT);
break;
case rxkad_crypt:
- code = rxkad_DecryptPacket(tconn, schedule, ivec, len, apacket);
+ code = rxkad_DecryptPacket(tconn, schedule, (const fc_InitializationVector *)ivec, len, apacket);
if (code)
return code;
break;
fc_KeySchedule *schedule;
fc_InitializationVector *ivec;
int len;
- int nlen;
+ int nlen = 0;
int word;
afs_int32 code;
afs_int32 *preSeq;
if (sconn && sconn->authenticated
&& (osi_Time() < sconn->expirationTime)) {
level = sconn->level;
- LOCK_RXKAD_STATS;
- rxkad_stats.
- preparePackets[rxkad_StatIndex(rxkad_server, level)]++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(preparePackets[rxkad_StatIndex(rxkad_server, level)]);
sconn->stats.packetsSent++;
sconn->stats.bytesSent += len;
schedule = (fc_KeySchedule *) sconn->keysched;
ivec = (fc_InitializationVector *) sconn->ivec;
} else {
- LOCK_RXKAD_STATS;
- rxkad_stats.expired++; /* this is a pretty unlikely path... */
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(expired); /* this is a pretty unlikely path... */
return RXKADEXPIRED;
}
preSeq = sconn->preSeq;
if (!(tcp->type & rxkad_client))
return RXKADINCONSISTENCY;
level = tcp->level;
- LOCK_RXKAD_STATS;
- rxkad_stats.preparePackets[rxkad_StatIndex(rxkad_client, level)]++;
- UNLOCK_RXKAD_STATS;
+ INC_RXKAD_STATS(preparePackets[rxkad_StatIndex(rxkad_client, level)]);
cconn->stats.packetsSent++;
cconn->stats.bytesSent += len;
preSeq = cconn->preSeq;
nlen - (len + rx_GetSecurityHeaderSize(tconn)));
}
rx_Pullup(apacket, 8); /* the following encrypts 8 bytes only */
- fc_ecb_encrypt(rx_DataOf(apacket), rx_DataOf(apacket), schedule,
+ fc_ecb_encrypt(rx_DataOf(apacket), rx_DataOf(apacket), *schedule,
ENCRYPT);
break;
case rxkad_crypt:
rxi_RoundUpPacket(apacket,
nlen - (len + rx_GetSecurityHeaderSize(tconn)));
}
- code = rxkad_EncryptPacket(tconn, schedule, ivec, nlen, apacket);
+ code = rxkad_EncryptPacket(tconn, (const fc_KeySchedule *)schedule, (const fc_InitializationVector *)ivec, nlen, apacket);
if (code)
return code;
break;