From 275a2ff8c8d384368462531ccc7fcfbea4f4d088 Mon Sep 17 00:00:00 2001 From: mid Date: Fri, 15 Dec 2000 10:13:21 +0000 Subject: [PATCH] - Fri Dec 15 02:04:12 UTC 2000 - Parse rate changes *properly* - Add sample code to faimtest demonstrating my approximations on how to fiddle with aim_conn_setlatency() in relation to the rate changes (properly wildly conservative). [I also copied this stuff into mfaim.] --- CHANGES | 7 ++++ aim_rxhandlers.c | 37 ++++++++++++++---- faim/aim.h | 6 +++ utils/faimtest/faimtest.c | 79 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 117 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 3f5aa87..d85c915 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,13 @@ No release numbers ------------------ + - Fri Dec 15 02:04:12 UTC 2000 + - Parse rate changes *properly* + - Add sample code to faimtest demonstrating my approximations + on how to fiddle with aim_conn_setlatency() in relation + to the rate changes (properly wildly conservative). [I also + copied this stuff into mfaim.] + - Thu Dec 14 03:39:34 UTC 2000 - Change the 0x01 to a 0x00 in auth request to make buddy lists work again - Rearrange bytes in setversions() to match winaim diff --git a/aim_rxhandlers.c b/aim_rxhandlers.c index 75167b8..55a00d5 100644 --- a/aim_rxhandlers.c +++ b/aim_rxhandlers.c @@ -574,6 +574,8 @@ faim_export int aim_rxdispatch(struct aim_session_t *sess) workingPtr->handled = aim_parse_hostonline(sess, workingPtr); else if (subtype == 0x0007) workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr); + else if (subtype == 0x000a) + workingPtr->handled = aim_parse_ratechange_middle(sess, workingPtr); else workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr); } else if (family == 0x000e) { @@ -657,17 +659,36 @@ faim_internal int aim_parse_ratechange_middle(struct aim_session_t *sess, struct { rxcallback_t userfunc = NULL; int ret = 1; - unsigned long newrate; + int i; + int code; + unsigned long parmid, windowsize, clear, alert, limit, disconnect; + unsigned long currentavg, maxavg; - if (command->commandlen != 0x2f) { - printf("faim: unknown rate change length 0x%04x\n", command->commandlen); - return 1; - } - - newrate = aimutil_get32(command->data+34); + i = 10; + + code = aimutil_get16(command->data+i); + i += 2; + + parmid = aimutil_get16(command->data+i); + i += 2; + + windowsize = aimutil_get32(command->data+i); + i += 4; + clear = aimutil_get32(command->data+i); + i += 4; + alert = aimutil_get32(command->data+i); + i += 4; + limit = aimutil_get32(command->data+i); + i += 4; + disconnect = aimutil_get32(command->data+i); + i += 4; + currentavg = aimutil_get32(command->data+i); + i += 4; + maxavg = aimutil_get32(command->data+i); + i += 4; if ((userfunc = aim_callhandler(command->conn, 0x0001, 0x000a))) - ret = userfunc(sess, command, newrate); + ret = userfunc(sess, command, code, parmid, windowsize, clear, alert, limit, disconnect, currentavg, maxavg); return ret; } diff --git a/faim/aim.h b/faim/aim.h index 3c83b91..a29c109 100644 --- a/faim/aim.h +++ b/faim/aim.h @@ -577,7 +577,13 @@ faim_internal int aim_parse_unknown(struct aim_session_t *, struct command_rx_st int aim_parse_last_bad(struct aim_session_t *, struct command_rx_struct *, ...); faim_internal int aim_parse_generalerrs(struct aim_session_t *, struct command_rx_struct *command, ...); faim_internal int aim_parsemotd_middle(struct aim_session_t *sess, struct command_rx_struct *command, ...); + +#define AIM_RATE_CODE_CHANGE 0x0001 +#define AIM_RATE_CODE_WARNING 0x0002 +#define AIM_RATE_CODE_LIMIT 0x0003 +#define AIM_RATE_CODE_CLEARLIMIT 0x0004 faim_internal int aim_parse_ratechange_middle(struct aim_session_t *sess, struct command_rx_struct *command); + faim_internal int aim_parse_evilnotify_middle(struct aim_session_t *sess, struct command_rx_struct *command); faim_internal int aim_parse_msgack_middle(struct aim_session_t *sess, struct command_rx_struct *command); diff --git a/utils/faimtest/faimtest.c b/utils/faimtest/faimtest.c index 9fffe47..5370a49 100644 --- a/utils/faimtest/faimtest.c +++ b/utils/faimtest/faimtest.c @@ -1604,14 +1604,85 @@ int faimtest_getfile_disconnect(struct aim_session_t *sess, struct command_rx_st int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...) { + static char *codes[5] = {"invalid", + "change", + "warning", + "limit", + "limit cleared"}; va_list ap; - unsigned long newrate; - + int code; + unsigned long parmid, windowsize, clear, alert, limit, disconnect; + unsigned long currentavg, maxavg; + va_start(ap, command); - newrate = va_arg(ap, unsigned long); + + /* See code explanations below */ + code = va_arg(ap, int); + + /* + * Known parameter ID's... + * 0x0003 BOS (normal ICBMs, userinfo requests, etc) + * 0x0005 Chat messages + */ + parmid = va_arg(ap, unsigned long); + + /* + * Not sure what this is exactly. I think its the temporal + * relation factor (ie, how to make the rest of the numbers + * make sense in the real world). + */ + windowsize = va_arg(ap, unsigned long); + + /* Explained below */ + clear = va_arg(ap, unsigned long); + alert = va_arg(ap, unsigned long); + limit = va_arg(ap, unsigned long); + disconnect = va_arg(ap, unsigned long); + currentavg = va_arg(ap, unsigned long); + maxavg = va_arg(ap, unsigned long); + va_end(ap); - printf("faimtest: ratechange: %lu\n", newrate); + + printf("faimtest: rate %s (paramid 0x%04lx): curavg = %ld, maxavg = %ld, alert at %ld, clear warning at %ld, limit at %ld, disconnect at %ld (window size = %ld)\n", + (code < 5)?codes[code]:"invalid", + parmid, + currentavg, maxavg, + alert, clear, + limit, disconnect, + windowsize); + + if (code == AIM_RATE_CODE_CHANGE) { + /* + * Not real sure when these get sent. + */ + if (currentavg >= clear) + aim_conn_setlatency(command->conn, 0); + + } else if (code == AIM_RATE_CODE_WARNING) { + /* + * We start getting WARNINGs the first time we go below the 'alert' + * limit (currentavg < alert) and they stop when either we pause + * long enough for currentavg to go above 'clear', or until we + * flood it bad enough to go below 'limit' (and start getting + * LIMITs instead) or even further and go below 'disconnect' and + * get disconnected completely (and won't be able to login right + * away either). + */ + aim_conn_setlatency(command->conn, windowsize/4); /* XXX this is bogus! */ + + } else if (code == AIM_RATE_CODE_LIMIT) { + /* + * When we hit LIMIT, messages will start getting dropped. + */ + aim_conn_setlatency(command->conn, windowsize/2); /* XXX this is bogus! */ + + } else if (code == AIM_RATE_CODE_CLEARLIMIT) { + /* + * The limit is cleared when curavg goes above 'clear'. + */ + aim_conn_setlatency(command->conn, 0); + } return 1; } -- 2.45.1