@@ -128,7 +128,7 @@ verify_request::~verify_request(void)
128128
129129shard_connection::shard_connection (unsigned int id, connections_manager* conns_man, benchmark_config* config,
130130 struct event_base * event_base, abstract_protocol* abs_protocol) :
131- m_address(NULL ), m_port(NULL ), m_unix_sockaddr(NULL ),
131+ m_address(NULL ), m_port(NULL ), m_unix_sockaddr(NULL ), m_unix_sockaddrlen( 0 ),
132132 m_bev(NULL ), m_request_per_cur_interval(0 ), m_pending_resp(0 ), m_connection_state(conn_disconnected),
133133 m_hello(setup_done), m_authentication(setup_done), m_db_selection(setup_done), m_cluster_slots(setup_done) {
134134 m_id = id;
@@ -140,9 +140,19 @@ shard_connection::shard_connection(unsigned int id, connections_manager* conns_m
140140 m_unix_sockaddr = (struct sockaddr_un *) malloc (sizeof (struct sockaddr_un ));
141141 assert (m_unix_sockaddr != NULL );
142142
143+ memset (m_unix_sockaddr, 0 , sizeof (struct sockaddr_un ));
143144 m_unix_sockaddr->sun_family = AF_UNIX;
144- strncpy (m_unix_sockaddr->sun_path , m_config->unix_socket , sizeof (m_unix_sockaddr->sun_path )-1 );
145- m_unix_sockaddr->sun_path [sizeof (m_unix_sockaddr->sun_path )-1 ] = ' \0 ' ;
145+
146+ // Consider any Unix socket path prefixed with @ an abstract socket.
147+ // In this scenario, sun_path[0] must be a null byte, and addrlen should be terminated at
148+ // exactly the socket name length; see the manpage for unix(7).
149+ if (m_config->unix_socket [0 ] == ' @' ) {
150+ strncpy (&m_unix_sockaddr->sun_path [1 ], &m_config->unix_socket [1 ], strlen (m_config->unix_socket )-1 );
151+ m_unix_sockaddrlen = offsetof (struct sockaddr_un , sun_path) + strlen (m_config->unix_socket );
152+ } else {
153+ strncpy (m_unix_sockaddr->sun_path , m_config->unix_socket , sizeof (m_unix_sockaddr->sun_path )-1 );
154+ m_unix_sockaddrlen = sizeof (struct sockaddr_un );
155+ }
146156 }
147157
148158 m_protocol = abs_protocol->clone ();
@@ -279,7 +289,7 @@ int shard_connection::connect(struct connect_info* addr) {
279289
280290 if (bufferevent_socket_connect (m_bev,
281291 m_unix_sockaddr ? (struct sockaddr *) m_unix_sockaddr : addr->ci_addr ,
282- m_unix_sockaddr ? sizeof ( struct sockaddr_un ) : addr->ci_addrlen ) == -1 ) {
292+ m_unix_sockaddr ? m_unix_sockaddrlen : addr->ci_addrlen ) == -1 ) {
283293 disconnect ();
284294
285295 benchmark_error_log (" connect failed, error = %s\n " , strerror (errno));
0 commit comments