summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-06-18 17:52:04 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-06-18 17:52:04 +0800
commit84e77804f1b96b59cb3c23a6d4e2c80361ee6135 (patch)
treefcc380d76c019d88ee82429b8c69a7117a950a85
parentd016dfb31f873b44fe4e89658de19920d8a9543d (diff)
downloadpttbbs-84e77804f1b96b59cb3c23a6d4e2c80361ee6135.tar
pttbbs-84e77804f1b96b59cb3c23a6d4e2c80361ee6135.tar.gz
pttbbs-84e77804f1b96b59cb3c23a6d4e2c80361ee6135.tar.bz2
pttbbs-84e77804f1b96b59cb3c23a6d4e2c80361ee6135.tar.lz
pttbbs-84e77804f1b96b59cb3c23a6d4e2c80361ee6135.tar.xz
pttbbs-84e77804f1b96b59cb3c23a6d4e2c80361ee6135.tar.zst
pttbbs-84e77804f1b96b59cb3c23a6d4e2c80361ee6135.zip
* fix: if connection was closed before being acked, the ack should be abandoned directly.
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4658 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--daemon/logind/logind.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/daemon/logind/logind.c b/daemon/logind/logind.c
index 4e8149ef..e2e66db5 100644
--- a/daemon/logind/logind.c
+++ b/daemon/logind/logind.c
@@ -391,7 +391,9 @@ ackq_del(login_conn_ctx *conn)
{
size_t i;
- assert(conn && conn->cb == sizeof(login_conn_ctx));
+ // XXX in current implementation, the conn pointer may be
+ // destroyed before getting acks, so don't check its validness.
+ // assert(conn && conn->cb == sizeof(login_conn_ctx));
for (i = 0; i < g_ack_queue.size; i++)
{
if (g_ack_queue.queue[i] != conn)
@@ -1465,24 +1467,29 @@ ack_cb(int tunnel, short event, void *arg)
return;
}
- if (conn->cb != sizeof(login_conn_ctx))
+ // some connections may be removed (for example, socket close) before being acked.
+ // XXX FIXME if someone created a new connection before ack comes and re-used
+ // the memory location of previous destroyed one, we'd have problem here.
+ if (!ackq_del(conn))
{
- fprintf(stderr, LOG_PREFIX "warning: tunnel returned invalid ack. abort?\r\n");
- // assert(conn && conn->cb == sizeof(login_conn_ctx));
+ if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX
+ "drop abandoned ack connection: %p.\r\n", conn);
return;
}
- // XXX success connection.
- if (ackq_del(conn))
+ // check connection
+ if (conn->cb != sizeof(login_conn_ctx))
{
- // reset the state to prevent processing ackq again
- conn->ctx.state = LOGIN_STATE_AUTH;
- // this event is still in queue.
- login_conn_remove(conn, conn->telnet.fd, 0);
- } else {
- if (g_verbose > VERBOSE_ERROR) fprintf(stderr, LOG_PREFIX
- "got invalid ack connection: %p.\r\n", conn);
+ fprintf(stderr, LOG_PREFIX
+ "warning: received invalid ack from tunnel. abort/reset tunnel?\r\n");
+ // assert(conn && conn->cb == sizeof(login_conn_ctx));
+ return;
}
+
+ // reset the state to prevent processing ackq again
+ conn->ctx.state = LOGIN_STATE_AUTH;
+ // this event is still in queue.
+ login_conn_remove(conn, conn->telnet.fd, 0);
}