From bd02ba6bfa52a69e04b17e2721eba0a2b9c0b8ce Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Mon, 8 Oct 2007 09:50:55 +0000 Subject: [PATCH] Show local address in SHOW CLIENTS/SERVERS/SOCKETS; Also include 'ptr' and 'link' fields in SHOW CLIENTS/SERVERS; --- doc/pgbouncer.cmdline.txt | 29 ++++++++++++++++++-- src/admin.c | 39 +++++++++++++++++--------- src/bouncer.h | 3 +- src/objects.c | 20 ++++++-------- src/server.c | 2 ++ src/util.c | 58 +++++++++++++++++++++++++++++++++++++-- src/util.h | 4 +++ 7 files changed, 125 insertions(+), 30 deletions(-) diff --git a/doc/pgbouncer.cmdline.txt b/doc/pgbouncer.cmdline.txt index 2b7ee09..cd1c749 100644 --- a/doc/pgbouncer.cmdline.txt +++ b/doc/pgbouncer.cmdline.txt @@ -166,10 +166,10 @@ type:: 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 @@ -181,12 +181,25 @@ addr:: 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:: @@ -208,12 +221,24 @@ addr:: 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; ==== diff --git a/src/admin.c b/src/admin.c index ce594ab..01f4a40 100644 --- a/src/admin.c +++ b/src/admin.c @@ -179,7 +179,7 @@ static bool send_one_fd(PgSocket *admin, 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); @@ -208,7 +208,7 @@ static bool send_one_fd(PgSocket *admin, /* 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; @@ -404,28 +404,40 @@ static bool admin_show_users(PgSocket *admin, const char *arg) 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) @@ -437,16 +449,17 @@ static void socket_row(PktBuf *buf, PgSocket *sk, const char *state, bool debug) 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 */ @@ -910,7 +923,7 @@ bool admin_pre_login(PgSocket *client) 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) diff --git a/src/bouncer.h b/src/bouncer.h index 2b487bb..9e6c018 100644 --- a/src/bouncer.h +++ b/src/bouncer.h @@ -242,7 +242,8 @@ struct PgSocket { char salt[4]; uint8 cancel_key[BACKENDKEY_LEN]; PgUser * auth_user; - PgAddr addr; + PgAddr remote_addr; + PgAddr local_addr; VarCache vars; diff --git a/src/objects.c b/src/objects.c index 0a88787..0316376 100644 --- a/src/objects.c +++ b/src/objects.c @@ -775,7 +775,7 @@ void launch_new_connection(PgPool *pool) /* 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); @@ -788,7 +788,7 @@ void launch_new_connection(PgPool *pool) 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); } @@ -807,19 +807,16 @@ PgSocket * accept_client(int sock, 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; } @@ -940,7 +937,6 @@ bool use_client_socket(int fd, PgAddr *addr, PktBuf tmp; client = accept_client(fd, NULL, addr->is_unix); - client->addr = *addr; client->suspended = 1; if (!set_pool(client, dbname, username)) @@ -993,10 +989,12 @@ bool use_server_socket(int fd, PgAddr *addr, 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); diff --git a/src/server.c b/src/server.c index cc06da1..cb2a1c2 100644 --- a/src/server.c +++ b/src/server.c @@ -247,6 +247,8 @@ static bool handle_connect(PgSocket *server) 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 */ diff --git a/src/util.c b/src/util.c index 45177be..d8fd88d 100644 --- a/src/util.c +++ b/src/util.c @@ -144,12 +144,12 @@ slog_level(const char *pfx, const PgSocket *sock, const char *fmt, ...) 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); @@ -537,3 +537,55 @@ const char *format_date(usec_t uval) 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); + } + } +} + diff --git a/src/util.h b/src/util.h index 6a3d03a..dfb0186 100644 --- a/src/util.h +++ b/src/util.h @@ -99,3 +99,7 @@ bool strlist_contains(const char *liststr, const char *str); 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); + + -- 2.40.0