| 149 | } |
| 150 | |
| 151 | ssize_t |
| 152 | pgtls_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 | |
| 160 | rloop: |
| 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; |
no test coverage detected