From 862e5cc65ecff417924d39f4d08f2d0116a44925 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Sun, 26 May 2024 09:47:40 -0700 Subject: [PATCH] shard_connection: Support abstract Unix socket clients --- shard_connection.cpp | 18 ++++++++++++++---- shard_connection.h | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/shard_connection.cpp b/shard_connection.cpp index e8733082..8fd2012e 100644 --- a/shard_connection.cpp +++ b/shard_connection.cpp @@ -128,7 +128,7 @@ verify_request::~verify_request(void) shard_connection::shard_connection(unsigned int id, connections_manager* conns_man, benchmark_config* config, struct event_base* event_base, abstract_protocol* abs_protocol) : - m_address(NULL), m_port(NULL), m_unix_sockaddr(NULL), + m_address(NULL), m_port(NULL), m_unix_sockaddr(NULL), m_unix_sockaddrlen(0), m_bev(NULL), m_event_timer(NULL), m_request_per_cur_interval(0), m_pending_resp(0), m_connection_state(conn_disconnected), m_hello(setup_done), m_authentication(setup_done), m_db_selection(setup_done), m_cluster_slots(setup_done) { m_id = id; @@ -140,9 +140,19 @@ shard_connection::shard_connection(unsigned int id, connections_manager* conns_m m_unix_sockaddr = (struct sockaddr_un *) malloc(sizeof(struct sockaddr_un)); assert(m_unix_sockaddr != NULL); + memset(m_unix_sockaddr, 0, sizeof(struct sockaddr_un)); m_unix_sockaddr->sun_family = AF_UNIX; - strncpy(m_unix_sockaddr->sun_path, m_config->unix_socket, sizeof(m_unix_sockaddr->sun_path)-1); - m_unix_sockaddr->sun_path[sizeof(m_unix_sockaddr->sun_path)-1] = '\0'; + + // Consider any Unix socket path prefixed with @ an abstract socket. + // In this scenario, sun_path[0] must be a null byte, and addrlen should be terminated at + // exactly the socket name length; see the manpage for unix(7). + if (m_config->unix_socket[0] == '@') { + strncpy(&m_unix_sockaddr->sun_path[1], &m_config->unix_socket[1], strlen(m_config->unix_socket)-1); + m_unix_sockaddrlen = offsetof(struct sockaddr_un, sun_path) + strlen(m_config->unix_socket); + } else { + strncpy(m_unix_sockaddr->sun_path, m_config->unix_socket, sizeof(m_unix_sockaddr->sun_path)-1); + m_unix_sockaddrlen = sizeof(struct sockaddr_un); + } } m_protocol = abs_protocol->clone(); @@ -290,7 +300,7 @@ int shard_connection::connect(struct connect_info* addr) { if (bufferevent_socket_connect(m_bev, m_unix_sockaddr ? (struct sockaddr *) m_unix_sockaddr : addr->ci_addr, - m_unix_sockaddr ? sizeof(struct sockaddr_un) : addr->ci_addrlen) == -1) { + m_unix_sockaddr ? m_unix_sockaddrlen : addr->ci_addrlen) == -1) { disconnect(); benchmark_error_log("connect failed, error = %s\n", strerror(errno)); diff --git a/shard_connection.h b/shard_connection.h index 12fbaae3..a190299d 100644 --- a/shard_connection.h +++ b/shard_connection.h @@ -160,6 +160,7 @@ class shard_connection { std::string m_readable_id; struct sockaddr_un* m_unix_sockaddr; + int m_unix_sockaddrlen; struct bufferevent *m_bev; struct event_base* m_event_base; struct event* m_event_timer;