# HG changeset patch # User Eric Warmenhoven # Date 966558113 0 # Node ID 58106806ac2b02d6d2c72dc92cc8fa60916f6bc5 # Parent d7557252bfb11c049332fc829b001d7c4c898e44 [gaim-migrate @ 725] yay committer: Tailor Script diff -r d7557252bfb1 -r 58106806ac2b libfaim/CHANGES --- a/libfaim/CHANGES Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/CHANGES Fri Aug 18 00:21:53 2000 +0000 @@ -1,6 +1,19 @@ No release numbers ------------------ + - Thu Aug 17 23:19:40 UTC 2000 + - A few more leak fixes (only a few left to go...) + + - Thu Aug 17 23:08:08 UTC 2000 + - More leak fixes (eric, eric, eric...) + + - Thu Aug 17 22:53:03 UTC 2000 + - Change the SNAC cache to a hash instead of list + - Fixed a few leaks relating to aim_gettlv_str() + + - Thu Aug 17 14:04:18 UTC 2000 + - Fix the fd closing bug introduced last week + - Tue Aug 8 04:25:35 UTC 2000 - Preserve subtype and priv after aim_conn_close diff -r d7557252bfb1 -r 58106806ac2b libfaim/CHANGES.gaim --- a/libfaim/CHANGES.gaim Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/CHANGES.gaim Fri Aug 18 00:21:53 2000 +0000 @@ -1,3 +1,6 @@ + +Fri Aug 18 00:21:11 UTC 2000 EWarmenhoven + - Adam got rid of a lot of leaks thanks to me :) Thu Aug 17 07:56:49 UTC 2000 EWarmenhoven - The permit/deny stuff is warped. It's untested and just doesn't diff -r d7557252bfb1 -r 58106806ac2b libfaim/README.gaim --- a/libfaim/README.gaim Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/README.gaim Fri Aug 18 00:21:53 2000 +0000 @@ -13,7 +13,6 @@ included with the libfaim source on sourceforge) with the Gaim GTK front-end. So far the changes to libfaim that I've made are: - remove mkbuildinfo.sh and put the #defines it creates into Makefile.am -- fix a typo in aim.h - "aim_directim_initiate", not "aim_directim_intiate" - add #if HAVE_GETADDRINFO in aim_ft.c for Solaris people And finally, a word of warning. Gaim/Faim is VERY buggy. Please, don't use this diff -r d7557252bfb1 -r 58106806ac2b libfaim/aim_buddylist.c --- a/libfaim/aim_buddylist.c Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/aim_buddylist.c Fri Aug 18 00:21:53 2000 +0000 @@ -28,6 +28,7 @@ aim_tx_enqueue(sess, newpacket ); +#if 0 /* do we really need this code? */ { struct aim_snac_t snac; @@ -41,6 +42,7 @@ aim_newsnac(sess, &snac); } +#endif return( sess->snac_nextid++ ); } diff -r d7557252bfb1 -r 58106806ac2b libfaim/aim_chatnav.c --- a/libfaim/aim_chatnav.c Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/aim_chatnav.c Fri Aug 18 00:21:53 2000 +0000 @@ -68,6 +68,7 @@ struct aim_snac_t *snac; u_long snacid; rxcallback_t userfunc; + int ret=1; snacid = aimutil_get32(command->data+6); snac = aim_remsnac(sess, snacid); @@ -96,7 +97,6 @@ int curexchange = 0; struct aim_tlv_t *exchangetlv; u_char maxrooms = 0; - int ret = 1; struct aim_tlvlist_t *innerlist; tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10); @@ -215,7 +215,8 @@ exchanges[curexchange-1].lang2 = aim_gettlv_str(innerlist, 0x00d9, 1); else exchanges[curexchange-1].lang2 = NULL; - + + aim_freetlvchain(&innerlist); } /* @@ -245,33 +246,38 @@ curexchange--; } free(exchanges); - aim_freetlvchain(&innerlist); aim_freetlvchain(&tlvlist); - return ret; + + break; } case 0x0003: /* request exchange info */ printf("faim: chatnav_parse_info: resposne to exchange info\n"); - return 1; + break; case 0x0004: /* request room info */ printf("faim: chatnav_parse_info: response to room info\n"); - return 1; + break; case 0x0005: /* request more room info */ printf("faim: chatnav_parse_info: response to more room info\n"); - return 1; + break; case 0x0006: /* request occupant list */ printf("faim: chatnav_parse_info: response to occupant info\n"); - return 1; + break; case 0x0007: /* search for a room */ printf("faim: chatnav_parse_info: search results\n"); - return 1; + break; case 0x0008: /* create room */ printf("faim: chatnav_parse_info: response to create room\n"); - return 1; + break; default: /* unknown */ printf("faim: chatnav_parse_info: unknown request subtype (%04x)\n", snac->type); } - return 1; /* shouldn't get here */ + if (snac && snac->data) + free(snac->data); + if (snac) + free(snac); + + return ret; } u_long aim_chatnav_createroom(struct aim_session_t *sess, diff -r d7557252bfb1 -r 58106806ac2b libfaim/aim_conn.c --- a/libfaim/aim_conn.c Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/aim_conn.c Fri Aug 18 00:21:53 2000 +0000 @@ -13,7 +13,7 @@ */ void aim_connrst(struct aim_session_t *sess) { - faim_mutex_init(&sess->connlistlock, NULL); + faim_mutex_init(&sess->connlistlock); if (sess->connlist) { struct aim_conn_t *cur = sess->connlist, *tmp; @@ -68,8 +68,8 @@ deadconn->forcedlatency = 0; deadconn->handlerlist = NULL; deadconn->priv = NULL; - faim_mutex_init(&deadconn->active, NULL); - faim_mutex_init(&deadconn->seqnum_lock, NULL); + faim_mutex_init(&deadconn->active); + faim_mutex_init(&deadconn->seqnum_lock); return; } @@ -373,7 +373,7 @@ sess->queue_outgoing = NULL; sess->queue_incoming = NULL; sess->pendingjoin = NULL; - sess->outstanding_snacs = NULL; + aim_initsnachash(sess); sess->snac_nextid = 0x00000001; /* diff -r d7557252bfb1 -r 58106806ac2b libfaim/aim_login.c --- a/libfaim/aim_login.c Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/aim_login.c Fri Aug 18 00:21:53 2000 +0000 @@ -253,9 +253,9 @@ * No matter what, we should have a screen name. */ sn = aim_gettlv_str(tlvlist, 0x0001, 1); - memcpy(sess->logininfo.screen_name, sn, strlen(sn)); - sn[(strlen(sn))] = '\0'; - + strncpy(sess->logininfo.screen_name, sn, strlen(sn)); + free(sn); + /* * Check for an error code. If so, we should also * have an error url. @@ -311,10 +311,18 @@ aim_freetlvchain(&tlvlist); - /* These have been clobbered by the freetlvchain */ - sess->logininfo.BOSIP = NULL; - sess->logininfo.email = NULL; - sess->logininfo.errorurl = NULL; + if (sess->logininfo.BOSIP) { + free(sess->logininfo.BOSIP); + sess->logininfo.BOSIP = NULL; + } + if (sess->logininfo.email) { + free(sess->logininfo.email); + sess->logininfo.email = NULL; + } + if (sess->logininfo.errorurl) { + free(sess->logininfo.errorurl); + sess->logininfo.errorurl = NULL; + } return ret; } diff -r d7557252bfb1 -r 58106806ac2b libfaim/aim_rxhandlers.c --- a/libfaim/aim_rxhandlers.c Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/aim_rxhandlers.c Fri Aug 18 00:21:53 2000 +0000 @@ -639,7 +639,6 @@ int aim_parse_ratechange_middle(struct aim_session_t *sess, struct command_rx_struct *command) { rxcallback_t userfunc = NULL; - int i = 10; /* skip SNAC */ int ret = 1; unsigned long newrate; @@ -673,18 +672,22 @@ /* * TLVs follow */ - tlvlist = aim_readtlvchain(command->data+12, command->commandlen-12); - - msg = aim_gettlv_str(tlvlist, 0x000b, 1); + if (!(tlvlist = aim_readtlvchain(command->data+12, command->commandlen-12))) + return ret; + + if (!(msg = aim_gettlv_str(tlvlist, 0x000b, 1))) { + aim_freetlvchain(&tlvlist); + return ret; + } userfunc = aim_callhandler(command->conn, 0x0001, 0x0013); if (userfunc) ret = userfunc(sess, command, id, msg); aim_freetlvchain(&tlvlist); + free(msg); - return ret; - + return ret; } int aim_handleredirect_middle(struct aim_session_t *sess, @@ -715,6 +718,7 @@ if (!(ip = aim_gettlv_str(tlvlist, 0x0005, 1))) { printf("libfaim: major bug: no IP in tlvchain from redirect (service 0x%02x)\n", serviceid); + free(ip); aim_freetlvchain(&tlvlist); return ret; } @@ -722,6 +726,7 @@ if (!(tmptlv = aim_gettlv(tlvlist, 0x0006, 1))) { printf("libfaim: major bug: no cookie in tlvchain from redirect (service 0x%02x)\n", serviceid); + free(ip); aim_freetlvchain(&tlvlist); return ret; } @@ -746,9 +751,7 @@ ret = userfunc(sess, command, serviceid, ip, cookie); } - /* - * XXX: Is there a leak here? Where does IP get freed? - */ + free(ip); aim_freetlvchain(&tlvlist); return ret; diff -r d7557252bfb1 -r 58106806ac2b libfaim/aim_snac.c --- a/libfaim/aim_snac.c Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/aim_snac.c Fri Aug 18 00:21:53 2000 +0000 @@ -5,76 +5,112 @@ * * outstanding_snacs is a list of aim_snac_t structs. A SNAC should be added * whenever a new SNAC is sent and it should remain in the list until the - * response for it has been receieved. + * response for it has been receieved. * - * First edition badly written by Adam Fritzler (afritz@delphid.ml.org) - * Current edition nicely rewritten (it even works) by n (n@ml.org) + * cleansnacs() should be called periodically by the client in order + * to facilitate the aging out of unreplied-to SNACs. This can and does + * happen, so it should be handled. * */ #include +/* + * Called from aim_session_init() to initialize the hash. + */ +void aim_initsnachash(struct aim_session_t *sess) +{ + int i; + + for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) { + sess->snac_hash[i] = NULL; + faim_mutex_init(&sess->snac_hash_locks[i]); + } + + return; +} + +/* + * 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) { struct aim_snac_t *snac = NULL, *cur = NULL; - + int index; + if (!newsnac) return 0; - cur = sess->outstanding_snacs; - snac = calloc(1, sizeof(struct aim_snac_t)); if (!snac) return 0; memcpy(snac, newsnac, sizeof(struct aim_snac_t)); snac->issuetime = time(&snac->issuetime); snac->next = NULL; - - if (cur == NULL) { - sess->outstanding_snacs = snac; - return(snac->id); + + 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; } - while (cur->next != NULL) - cur = cur->next; - cur->next = snac; + faim_mutex_unlock(&sess->snac_hash_locks[index]); return(snac->id); } +/* + * Finds a snac structure with the passed SNAC ID, + * removes it from the list/hash, and returns a pointer to it. + * + * The returned structure must be freed by the caller. + * + */ struct aim_snac_t *aim_remsnac(struct aim_session_t *sess, u_long id) { struct aim_snac_t *cur; + int index; - cur = sess->outstanding_snacs; + index = id % FAIM_SNAC_HASH_SIZE; - if (cur == NULL) - return(NULL); - - if (cur->id == id) { - sess->outstanding_snacs = cur->next; - return(cur); + 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 { + cur = sess->snac_hash[index]; + while (cur->next) { + if (cur->next->id == id) { + struct aim_snac_t *tmp; + + tmp = cur->next; + cur->next = cur->next->next; + cur = tmp; + break; + } + cur = cur->next; + } } - while (cur->next != NULL) { - if (cur->next->id == id) { - struct aim_snac_t *tmp = NULL; - - tmp = cur->next; - cur->next = cur->next->next; - return(tmp); - } - cur = cur->next; - } - return(NULL); + faim_mutex_unlock(&sess->snac_hash_locks[index]); + + return cur; } /* * This is for cleaning up old SNACs that either don't get replies or * a reply was never received for. Garabage collection. Plain and simple. * - * maxage is the _minimum_ age in seconds to keep SNACs (though I don't know - * why its called _max_age). + * maxage is the _minimum_ age in seconds to keep SNACs. * */ int aim_cleansnacs(struct aim_session_t *sess, @@ -83,29 +119,36 @@ struct aim_snac_t *cur; struct aim_snac_t *remed = NULL; time_t curtime; - - cur = sess->outstanding_snacs; - - curtime = time(&curtime); - - while (cur) - { - if ( (cur) && (((cur->issuetime) + maxage) < curtime)) - { -#if DEBUG > 1 - printf("aimsnac: WARNING purged obsolete snac %08lx\n", cur->id); -#endif - remed = aim_remsnac(sess, cur->id); - if (remed) - { - if (remed->data) - free(remed->data); - free(remed); - } + int i; + + for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) { + 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; + cur = cur->next; + } } - + faim_mutex_unlock(&sess->snac_hash_locks[i]); + } + return 0; } diff -r d7557252bfb1 -r 58106806ac2b libfaim/faim/aim.h --- a/libfaim/faim/aim.h Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/faim/aim.h Fri Aug 18 00:21:53 2000 +0000 @@ -40,10 +40,10 @@ #ifdef FAIM_USEPTHREADS #include #define faim_mutex_t pthread_mutex_t -#define faim_mutex_init pthread_mutex_init -#define faim_mutex_lock pthread_mutex_lock -#define faim_mutex_unlock pthread_mutex_unlock -#define faim_mutex_destroy pthread_mutex_destroy +#define faim_mutex_init(x) pthread_mutex_init(x, NULL) +#define faim_mutex_lock(x) pthread_mutex_lock(x) +#define faim_mutex_unlock(x) pthread_mutex_unlock(x) +#define faim_mutex_destroy(x) pthread_mutex_destroy(x) #elif defined(FAIM_USEFAKELOCKS) /* * For platforms without pthreads, we also assume @@ -306,8 +306,9 @@ * Outstanding snac handling * * XXX: Should these be per-connection? -mid - **/ - struct aim_snac_t *outstanding_snacs; + */ + struct aim_snac_t *snac_hash[FAIM_SNAC_HASH_SIZE]; + faim_mutex_t snac_hash_locks[FAIM_SNAC_HASH_SIZE]; u_long snac_nextid; struct aim_msgcookie_t *msgcookies; @@ -457,6 +458,7 @@ time_t issuetime; struct aim_snac_t *next; }; +void aim_initsnachash(struct aim_session_t *sess); u_long aim_newsnac(struct aim_session_t *, struct aim_snac_t *newsnac); struct aim_snac_t *aim_remsnac(struct aim_session_t *, u_long id); int aim_cleansnacs(struct aim_session_t *, int maxage); @@ -510,6 +512,8 @@ int aim_parse_last_bad(struct aim_session_t *, struct command_rx_struct *, ...); int aim_parse_generalerrs(struct aim_session_t *, struct command_rx_struct *command, ...); int aim_parsemotd_middle(struct aim_session_t *sess, struct command_rx_struct *command, ...); +int aim_parse_ratechange_middle(struct aim_session_t *sess, struct command_rx_struct *command); +int aim_parse_msgack_middle(struct aim_session_t *sess, struct command_rx_struct *command); /* aim_im.c */ struct aim_directim_priv { diff -r d7557252bfb1 -r 58106806ac2b libfaim/faim/faimconfig.h --- a/libfaim/faim/faimconfig.h Thu Aug 17 23:23:24 2000 +0000 +++ b/libfaim/faim/faimconfig.h Fri Aug 18 00:21:53 2000 +0000 @@ -118,6 +118,14 @@ #define FAIM_USEFAKELOCKS #endif +/* + * Size of the SNAC caching hash. + * + * Default: 16 + * + */ +#define FAIM_SNAC_HASH_SIZE 16 + #endif /* __FAIMCONFIG_H__ */