mirror of
https://github.com/postgres/postgres.git
synced 2025-10-29 22:49:41 +03:00
Restructure libpq's handling of send failures.
Originally, if libpq got a failure (e.g., ECONNRESET) while trying to send data to the server, it would just report that and wash its hands of the matter. It was soon found that that wasn't a very pleasant way of coping with server-initiated disconnections, so we introduced a hack (pqHandleSendFailure) in the code that sends queries to make it peek ahead for server error reports before reporting the send failure. It now emerges that related cases can occur during connection setup; in particular, as of TLS 1.3 it's unsafe to assume that SSL connection failures will be reported by SSL_connect rather than during our first send attempt. We could have fixed that in a hacky way by applying pqHandleSendFailure after a startup packet send failure, but (a) pqHandleSendFailure explicitly disclaims suitability for use in any state except query startup, and (b) the problem still potentially exists for other send attempts in libpq. Instead, let's fix this in a more general fashion by eliminating pqHandleSendFailure altogether, and instead arranging to postpone all reports of send failures in libpq until after we've made an attempt to read and process server messages. The send failure won't be reported at all if we find a server message or detect input EOF. (Note: this removes one of the reasons why libpq typically overwrites, rather than appending to, conn->errorMessage: pqHandleSendFailure needed that behavior so that the send failure report would be replaced if we got a server message or read failure report. Eventually I'd like to get rid of that overwrite behavior altogether, but today is not that day. For the moment, pqSendSome is assuming that its callees will overwrite not append to conn->errorMessage.) Possibly this change should get back-patched someday; but it needs testing first, so let's not consider that till after v12 beta. Discussion: https://postgr.es/m/CAEepm=2n6Nv+5tFfe8YnkUm1fXgvxR0Mm1FoD+QKG-vLNGLyKg@mail.gmail.com
This commit is contained in:
@@ -410,6 +410,8 @@ struct pg_conn
|
||||
bool password_needed; /* true if server demanded a password */
|
||||
bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */
|
||||
bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */
|
||||
bool write_failed; /* have we had a write failure on sock? */
|
||||
char *write_err_msg; /* write error message, or NULL if OOM */
|
||||
|
||||
/* Transient state needed while establishing connection */
|
||||
bool try_next_addr; /* time to advance to next address/host? */
|
||||
@@ -585,7 +587,6 @@ extern void pqSaveMessageField(PGresult *res, char code,
|
||||
extern void pqSaveParameterStatus(PGconn *conn, const char *name,
|
||||
const char *value);
|
||||
extern int pqRowProcessor(PGconn *conn, const char **errmsgp);
|
||||
extern void pqHandleSendFailure(PGconn *conn);
|
||||
|
||||
/* === in fe-protocol2.c === */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user