S, for server.
user::
- +pgbouncer+ connected user.
+ Username +pgbouncer+ uses to connect to server.
database::
- database name.
+ database name on server.
state::
State of the pgbouncer server connection, one of +active+, +used+ or
port::
Port of PostgreSQL server.
+local_addr::
+ Connection start address on local machine.
+
+local_port::
+ Connection start port on local machine.
+
connect_time::
When the connection was made.
request_time::
When last request was issued.
+ptr::
+ Address of internal object for this connection.
+ Used as unique ID.
+
+link::
+ Address of client connection the server is paired with.
+
==== SHOW CLIENTS; ====
type::
port::
port client is connected to.
+local_addr::
+ Connection end address on local machine.
+
+local_port::
+ Connection end port on local machine.
+
connect_time::
Timestamp of later client connection.
request_time::
Timestamp of later client request.
+ptr::
+ Address of internal object for this connection.
+ Used as unique ID.
+
+link::
+ Address of server connection the client is paired with.
==== SHOW POOLS; ====
msg.msg_iovlen = 1;
/* attach a fd */
- if (admin->addr.is_unix && admin->own_user) {
+ if (admin->remote_addr.is_unix && admin->own_user) {
msg.msg_control = cntbuf;
msg.msg_controllen = sizeof(cntbuf);
/* send a row with sendmsg, optionally attaching a fd */
static bool show_one_fd(PgSocket *admin, PgSocket *sk)
{
- PgAddr *addr = &sk->addr;
+ PgAddr *addr = &sk->remote_addr;
MBuf tmp;
VarCache *v = &sk->vars;
return true;
}
-#define SKF_STD "sssssiTT"
-#define SKF_DBG "sssssiTTiiiiiiiss"
+#define SKF_STD "sssssisiTTss"
+#define SKF_DBG "sssssisiTTssiiiiiii"
static void socket_header(PktBuf *buf, bool debug)
{
pktbuf_write_RowDescription(buf, debug ? SKF_DBG : SKF_STD,
"type", "user", "database", "state",
- "addr", "port",
+ "addr", "port", "local_addr", "local_port",
"connect_time", "request_time",
+ "ptr", "link",
"recv_pos", "pkt_pos", "pkt_remain",
"send_pos", "send_remain",
- "pkt_avail", "send_avail",
- "ptr", "link");
+ "pkt_avail", "send_avail");
+}
+
+static void adr2txt(const PgAddr *adr, char *dst, int dstlen)
+{
+ if (adr->is_unix) {
+ strlcpy(dst, "unix", dstlen);
+ } else {
+ char *tmp = inet_ntoa(adr->ip_addr);
+ strlcpy(dst, tmp, dstlen);
+ }
}
static void socket_row(PktBuf *buf, PgSocket *sk, const char *state, bool debug)
{
- const char *addr = sk->addr.is_unix ? "unix"
- : inet_ntoa(sk->addr.ip_addr);
int pkt_avail = sk->sbuf.recv_pos - sk->sbuf.pkt_pos;
int send_avail = sk->sbuf.recv_pos - sk->sbuf.send_pos;
char ptrbuf[128], linkbuf[128];
+ char l_addr[32], r_addr[32];
+
+ adr2txt(&sk->remote_addr, r_addr, sizeof(r_addr));
+ adr2txt(&sk->local_addr, l_addr, sizeof(l_addr));
snprintf(ptrbuf, sizeof(ptrbuf), "%p", sk);
if (sk->link)
is_server_socket(sk) ? "S" :"C",
sk->auth_user ? sk->auth_user->name : "(nouser)",
sk->pool ? sk->pool->db->name : "(nodb)",
- state, addr, sk->addr.port,
+ state, r_addr, sk->remote_addr.port,
+ l_addr, sk->local_addr.port,
sk->connect_time,
sk->request_time,
+ ptrbuf, linkbuf,
sk->sbuf.recv_pos,
sk->sbuf.pkt_pos,
sk->sbuf.pkt_remain,
sk->sbuf.send_pos,
sk->sbuf.send_remain,
- pkt_avail, send_avail,
- ptrbuf, linkbuf);
+ pkt_avail, send_avail);
}
/* Helper for SHOW CLIENTS */
client->own_user = 0;
/* tag same uid as special */
- if (client->addr.is_unix) {
+ if (client->remote_addr.is_unix) {
res = getpeereid(sbuf_socket(&client->sbuf), &peer_uid, &peer_gid);
if (res >= 0 && peer_uid == getuid()
&& strcmp("pgbouncer", username) == 0)
char salt[4];
uint8 cancel_key[BACKENDKEY_LEN];
PgUser * auth_user;
- PgAddr addr;
+ PgAddr remote_addr;
+ PgAddr local_addr;
VarCache vars;
/* initialize it */
server->pool = pool;
server->auth_user = server->pool->user;
- server->addr = server->pool->db->addr;
+ server->remote_addr = server->pool->db->addr;
server->connect_time = get_cached_time();
pool->last_connect_time = get_cached_time();
change_server_state(server, SV_LOGIN);
unix_dir = server->pool->db->unix_socket_dir;
/* start connecting */
- sbuf_connect(&server->sbuf, &server->addr, unix_dir,
+ sbuf_connect(&server->sbuf, &server->remote_addr, unix_dir,
cf_server_connect_timeout / USEC);
}
client->connect_time = client->request_time = get_cached_time();
client->query_start = 0;
- if (addr) {
- client->addr.ip_addr = addr->sin_addr;
- client->addr.port = ntohs(addr->sin_port);
- } else {
- memset(&client->addr, 0, sizeof(client->addr));
- }
- client->addr.is_unix = is_unix;
+ fill_remote_addr(client, sock, is_unix);
+ fill_local_addr(client, sock, is_unix);
+
change_client_state(client, CL_LOGIN);
if (cf_log_connections)
slog_debug(client, "got connection attempt");
sbuf_accept(&client->sbuf, sock, is_unix);
+
return client;
}
PktBuf tmp;
client = accept_client(fd, NULL, addr->is_unix);
- client->addr = *addr;
client->suspended = 1;
if (!set_pool(client, dbname, username))
server->suspended = 1;
server->pool = pool;
server->auth_user = user;
- server->addr = *addr;
server->connect_time = server->request_time = get_cached_time();
server->query_start = 0;
+ fill_remote_addr(server, fd, addr->is_unix);
+ fill_local_addr(server, fd, addr->is_unix);
+
if (linkfd) {
server->ready = 0;
change_server_state(server, SV_ACTIVE);
bool res = false;
PgPool *pool = server->pool;
+ fill_local_addr(server, sbuf_socket(&server->sbuf), server->remote_addr.is_unix);
+
if (!statlist_empty(&pool->cancel_req_list)) {
slog_debug(server, "use it for pending cancel req");
/* if pending cancel req, send it */
db = sock->pool ? sock->pool->db->name : "(nodb)";
user = sock->auth_user ? sock->auth_user->name : "(nouser)";
- if (sock->addr.is_unix) {
+ if (sock->remote_addr.is_unix) {
host = "unix";
} else {
- host = inet_ntoa(sock->addr.ip_addr);
+ host = inet_ntoa(sock->remote_addr.ip_addr);
}
- port = sock->addr.port;
+ port = sock->remote_addr.port;
va_start(ap, fmt);
vsnprintf(buf1, sizeof(buf1), fmt, ap);
return buf;
}
+void fill_remote_addr(PgSocket *sk, int fd, bool is_unix)
+{
+ PgAddr *dst = &sk->remote_addr;
+ struct sockaddr_in adr;
+ socklen_t len = sizeof(adr);
+ int err;
+
+ dst->ip_addr.s_addr = INADDR_ANY;
+ dst->port = 0;
+ dst->is_unix = is_unix;
+ if (is_unix) {
+ dst->port = cf_listen_port;
+ } else {
+ err = getpeername(fd, (struct sockaddr *)&adr, &len);
+ if (err < 0) {
+ log_error("fill_remote_addr: getpeername(%d) = %s",
+ fd, strerror(errno));
+ } else {
+ log_info("fill_remote_addr: remote=%s:%d",
+ inet_ntoa(adr.sin_addr), ntohs(adr.sin_port));
+ dst->ip_addr = adr.sin_addr;
+ dst->port = ntohs(adr.sin_port);
+ }
+ }
+}
+
+void fill_local_addr(PgSocket *sk, int fd, bool is_unix)
+{
+ PgAddr *dst = &sk->local_addr;
+ struct sockaddr_in adr;
+ socklen_t len = sizeof(adr);
+ int err;
+
+ dst->ip_addr.s_addr = INADDR_ANY;
+ dst->port = 0;
+ dst->is_unix = is_unix;
+ if (is_unix) {
+ dst->port = cf_listen_port;
+ } else {
+ err = getsockname(fd, (struct sockaddr *)&adr, &len);
+ if (err < 0) {
+ log_error("fill_local_addr: getsockname(%d) = %s",
+ fd, strerror(errno));
+ } else {
+ log_info("fill_local_addr: local=%s:%d",
+ inet_ntoa(adr.sin_addr), ntohs(adr.sin_port));
+ dst->ip_addr = adr.sin_addr;
+ dst->port = ntohs(adr.sin_port);
+ }
+ }
+}
+
const char *format_date(usec_t uval);
+void fill_remote_addr(PgSocket *sk, int fd, bool is_unix);
+void fill_local_addr(PgSocket *sk, int fd, bool is_unix);
+
+