diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-06-18 17:52:04 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-06-18 17:52:04 +0800 |
commit | 84e77804f1b96b59cb3c23a6d4e2c80361ee6135 (patch) | |
tree | fcc380d76c019d88ee82429b8c69a7117a950a85 | |
parent | d016dfb31f873b44fe4e89658de19920d8a9543d (diff) | |
download | pttbbs-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.c | 33 |
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); } |