MCPcopy Create free account
hub / github.com/apache/cloudberry / pgtls_read

Function pgtls_read

src/interfaces/libpq/fe-secure-openssl.c:151–272  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

149}
150
151ssize_t
152pgtls_read(PGconn *conn, void *ptr, size_t len)
153{
154 ssize_t n;
155 int result_errno = 0;
156 char sebuf[PG_STRERROR_R_BUFLEN];
157 int err;
158 unsigned long ecode;
159
160rloop:
161
162 /*
163 * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
164 * queue. In general, the current thread's error queue must be empty
165 * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
166 * not work reliably. Since the possibility exists that other OpenSSL
167 * clients running in the same thread but not under our control will fail
168 * to call ERR_get_error() themselves (after their own I/O operations),
169 * pro-actively clear the per-thread error queue now.
170 */
171 SOCK_ERRNO_SET(0);
172 ERR_clear_error();
173 n = SSL_read(conn->ssl, ptr, len);
174 err = SSL_get_error(conn->ssl, n);
175
176 /*
177 * Other clients of OpenSSL may fail to call ERR_get_error(), but we
178 * always do, so as to not cause problems for OpenSSL clients that don't
179 * call ERR_clear_error() defensively. Be sure that this happens by
180 * calling now. SSL_get_error() relies on the OpenSSL per-thread error
181 * queue being intact, so this is the earliest possible point
182 * ERR_get_error() may be called.
183 */
184 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
185 switch (err)
186 {
187 case SSL_ERROR_NONE:
188 if (n < 0)
189 {
190 /* Not supposed to happen, so we don't translate the msg */
191 appendPQExpBufferStr(&conn->errorMessage,
192 "SSL_read failed but did not provide error information\n");
193 /* assume the connection is broken */
194 result_errno = ECONNRESET;
195 }
196 break;
197 case SSL_ERROR_WANT_READ:
198 n = 0;
199 break;
200 case SSL_ERROR_WANT_WRITE:
201
202 /*
203 * Returning 0 here would cause caller to wait for read-ready,
204 * which is not correct since what SSL wants is wait for
205 * write-ready. The former could get us stuck in an infinite
206 * wait, so don't risk it; busy-loop instead.
207 */
208 goto rloop;

Callers 1

pqsecure_readFunction · 0.85

Calls 5

appendPQExpBufferStrFunction · 0.85
libpq_gettextFunction · 0.85
appendPQExpBufferFunction · 0.85
SSLerrfreeFunction · 0.85
SSLerrmessageFunction · 0.70

Tested by

no test coverage detected