Content-Length: 376424 | pFad | http://github.com/postgres/postgres/commit/3f37400cfb87002e48ee98d6c0d34a597d0dddf8

2B Don't reduce output request size on non-Unix-socket connections. · postgres/postgres@3f37400 · GitHub
Skip to content

Commit 3f37400

Browse files
committed
Don't reduce output request size on non-Unix-socket connections.
Traditionally, libpq's pqPutMsgEnd has rounded down the amount-to-send to be a multiple of 8K when it is eagerly writing some data. This still seems like a good idea when sending through a Unix socket, as pipes typically have a buffer size of 8K or some fraction/multiple of that. But there's not much argument for it on a TCP connection, since (a) standard MTU values are not commensurate with that, and (b) the kernel typically applies its own packet splitting/merging logic. Worse, our SSL and GSSAPI code paths both have API stipulations that if they fail to send all the data that was offered in the previous write attempt, we mustn't offer less data in the next attempt; else we may get "SSL error: bad length" or "GSSAPI caller failed to retransmit all data needing to be retried". The previous write attempt might've been pqFlush attempting to send everything in the buffer, so pqPutMsgEnd can't safely write less than the full buffer contents. (Well, we could add some more state to track exactly how much the previous write attempt was, but there's little value evident in such extra complication.) Hence, apply the round-down only on AF_UNIX sockets, where we never use SSL or GSSAPI. Interestingly, we had a very closely related bug report before, which I attempted to fix in commit d053a87. But the test case we had then seemingly didn't trigger this pqFlush-then-pqPutMsgEnd scenario, or at least we failed to recognize this variant of the bug. Bug: #18907 Reported-by: Dorjpalam Batbaatar <htgn.dbat.95@gmail.com> Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/18907-d41b9bcf6f29edda@postgresql.org Backpatch-through: 13
1 parent 1694292 commit 3f37400

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

src/backend/libpq/be-secure-gssapi.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@ be_gssapi_write(Port *port, void *ptr, size_t len)
120120
* again, so if it offers a len less than that, something is wrong.
121121
*
122122
* Note: it may seem attractive to report partial write completion once
123-
* we've successfully sent any encrypted packets. However, that can cause
124-
* problems for callers; notably, pqPutMsgEnd's heuristic to send only
125-
* full 8K blocks interacts badly with such a hack. We won't save much,
123+
* we've successfully sent any encrypted packets. However, doing that
124+
* expands the state space of this processing and has been responsible for
125+
* bugs in the past (cf. commit d053a879b). We won't save much,
126126
* typically, by letting callers discard data early, so don't risk it.
127127
*/
128128
if (len < PqGSSSendConsumed)

src/interfaces/libpq/fe-misc.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,35 @@ pqPutMsgEnd(PGconn *conn)
539539
/* Make message eligible to send */
540540
conn->outCount = conn->outMsgEnd;
541541

542+
/* If appropriate, try to push out some data */
542543
if (conn->outCount >= 8192)
543544
{
544-
int toSend = conn->outCount - (conn->outCount % 8192);
545+
int toSend = conn->outCount;
546+
547+
/*
548+
* On Unix-pipe connections, it seems profitable to prefer sending
549+
* pipe-buffer-sized packets not randomly-sized ones, so retain the
550+
* last partial-8K chunk in our buffer for now. On TCP connections,
551+
* the advantage of that is far less clear. Moreover, it flat out
552+
* isn't safe when using SSL or GSSAPI, because those code paths have
553+
* API stipulations that if they fail to send all the data that was
554+
* offered in the previous write attempt, we mustn't offer less data
555+
* in this write attempt. The previous write attempt might've been
556+
* pqFlush attempting to send everything in the buffer, so we mustn't
557+
* offer less now. (Presently, we won't try to use SSL or GSSAPI on
558+
* Unix connections, so those checks are just Asserts. They'll have
559+
* to become part of the regular if-test if we ever change that.)
560+
*/
561+
if (conn->raddr.addr.ss_family == AF_UNIX)
562+
{
563+
#ifdef USE_SSL
564+
Assert(!conn->ssl_in_use);
565+
#endif
566+
#ifdef ENABLE_GSS
567+
Assert(!conn->gssenc);
568+
#endif
569+
toSend -= toSend % 8192;
570+
}
545571

546572
if (pqSendSome(conn, toSend) < 0)
547573
return EOF;

src/interfaces/libpq/fe-secure-gssapi.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
112112
* again, so if it offers a len less than that, something is wrong.
113113
*
114114
* Note: it may seem attractive to report partial write completion once
115-
* we've successfully sent any encrypted packets. However, that can cause
116-
* problems for callers; notably, pqPutMsgEnd's heuristic to send only
117-
* full 8K blocks interacts badly with such a hack. We won't save much,
115+
* we've successfully sent any encrypted packets. However, doing that
116+
* expands the state space of this processing and has been responsible for
117+
* bugs in the past (cf. commit d053a879b). We won't save much,
118118
* typically, by letting callers discard data early, so don't risk it.
119119
*/
120120
if (len < PqGSSSendConsumed)

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/postgres/postgres/commit/3f37400cfb87002e48ee98d6c0d34a597d0dddf8

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy