Re: [Proposal] add portaddr like hostaddr

From: Diego <mrstephenamell(at)gmail(dot)com>
To: Denis Smirnov <darthunix(at)gmail(dot)com>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: [Proposal] add portaddr like hostaddr
Date: 2026-08-27 18:18:28
Message-ID: 636a2d5b-adaf-45d7-a255-870682a8cc73@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 2026-08-27 00:49, Denis Smirnov wrote:

Hi Denis!

Thank you, and thank you for conceding the client-side point.

> It is not clear why libpq should expose exactly two endpoints. Which
> port is the "server port" here: 39907, 6432, or 5432? Only 39907 is
> visible to libpq.

The same question, asked about the other coordinate, already has an
answer in libpq. In your chain:

libpq -> localhost:39907 -> SSH jump1 -> SSH jump2
-> PgBouncer:6432 -> PostgreSQL:5432

which one is the host? Only localhost is visible to libpq, and yet
"host=db.example.com hostaddr=127.0.0.1" is supported, documented, and
used in production today -- pgAdmin does exactly this for its tunnels.
libpq does not model the route there either: hostaddr is the first hop,
the only thing libpq dials, and host is who the user says is at the end
of it. Everything in between has always been invisible, and nothing in
the patch changes that.

So portaddr adds no knowledge of the route. It completes the address of
that same first hop. The patch does not expose two endpoints: it
exposes one endpoint and one identity, which is what host and hostaddr
already are.

And "which port is the server port" is answered the same way as "which
host": by the user, explicitly, or not at all. If you authenticate
against PgBouncer, the credential is PgBouncer's and port is 6432; if
the tunnel ends at PostgreSQL, it is 5432. libpq never guesses. Your
example is in fact where today's workaround breaks: with PgBouncer on
6432 and PostgreSQL on 5432 on one host, the wildcard entry that a
tunnel forces you to write, host:*:..., collapses both into whichever
line comes first.

> port and PQport() should continue to mean the port to which libpq
> actually connects.

PQhost() already does not mean the host to which libpq actually
connects: with hostaddr it returns the host verbatim, and PQhostaddr()
returns the address. Keeping port as the exception is the part that
needs justification.

> SSH forwarding should be configured by SSH itself, for example with
> ProxyJump and LocalForward in ~/.ssh/config.

Agreed for the chain itself. But LocalForward takes an explicit
[bind_address:]port, so that configuration means a fixed local port,
which is exactly the case I already granted Christoph: write it into
.pgpass and you need no patch. (ProxyJump is not something libpq can
use on its own; libpq calls connect() on a socket and never invokes
ssh.) What remains is the case where no port can be written in advance,
because it does not exist yet.

I would like to hear other opinions on the model.

Thank you,
BR,
Diego

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Nathan Bossart 2026-08-27 18:26:12 REPACK (CONCURRENTLY) fails when replica identity index is dropped
Previous Message Matheus Alcantara 2026-08-27 18:16:31 Re: REPACK (CONCURRENTLY) fails when table owner lacks CONNECT