]> andersk Git - libfaim.git/blame - src/snac.c
- Mon Sep 3 18:48:26 PDT 2001
[libfaim.git] / src / snac.c
CommitLineData
9de3ca7e 1/*
2 *
3 * Various SNAC-related dodads...
4 *
5 * outstanding_snacs is a list of aim_snac_t structs. A SNAC should be added
6 * whenever a new SNAC is sent and it should remain in the list until the
b13c9e13 7 * response for it has been receieved.
9de3ca7e 8 *
b13c9e13 9 * cleansnacs() should be called periodically by the client in order
10 * to facilitate the aging out of unreplied-to SNACs. This can and does
11 * happen, so it should be handled.
9de3ca7e 12 *
13 */
14
37ee990e 15#define FAIM_INTERNAL
dd60ff8b 16#include <aim.h>
9de3ca7e 17
b13c9e13 18/*
19 * Called from aim_session_init() to initialize the hash.
20 */
d410cf58 21faim_internal void aim_initsnachash(aim_session_t *sess)
b13c9e13 22{
d410cf58 23 int i;
b13c9e13 24
d410cf58 25 for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) {
26 sess->snac_hash[i] = NULL;
27 faim_mutex_init(&sess->snac_hash_locks[i]);
28 }
b13c9e13 29
d410cf58 30 return;
b13c9e13 31}
32
d410cf58 33faim_internal aim_snacid_t aim_cachesnac(aim_session_t *sess, const fu16_t family, const fu16_t type, const fu16_t flags, const void *data, const int datalen)
1ea867e3 34{
d410cf58 35 aim_snac_t snac;
1ea867e3 36
d410cf58 37 snac.id = sess->snacid_next++;
38 snac.family = family;
39 snac.type = type;
40 snac.flags = flags;
1ea867e3 41
d410cf58 42 if (datalen) {
43 if (!(snac.data = malloc(datalen)))
44 return 0; /* er... */
45 memcpy(snac.data, data, datalen);
46 } else
47 snac.data = NULL;
1ea867e3 48
d410cf58 49 return aim_newsnac(sess, &snac);
1ea867e3 50}
51
b13c9e13 52/*
53 * Clones the passed snac structure and caches it in the
54 * list/hash.
55 */
d410cf58 56faim_internal aim_snacid_t aim_newsnac(aim_session_t *sess, aim_snac_t *newsnac)
a25832e6 57{
d410cf58 58 aim_snac_t *snac;
59 int index;
b13c9e13 60
d410cf58 61 if (!newsnac)
62 return 0;
9de3ca7e 63
d410cf58 64 if (!(snac = malloc(sizeof(aim_snac_t))))
65 return 0;
66 memcpy(snac, newsnac, sizeof(aim_snac_t));
67 snac->issuetime = time(NULL);
b13c9e13 68
d410cf58 69 index = snac->id % FAIM_SNAC_HASH_SIZE;
b13c9e13 70
d410cf58 71 faim_mutex_lock(&sess->snac_hash_locks[index]);
72 snac->next = (aim_snac_t *)sess->snac_hash[index];
73 sess->snac_hash[index] = (void *)snac;
74 faim_mutex_unlock(&sess->snac_hash_locks[index]);
5b401785 75
d410cf58 76 return snac->id;
a25832e6 77}
9de3ca7e 78
b13c9e13 79/*
80 * Finds a snac structure with the passed SNAC ID,
81 * removes it from the list/hash, and returns a pointer to it.
82 *
83 * The returned structure must be freed by the caller.
84 *
85 */
d410cf58 86faim_internal aim_snac_t *aim_remsnac(aim_session_t *sess, aim_snacid_t id)
a25832e6 87{
d410cf58 88 aim_snac_t *cur, **prev;
89 int index;
90
91 index = id % FAIM_SNAC_HASH_SIZE;
92
93 faim_mutex_lock(&sess->snac_hash_locks[index]);
94 for (prev = (aim_snac_t **)&sess->snac_hash[index]; (cur = *prev); ) {
95 if (cur->id == id) {
96 *prev = cur->next;
97 return cur;
98 } else
99 prev = &cur->next;
100 }
101 faim_mutex_unlock(&sess->snac_hash_locks[index]);
102
103 return cur;
9de3ca7e 104}
105
106/*
107 * This is for cleaning up old SNACs that either don't get replies or
108 * a reply was never received for. Garabage collection. Plain and simple.
109 *
b13c9e13 110 * maxage is the _minimum_ age in seconds to keep SNACs.
9de3ca7e 111 *
112 */
d410cf58 113faim_internal void aim_cleansnacs(aim_session_t *sess, int maxage)
9de3ca7e 114{
d410cf58 115 int i;
b13c9e13 116
d410cf58 117 for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) {
118 aim_snac_t *cur, **prev;
119 time_t curtime;
53c935f8 120
d410cf58 121 faim_mutex_lock(&sess->snac_hash_locks[i]);
122 if (!sess->snac_hash[i]) {
123 faim_mutex_unlock(&sess->snac_hash_locks[i]);
124 continue;
125 }
96f8b1ed 126
d410cf58 127 curtime = time(NULL); /* done here in case we waited for the lock */
96f8b1ed 128
d410cf58 129 for (prev = (aim_snac_t **)&sess->snac_hash[i]; (cur = *prev); ) {
130 if ((curtime - cur->issuetime) > maxage) {
37ee990e 131
d410cf58 132 *prev = cur->next;
96f8b1ed 133
d410cf58 134 /* XXX should we have destructors here? */
135 free(cur->data);
136 free(cur);
96f8b1ed 137
d410cf58 138 } else
139 prev = &cur->next;
140 }
141 faim_mutex_unlock(&sess->snac_hash_locks[i]);
142 }
96f8b1ed 143
d410cf58 144 return;
9de3ca7e 145}
146
d410cf58 147faim_internal int aim_putsnac(aim_bstream_t *bs, fu16_t family, fu16_t subtype, fu16_t flags, aim_snacid_t snacid)
9de3ca7e 148{
d410cf58 149
150 aimbs_put16(bs, family);
151 aimbs_put16(bs, subtype);
152 aimbs_put16(bs, flags);
153 aimbs_put32(bs, snacid);
154
155 return 10;
9de3ca7e 156}
This page took 0.072138 seconds and 5 git commands to generate.