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

View File

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

View File

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

View File

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

View File

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

View File

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