- Fix numerous tiny (but sometimes catastrophic) bugs dealing
with connection death (particularly with chat connections)
- *** Any connection with a -1 fd will get returned by aim_select
immediatly now... your code probably already handles this implicitly.
No release numbers
------------------
No release numbers
------------------
+ - Fri Dec 1 22:25:56 UTC 2000
+ - Fix numerous tiny (but sometimes catastrophic) bugs dealing
+ with connection death (particularly with chat connections)
+ - *** Any connection with a -1 fd will get returned by aim_select
+ immediatly now... your code probably already handles this implicitly.
+
- Wed Nov 29 17:31:23 UTC 2000
- Rewrote some of the msgcookie stuff
- Changed cachecookies to uncachecookies where it makes sense (arg!)
- Wed Nov 29 17:31:23 UTC 2000
- Rewrote some of the msgcookie stuff
- Changed cachecookies to uncachecookies where it makes sense (arg!)
for (cur = sess->connlist; cur; cur = cur->next) {
if (cur->type != AIM_CONN_TYPE_CHAT)
continue;
for (cur = sess->connlist; cur; cur = cur->next) {
if (cur->type != AIM_CONN_TYPE_CHAT)
continue;
+ if (!cur->priv) {
+ printf("faim: chat: chat connection with no name! (fd = %d)\n", cur->fd);
+ continue;
+ }
if (strcmp((char *)cur->priv, name) == 0)
break;
}
if (strcmp((char *)cur->priv, name) == 0)
break;
}
if (!conn || !roomname)
return -1;
if (!conn || !roomname)
return -1;
- conn->priv = malloc(strlen(roomname)+1);
- strcpy(conn->priv, roomname);
+ if (conn->priv)
+ free(conn->priv);
+
+ conn->priv = strdup(roomname);
struct aim_conn_t *conn;
if ((conn = aim_chat_getconn(sess, name)))
struct aim_conn_t *conn;
if ((conn = aim_chat_getconn(sess, name)))
- aim_conn_kill(sess, &conn);
int i,curbyte=0;
if (!sess || !conn || !sn || !msg || !roomname)
int i,curbyte=0;
if (!sess || !conn || !sn || !msg || !roomname)
+ return -1;
+
+ if (conn->type != AIM_CONN_TYPE_BOS)
+ return -1;
if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152+strlen(sn)+strlen(roomname)+strlen(msg))))
return -1;
if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152+strlen(sn)+strlen(roomname)+strlen(msg))))
return -1;
+/**
+ * aim_conn_init - Reset a connection to default values.
+ * @deadconn: Connection to be reset
+ *
+ * Initializes and/or resets a connection structure.
+ *
+ */
+static void aim_conn_init(struct aim_conn_t *deadconn)
+{
+ if (!deadconn)
+ return;
+
+ deadconn->fd = -1;
+ deadconn->subtype = -1;
+ deadconn->type = -1;
+ deadconn->seqnum = 0;
+ deadconn->lastactivity = 0;
+ deadconn->forcedlatency = 0;
+ deadconn->handlerlist = NULL;
+ deadconn->priv = NULL;
+ faim_mutex_init(&deadconn->active);
+ faim_mutex_init(&deadconn->seqnum_lock);
+
+ return;
+}
+
/**
* aim_conn_getnext - Gets a new connection structure.
* @sess: Session
/**
* aim_conn_getnext - Gets a new connection structure.
* @sess: Session
return NULL;
memset(newconn, 0, sizeof(struct aim_conn_t));
return NULL;
memset(newconn, 0, sizeof(struct aim_conn_t));
- aim_conn_close(newconn);
+ aim_conn_init(newconn);
newconn->next = NULL;
faim_mutex_lock(&sess->connlistlock);
newconn->next = NULL;
faim_mutex_lock(&sess->connlistlock);
-/**
- * aim_conn_init - Reset a connection to default values.
- * @deadconn: Connection to be reset
- *
- * Initializes and/or resets a connection structure.
- *
- */
-static void aim_conn_init(struct aim_conn_t *deadconn)
-{
- if (!deadconn)
- return;
-
- deadconn->fd = -1;
- deadconn->subtype = -1;
- deadconn->type = -1;
- deadconn->seqnum = 0;
- deadconn->lastactivity = 0;
- deadconn->forcedlatency = 0;
- deadconn->handlerlist = NULL;
- deadconn->priv = NULL;
- faim_mutex_init(&deadconn->active);
- faim_mutex_init(&deadconn->seqnum_lock);
-
- return;
-}
-
/**
* aim_conn_kill - Close and free a connection.
* @sess: Session for the connection
/**
* aim_conn_kill - Close and free a connection.
* @sess: Session for the connection
/* XXX: do we need this for txqueue too? */
aim_rxqueue_cleanbyconn(sess, *deadconn);
/* XXX: do we need this for txqueue too? */
aim_rxqueue_cleanbyconn(sess, *deadconn);
- aim_conn_close(*deadconn);
+ if ((*deadconn)->fd != -1)
+ aim_conn_close(*deadconn);
if ((*deadconn)->priv)
free((*deadconn)->priv);
free(*deadconn);
if ((*deadconn)->priv)
free((*deadconn)->priv);
free(*deadconn);
*
* Close (but not free) a connection.
*
*
* Close (but not free) a connection.
*
+ * This leaves everything untouched except for clearing the
+ * handler list and setting the fd to -1 (used to recognize
+ * dead connections).
+ *
*/
faim_export void aim_conn_close(struct aim_conn_t *deadconn)
{
*/
faim_export void aim_conn_close(struct aim_conn_t *deadconn)
{
- int typesav = -1, subtypesav = -1;
- void *privsav = NULL;
faim_mutex_destroy(&deadconn->active);
faim_mutex_destroy(&deadconn->seqnum_lock);
if (deadconn->fd >= 3)
close(deadconn->fd);
faim_mutex_destroy(&deadconn->active);
faim_mutex_destroy(&deadconn->seqnum_lock);
if (deadconn->fd >= 3)
close(deadconn->fd);
if (deadconn->handlerlist)
aim_clearhandlers(deadconn);
if (deadconn->handlerlist)
aim_clearhandlers(deadconn);
- typesav = deadconn->type;
- subtypesav = deadconn->subtype;
-
- if (deadconn->priv && (deadconn->type != AIM_CONN_TYPE_RENDEZVOUS)) {
- free(deadconn->priv);
- deadconn->priv = NULL;
- }
- privsav = deadconn->priv;
-
- aim_conn_init(deadconn);
-
- deadconn->type = typesav;
- deadconn->subtype = subtypesav;
- deadconn->priv = privsav;
-
faim_mutex_lock(&sess->connlistlock);
for (cur = sess->connlist; cur; cur = cur->next) {
faim_mutex_lock(&sess->connlistlock);
for (cur = sess->connlist; cur; cur = cur->next) {
- if (cur->status & AIM_CONN_STATUS_INPROGRESS) {
+ if (cur->fd == -1) {
+ /* don't let invalid/dead connections sit around */
+ *status = 2;
+ faim_mutex_unlock(&sess->connlistlock);
+ return cur;
+ } else if (cur->status & AIM_CONN_STATUS_INPROGRESS) {
FD_SET(cur->fd, &wfds);
haveconnecting++;
}
FD_SET(cur->fd, &wfds);
haveconnecting++;
}
if (!sess || !conn)
return 0;
if (!sess || !conn)
return 0;
+ if (conn->fd == -1)
+ return -1; /* its a aim_conn_close()'d connection */
+
if (conn->fd < 3) /* can happen when people abuse the interface */
return 0;
if (conn->fd < 3) /* can happen when people abuse the interface */
return 0;
if (send(cur->conn->fd, curPacket, buflen, 0) != buflen) {
faim_mutex_unlock(&cur->conn->active);
cur->sent = 1;
if (send(cur->conn->fd, curPacket, buflen, 0) != buflen) {
faim_mutex_unlock(&cur->conn->active);
cur->sent = 1;
- aim_conn_kill(sess, &cur->conn);
+ aim_conn_close(cur->conn);
return 0; /* bail out */
}
return 0; /* bail out */
}