From 6b5c8ffd9e1e9b988d0a28422df0955ebf1085c8 Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Fri, 11 Jan 2008 14:18:44 +0000 Subject: [PATCH] if cannot login to target db at all, notify clients (by killing them) --- include/proto.h | 1 + src/proto.c | 12 +++++++++++- src/server.c | 24 +++++++++++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/proto.h b/include/proto.h index 053ca3e..72133b6 100644 --- a/include/proto.h +++ b/include/proto.h @@ -36,6 +36,7 @@ bool get_header(MBuf *data, PktHdr *pkt) _MUSTCHECK; bool send_pooler_error(PgSocket *client, bool send_ready, const char *msg) /*_MUSTCHECK*/; void log_server_error(const char *note, PktHdr *pkt); +void parse_server_error(PktHdr *pkt, const char **level_p, const char **msg_p); void add_welcome_parameter(PgPool *pool, const char *key, const char *val); void finish_welcome_msg(PgSocket *server); diff --git a/src/proto.c b/src/proto.c index 6471726..2a43fca 100644 --- a/src/proto.c +++ b/src/proto.c @@ -117,7 +117,7 @@ bool send_pooler_error(PgSocket *client, bool send_ready, const char *msg) /* * Parse server error message and log it. */ -void log_server_error(const char *note, PktHdr *pkt) +void parse_server_error(PktHdr *pkt, const char **level_p, const char **msg_p) { const char *level = NULL, *msg = NULL, *val; int type; @@ -133,6 +133,16 @@ void log_server_error(const char *note, PktHdr *pkt) else if (type == 'M') msg = val; } + *level_p = level; + *msg_p = msg; +} + +void log_server_error(const char *note, PktHdr *pkt) +{ + const char *level = NULL, *msg = NULL; + + parse_server_error(pkt, &level, &msg); + if (!msg || !level) log_error("%s: corrupt error message", note); else diff --git a/src/server.c b/src/server.c index a7f6df2..4aab0b3 100644 --- a/src/server.c +++ b/src/server.c @@ -55,6 +55,24 @@ static bool load_parameter(PgSocket *server, PktHdr *pkt, bool startup) return true; } +/* we cannot log in at all, notify clients */ +static void kill_pool_logins(PgPool *pool, PktHdr *errpkt) +{ + List *item, *tmp; + PgSocket *client; + const char *level, *msg; + + parse_server_error(errpkt, &level, &msg); + + statlist_for_each_safe(item, &pool->waiting_client_list, tmp) { + client = container_of(item, PgSocket, head); + if (!client->wait_for_welcome) + continue; + + disconnect_client(client, true, msg); + } +} + /* process packets on server auth phase */ static bool handle_server_startup(PgSocket *server, PktHdr *pkt) { @@ -74,7 +92,11 @@ static bool handle_server_startup(PgSocket *server, PktHdr *pkt) break; case 'E': /* ErrorResponse */ - log_server_error("S: login failed", pkt); + if (!server->pool->welcome_msg_ready) + kill_pool_logins(server->pool, pkt); + else + log_server_error("S: login failed", pkt); + disconnect_server(server, true, "login failed"); break; -- 2.40.0