X-Git-Url: http://andersk.mit.edu/gitweb/libfaim.git/blobdiff_plain/b13c9e1382d31677b7b7e58b1bcbfc123228c792..3e2c7bcfd0f176bf1bb5726dcf61d85b32dc72b2:/aim_snac.c diff --git a/aim_snac.c b/aim_snac.c index 6cea5d5..ae46e47 100644 --- a/aim_snac.c +++ b/aim_snac.c @@ -18,7 +18,7 @@ /* * Called from aim_session_init() to initialize the hash. */ -void aim_initsnachash(struct aim_session_t *sess) +faim_internal void aim_initsnachash(struct aim_session_t *sess) { int i; @@ -30,21 +30,39 @@ void aim_initsnachash(struct aim_session_t *sess) return; } +faim_internal unsigned long aim_cachesnac(struct aim_session_t *sess, + const unsigned short family, + const unsigned short type, + const unsigned short flags, + const void *data, const int datalen) +{ + struct aim_snac_t snac; + + snac.id = sess->snac_nextid++; + snac.family = family; + snac.type = type; + snac.flags = flags; + + snac.data = malloc(datalen); + memcpy(snac.data, data, datalen); + + return aim_newsnac(sess, &snac); +} + /* * Clones the passed snac structure and caches it in the * list/hash. */ -u_long aim_newsnac(struct aim_session_t *sess, - struct aim_snac_t *newsnac) +faim_internal unsigned long aim_newsnac(struct aim_session_t *sess, + struct aim_snac_t *newsnac) { - struct aim_snac_t *snac = NULL, *cur = NULL; + struct aim_snac_t *snac = NULL; int index; if (!newsnac) return 0; - snac = calloc(1, sizeof(struct aim_snac_t)); - if (!snac) + if (!(snac = calloc(1, sizeof(struct aim_snac_t)))) return 0; memcpy(snac, newsnac, sizeof(struct aim_snac_t)); snac->issuetime = time(&snac->issuetime); @@ -53,12 +71,8 @@ u_long aim_newsnac(struct aim_session_t *sess, index = snac->id % FAIM_SNAC_HASH_SIZE; faim_mutex_lock(&sess->snac_hash_locks[index]); - if (!sess->snac_hash[index]) - sess->snac_hash[index] = snac; - else { - snac->next = sess->snac_hash[index]; - sess->snac_hash[index] = snac; - } + snac->next = sess->snac_hash[index]; + sess->snac_hash[index] = snac; faim_mutex_unlock(&sess->snac_hash_locks[index]); return(snac->id); @@ -71,10 +85,10 @@ u_long aim_newsnac(struct aim_session_t *sess, * The returned structure must be freed by the caller. * */ -struct aim_snac_t *aim_remsnac(struct aim_session_t *sess, - u_long id) +faim_internal struct aim_snac_t *aim_remsnac(struct aim_session_t *sess, + u_long id) { - struct aim_snac_t *cur; + struct aim_snac_t *cur = NULL; int index; index = id % FAIM_SNAC_HASH_SIZE; @@ -82,11 +96,9 @@ struct aim_snac_t *aim_remsnac(struct aim_session_t *sess, faim_mutex_lock(&sess->snac_hash_locks[index]); if (!sess->snac_hash[index]) ; - else if (!sess->snac_hash[index]->next) { - if (sess->snac_hash[index]->id == id) { - cur = sess->snac_hash[index]; - sess->snac_hash[index] = NULL; - } + else if (sess->snac_hash[index]->id == id) { + cur = sess->snac_hash[index]; + sess->snac_hash[index] = cur->next; } else { cur = sess->snac_hash[index]; while (cur->next) { @@ -113,46 +125,50 @@ struct aim_snac_t *aim_remsnac(struct aim_session_t *sess, * maxage is the _minimum_ age in seconds to keep SNACs. * */ -int aim_cleansnacs(struct aim_session_t *sess, - int maxage) +faim_internal int aim_cleansnacs(struct aim_session_t *sess, + int maxage) { - struct aim_snac_t *cur; - struct aim_snac_t *remed = NULL; - time_t curtime; int i; for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) { + struct aim_snac_t *cur = NULL, *next = NULL, *prev = NULL; + time_t curtime; + faim_mutex_lock(&sess->snac_hash_locks[i]); - if (!sess->snac_hash[i]) - ; - else if (!sess->snac_hash[i]->next) { - if ((sess->snac_hash[i]->issuetime + maxage) >= curtime) { - remed = sess->snac_hash[i]; - if(remed->data) - free(remed->data); - free(remed); - sess->snac_hash[i] = NULL; - } - } else { - cur = sess->snac_hash[i]; - while(cur && cur->next) { - if ((cur->next->issuetime + maxage) >= curtime) { - remed = cur->next; - cur->next = cur->next->next; - if (remed->data) - free(remed->data); - free(remed); - } - cur = cur->next; + if (!sess->snac_hash[i]) { + faim_mutex_unlock(&sess->snac_hash_locks[i]); + continue; + } + + curtime = time(NULL); /* done here in case we waited for the lock */ + + cur = sess->snac_hash[i]; + while (cur) { + next = cur->next; + if ((curtime - cur->issuetime) > maxage) { + if (sess->snac_hash[i] == cur) + prev = sess->snac_hash[i] = next; + else + prev->next = next; + + /* XXX should we have destructors here? */ + if (cur->data) + free(cur->data); + free(cur); + + } else { + prev = cur; } + cur = next; } + faim_mutex_unlock(&sess->snac_hash_locks[i]); } return 0; } -int aim_putsnac(u_char *buf, int family, int subtype, int flags, u_long snacid) +faim_internal int aim_putsnac(u_char *buf, int family, int subtype, int flags, u_long snacid) { int curbyte = 0; curbyte += aimutil_put16(buf+curbyte, (u_short)(family&0xffff));