From 77658a155bea3d94b0a90ca937b331082d515dac Mon Sep 17 00:00:00 2001
From: Nikita Kalyanov <44959448+nikitakalyanov@users.noreply.github.com>
Date: Tue, 5 Sep 2023 12:45:46 +0300
Subject: [PATCH] support deploying in IPv6-only environments (#4135)
A set of changes to enable neon to work in IPv6 environments. The
changes are backward-compatible but allow to deploy neon even to
IPv6-only environments:
- bind to both IPv4 and IPv6 interfaces
- allow connections to Postgres from IPv6 interface
- parse the address from control plane that could also be IPv6
---
compute_tools/src/http/api.rs | 6 +++++-
compute_tools/src/params.rs | 2 +-
proxy/src/console/provider/neon.rs | 9 +++++----
3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/compute_tools/src/http/api.rs b/compute_tools/src/http/api.rs
index a571628770..8851be1ec1 100644
--- a/compute_tools/src/http/api.rs
+++ b/compute_tools/src/http/api.rs
@@ -1,4 +1,6 @@
use std::convert::Infallible;
+use std::net::IpAddr;
+use std::net::Ipv6Addr;
use std::net::SocketAddr;
use std::sync::Arc;
use std::thread;
@@ -298,7 +300,9 @@ fn render_json_error(e: &str, status: StatusCode) -> Response
{
// Main Hyper HTTP server function that runs it and blocks waiting on it forever.
#[tokio::main]
async fn serve(port: u16, state: Arc) {
- let addr = SocketAddr::from(([0, 0, 0, 0], port));
+ // this usually binds to both IPv4 and IPv6 on linux
+ // see e.g. https://github.com/rust-lang/rust/pull/34440
+ let addr = SocketAddr::new(IpAddr::from(Ipv6Addr::UNSPECIFIED), port);
let make_service = make_service_fn(move |_conn| {
let state = state.clone();
diff --git a/compute_tools/src/params.rs b/compute_tools/src/params.rs
index 0ce01ff478..4ccb403ca6 100644
--- a/compute_tools/src/params.rs
+++ b/compute_tools/src/params.rs
@@ -6,4 +6,4 @@ pub const DEFAULT_LOG_LEVEL: &str = "info";
// https://www.postgresql.org/docs/15/auth-password.html
//
// So it's safe to set md5 here, as `control-plane` anyway uses SCRAM for all roles.
-pub const PG_HBA_ALL_MD5: &str = "host\tall\t\tall\t\t0.0.0.0/0\t\tmd5";
+pub const PG_HBA_ALL_MD5: &str = "host\tall\t\tall\t\tall\t\tmd5";
diff --git a/proxy/src/console/provider/neon.rs b/proxy/src/console/provider/neon.rs
index 3322d5a5be..163cdfffc0 100644
--- a/proxy/src/console/provider/neon.rs
+++ b/proxy/src/console/provider/neon.rs
@@ -8,6 +8,7 @@ use super::{
use crate::{auth::ClientCredentials, compute, http, scram};
use async_trait::async_trait;
use futures::TryFutureExt;
+use std::net::SocketAddr;
use tokio::time::Instant;
use tokio_postgres::config::SslMode;
use tracing::{error, info, info_span, warn, Instrument};
@@ -117,7 +118,7 @@ impl Api {
// We'll set username and such later using the startup message.
// TODO: add more type safety (in progress).
let mut config = compute::ConnCfg::new();
- config.host(host).port(port).ssl_mode(SslMode::Disable); // TLS is not configured on compute nodes.
+ config.host(&host).port(port).ssl_mode(SslMode::Disable); // TLS is not configured on compute nodes.
let node = NodeInfo {
config,
@@ -194,9 +195,9 @@ async fn parse_body serde::Deserialize<'a>>(
Err(ApiError::Console { status, text })
}
-fn parse_host_port(input: &str) -> Option<(&str, u16)> {
- let (host, port) = input.split_once(':')?;
- Some((host, port.parse().ok()?))
+fn parse_host_port(input: &str) -> Option<(String, u16)> {
+ let parsed: SocketAddr = input.parse().ok()?;
+ Some((parsed.ip().to_string(), parsed.port()))
}
#[cfg(test)]