Read from socket directly for handshake data. Store the data in an MIOBuffer. Place the data in * the read BIO so the openssl library has access to it. If for some reason we must abort out of the * handshake, the stored data can be replayed (e.g. back out to blind tunneling) */
| 301 | * handshake, the stored data can be replayed (e.g. back out to blind tunneling) |
| 302 | */ |
| 303 | int64_t |
| 304 | SSLNetVConnection::read_raw_data() |
| 305 | { |
| 306 | // read data |
| 307 | int64_t r = 0; |
| 308 | int64_t total_read = 0; |
| 309 | int64_t rattempted = 0; |
| 310 | char *buffer = nullptr; |
| 311 | int buf_len; |
| 312 | IOBufferBlock *b = this->handShakeBuffer->first_write_block(); |
| 313 | |
| 314 | rattempted = b->write_avail(); |
| 315 | while (rattempted) { |
| 316 | buffer = b->_end; |
| 317 | buf_len = rattempted; |
| 318 | b = b->next.get(); |
| 319 | |
| 320 | r = this->con.sock.read(buffer, buf_len); |
| 321 | Metrics::Counter::increment(net_rsb.calls_to_read); |
| 322 | total_read += rattempted; |
| 323 | |
| 324 | Dbg(dbg_ctl_ssl, "read_raw_data r=%" PRId64 " rattempted=%" PRId64 " total_read=%" PRId64 " fd=%d", r, rattempted, total_read, |
| 325 | con.sock.get_fd()); |
| 326 | // last read failed or was incomplete |
| 327 | if (r != rattempted || !b) { |
| 328 | break; |
| 329 | } |
| 330 | |
| 331 | rattempted = b->write_avail(); |
| 332 | } |
| 333 | // If we have already moved some bytes successfully, adjust total_read to reflect reality |
| 334 | // If any read succeeded, we should return success |
| 335 | if (r != rattempted) { |
| 336 | // If the first read fails, we should return error |
| 337 | if (r <= 0 && total_read > rattempted) { |
| 338 | r = total_read - rattempted; |
| 339 | } else { |
| 340 | r = total_read - rattempted + r; |
| 341 | } |
| 342 | } |
| 343 | Metrics::Counter::increment(net_rsb.read_bytes, r); |
| 344 | Metrics::Counter::increment(net_rsb.read_bytes_count); |
| 345 | |
| 346 | if (!this->haveCheckedProxyProtocol) { |
| 347 | // The PROXY Protocol, by spec, is designed to require only the first TCP packet of bytes |
| 348 | // because it is under typical MTU. So we only need to perform the following inspection on the |
| 349 | // first packet. |
| 350 | this->haveCheckedProxyProtocol = true; |
| 351 | swoc::IPRangeSet *pp_ipmap; |
| 352 | pp_ipmap = SSLConfigParams::proxy_protocol_ip_addrs; |
| 353 | |
| 354 | if (this->get_is_proxy_protocol() && this->get_proxy_protocol_version() == ProxyProtocolVersion::UNDEFINED) { |
| 355 | Dbg(dbg_ctl_proxyprotocol, "proxy protocol is enabled on this port"); |
| 356 | if (pp_ipmap->count() > 0) { |
| 357 | Dbg(dbg_ctl_proxyprotocol, "proxy protocol has a configured allowlist of trusted IPs - checking"); |
| 358 | |
| 359 | // Using get_remote_addr() will return the ip of the |
| 360 | // proxy source IP, not the Proxy Protocol client ip. |
no test coverage detected