From fb9c2a7f25a12040ecbbcc7a21fa75e6f7387d5c Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Thu, 5 Sep 2013 16:05:52 -0600 Subject: [PATCH] detect server close due to synchronous callbacks --- src/client.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/client.c b/src/client.c index d8bc5f2..5662f61 100644 --- a/src/client.c +++ b/src/client.c @@ -220,41 +220,42 @@ bool handle_auth_response(PgSocket *client, PktHdr *pkt) { uint32_t length; const char *username, *password; PgUser user; + PgSocket *server = client->link; switch(pkt->type) { case 'T': /* RowDescription */ if (!mbuf_get_uint16be(&pkt->data, &columns)) { - disconnect_server(client->link, false, "bad packet"); + disconnect_server(server, false, "bad packet"); return false; } if (columns != 2u) { - disconnect_server(client->link, false, "expected 1 column from login query, not %hu", columns); + disconnect_server(server, false, "expected 1 column from login query, not %hu", columns); return false; } break; case 'D': /* DataRow */ memset(&user, 0, sizeof(user)); if (!mbuf_get_uint16be(&pkt->data, &columns)) { - disconnect_server(client->link, false, "bad packet"); + disconnect_server(server, false, "bad packet"); return false; } if (columns != 2u) { - disconnect_server(client->link, false, "expected 1 column from login query, not %hu", columns); + disconnect_server(server, false, "expected 1 column from login query, not %hu", columns); return false; } if (!mbuf_get_uint32be(&pkt->data, &length)) { - disconnect_server(client->link, false, "bad packet"); + disconnect_server(server, false, "bad packet"); return false; } if (!mbuf_get_chars(&pkt->data, length, &username)) { - disconnect_server(client->link, false, "bad packet"); + disconnect_server(server, false, "bad packet"); return false; } if (sizeof(user.name) - 1 < length) length = sizeof(user.name) - 1; memcpy(user.name, username, length); if (!mbuf_get_uint32be(&pkt->data, &length)) { - disconnect_server(client->link, false, "bad packet"); + disconnect_server(server, false, "bad packet"); return false; } if (length == (uint32_t)-1) { @@ -264,7 +265,7 @@ bool handle_auth_response(PgSocket *client, PktHdr *pkt) { length = 3; } else { if (!mbuf_get_chars(&pkt->data, length, &password)) { - disconnect_server(client->link, false, "bad packet"); + disconnect_server(server, false, "bad packet"); return false; } } @@ -274,7 +275,7 @@ bool handle_auth_response(PgSocket *client, PktHdr *pkt) { client->auth_user = add_db_user(client->db, user.name, user.passwd); if (!client->auth_user) { - disconnect_server(client->link, false, "unable to allocate new user for auth"); + disconnect_server(server, false, "unable to allocate new user for auth"); return false; } break; @@ -291,12 +292,17 @@ bool handle_auth_response(PgSocket *client, PktHdr *pkt) { client->link->resetting = true; sbuf_continue(&client->sbuf); } + // either sbuf_continue or disconnect_client could disconnect the server + // way down in their bowels of other callbacks. so check that, and + // return appropriately (similar to reuse_on_release) + if (server->state == SV_FREE || server->state == SV_JUSTFREE) + return false; return true; default: - disconnect_server(client->link, false, "unexpected response from login query"); + disconnect_server(server, false, "unexpected response from login query"); return false; } - sbuf_prepare_skip(&client->link->sbuf, pkt->len); + sbuf_prepare_skip(&server->sbuf, pkt->len); return true; } -- 2.40.0