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);
/*
* 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;
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
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)
{
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;