mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-13 16:32:56 +00:00
Our rust-postgres fork is getting messy. Mostly because proxy wants more
control over the raw protocol than tokio-postgres provides. As such,
it's diverging more and more. Storage and compute also make use of
rust-postgres, but in more normal usage, thus they don't need our crazy
changes.
Idea:
* proxy maintains their subset
* other teams use a minimal patch set against upstream rust-postgres
Reviewing this code will be difficult. To implement it, I
1. Copied tokio-postgres, postgres-protocol and postgres-types from
00940fcdb5
2. Updated their package names with the `2` suffix to make them compile
in the workspace.
3. Updated proxy to use those packages
4. Copied in the code from tokio-postgres-rustls 0.13 (with some patches
applied https://github.com/jbg/tokio-postgres-rustls/pull/32
https://github.com/jbg/tokio-postgres-rustls/pull/33)
5. Removed as much dead code as I could find in the vendored libraries
6. Updated the tokio-postgres-rustls code to use our existing channel
binding implementation
66 lines
1.8 KiB
Rust
66 lines
1.8 KiB
Rust
use crate::config::Host;
|
|
use crate::Error;
|
|
use std::future::Future;
|
|
use std::io;
|
|
use std::time::Duration;
|
|
use tokio::net::{self, TcpStream};
|
|
use tokio::time;
|
|
|
|
pub(crate) async fn connect_socket(
|
|
host: &Host,
|
|
port: u16,
|
|
connect_timeout: Option<Duration>,
|
|
) -> Result<TcpStream, Error> {
|
|
match host {
|
|
Host::Tcp(host) => {
|
|
let addrs = net::lookup_host((&**host, port))
|
|
.await
|
|
.map_err(Error::connect)?;
|
|
|
|
let mut last_err = None;
|
|
|
|
for addr in addrs {
|
|
let stream =
|
|
match connect_with_timeout(TcpStream::connect(addr), connect_timeout).await {
|
|
Ok(stream) => stream,
|
|
Err(e) => {
|
|
last_err = Some(e);
|
|
continue;
|
|
}
|
|
};
|
|
|
|
stream.set_nodelay(true).map_err(Error::connect)?;
|
|
|
|
return Ok(stream);
|
|
}
|
|
|
|
Err(last_err.unwrap_or_else(|| {
|
|
Error::connect(io::Error::new(
|
|
io::ErrorKind::InvalidInput,
|
|
"could not resolve any addresses",
|
|
))
|
|
}))
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn connect_with_timeout<F, T>(connect: F, timeout: Option<Duration>) -> Result<T, Error>
|
|
where
|
|
F: Future<Output = io::Result<T>>,
|
|
{
|
|
match timeout {
|
|
Some(timeout) => match time::timeout(timeout, connect).await {
|
|
Ok(Ok(socket)) => Ok(socket),
|
|
Ok(Err(e)) => Err(Error::connect(e)),
|
|
Err(_) => Err(Error::connect(io::Error::new(
|
|
io::ErrorKind::TimedOut,
|
|
"connection timed out",
|
|
))),
|
|
},
|
|
None => match connect.await {
|
|
Ok(socket) => Ok(socket),
|
|
Err(e) => Err(Error::connect(e)),
|
|
},
|
|
}
|
|
}
|