odissey: send client errors

This commit is contained in:
Dmitry Simonenko 2017-06-08 15:36:21 +03:00
parent e87a00ba10
commit c35b7bec71
6 changed files with 48 additions and 7 deletions

View File

@ -91,6 +91,8 @@ od_auth_frontend_cleartext(od_client_t *client)
if (rc == -1) {
od_error_client(&instance->log, client->id, "auth",
"password read error");
od_frontend_error(client, SO_ERROR_PROTOCOL_VIOLATION,
"bad password message");
so_password_free(&client_token);
return -1;
}
@ -108,6 +110,8 @@ od_auth_frontend_cleartext(od_client_t *client)
od_log_client(&instance->log, client->id, "auth",
"user '%s' incorrect password",
client->startup.user);
od_frontend_error(client, SO_ERROR_INVALID_PASSWORD,
"incorrect password");
return -1;
}
return 0;
@ -162,6 +166,8 @@ od_auth_frontend_md5(od_client_t *client)
if (rc == -1) {
od_error_client(&instance->log, client->id, "auth",
"password read error");
od_frontend_error(client, SO_ERROR_PROTOCOL_VIOLATION,
"bad password message");
so_password_free(&client_token);
return -1;
}
@ -191,6 +197,8 @@ od_auth_frontend_md5(od_client_t *client)
od_log_client(&instance->log, client->id, "auth",
"user '%s' incorrect password",
client->startup.user);
od_frontend_error(client, SO_ERROR_INVALID_PASSWORD,
"incorrect password");
return -1;
}
return 0;
@ -211,6 +219,8 @@ int od_auth_frontend(od_client_t *client)
od_error_client(&instance->log, client->id, "auth"
"user '%s' not found",
so_parameter_value(client->startup.user));
od_frontend_error(client, SO_ERROR_INVALID_AUTHORIZATION_SPECIFICATION,
"unknown user");
return -1;
}
}
@ -221,6 +231,8 @@ int od_auth_frontend(od_client_t *client)
od_log_client(&instance->log, client->id, "auth",
"user '%s' access denied",
so_parameter_value(client->startup.user));
od_frontend_error(client, SO_ERROR_INVALID_AUTHORIZATION_SPECIFICATION,
"user access denied");
return -1;
}

View File

@ -95,7 +95,7 @@ od_frontend_startup_read(od_client_t *client)
break;
if (to_read == -1) {
od_error_client(&instance->log, client->id, "startup",
"bad startup packet");
"failed to read startup packet, closing");
return -1;
}
int rc = so_stream_ensure(stream, to_read);
@ -128,7 +128,7 @@ od_frontend_startup(od_client_t *client)
stream->s,
so_stream_used(stream));
if (rc == -1)
return -1;
goto error;
/* client ssl request */
rc = od_tls_frontend_accept(client, &instance->log,
@ -150,8 +150,15 @@ od_frontend_startup(od_client_t *client)
stream->s,
so_stream_used(stream));
if (rc == -1)
return -1;
goto error;
return 0;
error:
od_error_client(&instance->log, client->id, "startup",
"incorrect startup packet");
od_frontend_error(client, SO_ERROR_PROTOCOL_VIOLATION,
"bad startup packet");
return -1;
}
static inline void
@ -459,12 +466,23 @@ void od_frontend(void *arg)
case OD_RERROR:
od_error_client(&instance->log, client->id, NULL,
"routing failed, closing");
od_frontend_error(client, SO_ERROR_SYSTEM_ERROR,
"client routing failed");
od_frontend_close(client);
return;
case OD_RERROR_NOT_FOUND:
od_error_client(&instance->log, client->id, NULL,
"database route '%s' is not declared, closing",
so_parameter_value(client->startup.database));
od_frontend_error(client, SO_ERROR_UNDEFINED_DATABASE,
"database route is not declared");
od_frontend_close(client);
return;
case OD_RERROR_TIMEDOUT:
od_error_client(&instance->log, client->id, NULL,
"route connection timedout, closing");
od_frontend_error(client, SO_ERROR_TOO_MANY_CONNECTIONS,
"connection timedout");
od_frontend_close(client);
return;
case OD_RERROR_LIMIT:
@ -492,6 +510,8 @@ void od_frontend(void *arg)
case OD_RS_EATTACH:
assert(server == NULL);
assert(client->route != NULL);
od_frontend_error(client, SO_ERROR_CONNECTION_FAILURE,
"failed to get remote server connection");
/* detach client from route */
od_unroute(client);
break;
@ -536,7 +556,8 @@ void od_frontend(void *arg)
od_log_server(&instance->log, server->id, NULL,
"disconnected (server configure error): %s",
machine_error(server->io));
od_frontend_error(client, SO_ERROR_CONNECTION_FAILURE,
"failed to configure remote server");
/* close backend connection */
od_router_close_and_unroute(client);
break;
@ -547,7 +568,8 @@ void od_frontend(void *arg)
od_log_server(&instance->log, server->id, NULL,
"disconnected (read/write error): %s",
machine_error(server->io));
od_frontend_error(client, SO_ERROR_CONNECTION_FAILURE,
"remote server read/write error");
/* close backend connection */
od_router_close_and_unroute(client);
break;

View File

@ -7,6 +7,7 @@
* PostgreSQL connection pooler and request router.
*/
int od_frontend_error(od_client_t*, char*, char*, ...);
void od_frontend(void*);
#endif /* OD_FRONTEND_H */

View File

@ -157,7 +157,7 @@ od_router_attacher(void *arg)
if (rc < 0) {
od_debug_client(&instance->log, client->id, "router",
"server pool wait timedout, closing");
msg_attach->status = OD_RERROR;
msg_attach->status = OD_RERROR_TIMEDOUT;
machine_queue_put(msg_attach->response, msg);
return;
}

View File

@ -14,7 +14,8 @@ typedef enum
OD_ROK,
OD_RERROR,
OD_RERROR_NOT_FOUND,
OD_RERROR_LIMIT
OD_RERROR_LIMIT,
OD_RERROR_TIMEDOUT
} od_routerstatus_t;
struct od_router

View File

@ -43,6 +43,7 @@
#include "od_pooler.h"
#include "od_relay.h"
#include "od_tls.h"
#include "od_frontend.h"
machine_tls_t
od_tls_frontend(od_scheme_t *scheme)
@ -106,6 +107,8 @@ od_tls_frontend_accept(od_client_t *client,
return -1;
}
od_log_client(log, client->id, "tls", "disabled, closing");
od_frontend_error(client, SO_ERROR_FEATURE_NOT_SUPPORTED,
"SSL is not supported");
return -1;
}
/* supported 'S' */
@ -131,6 +134,8 @@ od_tls_frontend_accept(od_client_t *client,
break;
default:
od_log_client(log, client->id, "tls", "required, closing");
od_frontend_error(client, SO_ERROR_PROTOCOL_VIOLATION,
"SSL is required");
return -1;
}
return 0;