Przeglądaj źródła

qdevice-net: Add option to force ip version

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Jan Friesse 10 lat temu
rodzic
commit
1ec61e33cc

+ 31 - 2
qdevices/nss-sock.c

@@ -191,11 +191,17 @@ nss_sock_create_client_socket(const char *hostname, uint16_t port, PRIntn af,
 	void *addr_iter;
 	PRStatus res;
 	int connect_failed;
+	PRIntn tmp_af;
 
 	sock = NULL;
 	connect_failed = 0;
 
-	addr_info = PR_GetAddrInfoByName(hostname, af, PR_AI_ADDRCONFIG);
+	tmp_af = af;
+	if (af == PR_AF_INET6) {
+		tmp_af = PR_AF_UNSPEC;
+	}
+
+	addr_info = PR_GetAddrInfoByName(hostname, tmp_af, PR_AI_ADDRCONFIG);
 	if (addr_info == NULL) {
 		return (NULL);
 	}
@@ -203,6 +209,10 @@ nss_sock_create_client_socket(const char *hostname, uint16_t port, PRIntn af,
 	addr_iter = NULL;
 
 	while ((addr_iter = PR_EnumerateAddrInfo(addr_iter, addr_info, port, &addr)) != NULL) {
+		if (af != PR_AF_UNSPEC && addr.raw.family != af) {
+			continue ;
+		}
+
 		sock = nss_sock_create_socket(addr.raw.family, 0);
 		if (sock == NULL) {
 			continue ;
@@ -233,6 +243,7 @@ int
 nss_sock_non_blocking_client_init(const char *host_name, uint16_t port, PRIntn af,
     struct nss_sock_non_blocking_client *client)
 {
+	PRIntn tmp_af;
 
 	client->destroyed = 1;
 
@@ -245,7 +256,12 @@ nss_sock_non_blocking_client_init(const char *host_name, uint16_t port, PRIntn a
 	client->port = port;
 	client->af = af;
 
-	client->addr_info = PR_GetAddrInfoByName(client->host_name, af, PR_AI_ADDRCONFIG);
+	tmp_af = af;
+	if (af == PR_AF_INET6) {
+		tmp_af = PR_AF_UNSPEC;
+	}
+
+	client->addr_info = PR_GetAddrInfoByName(client->host_name, tmp_af, PR_AI_ADDRCONFIG);
 	if (client->addr_info == NULL) {
 		free(client->host_name);
 
@@ -265,6 +281,11 @@ nss_sock_non_blocking_client_try_next(struct nss_sock_non_blocking_client *clien
 	PRNetAddr addr;
 	PRStatus res;
 
+	if (client->destroyed) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return (-1);
+	}
+
 	if (client->socket != NULL) {
 		PR_Close(client->socket);
 		client->socket = NULL;
@@ -272,6 +293,10 @@ nss_sock_non_blocking_client_try_next(struct nss_sock_non_blocking_client *clien
 
 	while ((client->addr_iter = PR_EnumerateAddrInfo(client->addr_iter, client->addr_info,
 	    client->port, &addr)) != NULL) {
+		if (client->af != PR_AF_UNSPEC && addr.raw.family != client->af) {
+			continue ;
+		}
+
 		client->socket = nss_sock_create_socket(addr.raw.family, 0);
 		if (client->socket == NULL) {
 			continue ;
@@ -307,6 +332,10 @@ void
 nss_sock_non_blocking_client_destroy(struct nss_sock_non_blocking_client *client)
 {
 
+	if (client->destroyed) {
+		return ;
+	}
+
 	if (client->addr_info != NULL) {
 		PR_FreeAddrInfo(client->addr_info);
 		client->addr_info = NULL;

+ 19 - 1
qdevices/qdevice-model-net.c

@@ -133,6 +133,23 @@ qdevice_model_net_timer_connect_timeout(void *data1, void *data2)
 	return (0);
 }
 
+static PRIntn
+qdevice_model_net_get_af(const struct qdevice_net_instance *instance)
+{
+	PRIntn af;
+
+	af = PR_AF_UNSPEC;
+	if (instance->force_ip_version == 4) {
+		af = PR_AF_INET;
+	}
+
+	if (instance->force_ip_version == 6) {
+		af = PR_AF_INET6;
+	}
+
+	return (af);
+}
+
 int
 qdevice_model_net_run(struct qdevice_instance *instance)
 {
@@ -165,7 +182,8 @@ qdevice_model_net_run(struct qdevice_instance *instance)
 		    net_instance->host_addr, net_instance->host_port, net_instance->connect_timeout);
 
 		res = nss_sock_non_blocking_client_init(net_instance->host_addr,
-		    net_instance->host_port, PR_AF_UNSPEC, &net_instance->non_blocking_client);
+		    net_instance->host_port, qdevice_model_net_get_af(net_instance),
+		    &net_instance->non_blocking_client);
 		if (res == -1) {
 			qdevice_log_nss(LOG_ERR, "Can't initialize non blocking client connection");
 		}

+ 19 - 1
qdevices/qdevice-net-instance.c

@@ -51,7 +51,7 @@ qdevice_net_instance_init(struct qdevice_net_instance *instance, size_t initial_
     uint32_t sync_heartbeat_interval, uint32_t cast_vote_timer_interval,
     const char *host_addr, uint16_t host_port, const char *cluster_name,
     const struct tlv_tie_breaker *tie_breaker, uint32_t connect_timeout,
-    int cmap_fd, int votequorum_fd)
+    int force_ip_version, int cmap_fd, int votequorum_fd)
 {
 
 	memset(instance, 0, sizeof(*instance));
@@ -72,6 +72,7 @@ qdevice_net_instance_init(struct qdevice_net_instance *instance, size_t initial_
 	instance->last_msg_seq_num = 1;
 	instance->echo_request_expected_msg_seq_num = 1;
 	instance->echo_reply_received_msg_seq_num = 1;
+	instance->force_ip_version = force_ip_version;
 	memcpy(&instance->tie_breaker, tie_breaker, sizeof(*tie_breaker));
 
 	dynar_init(&instance->receive_buffer, initial_receive_size);
@@ -157,6 +158,7 @@ qdevice_net_instance_init_from_cmap(struct qdevice_instance *instance)
 	char *cluster_name;
 	uint32_t connect_timeout;
 	struct qdevice_net_instance *net_instance;
+	int force_ip_version;
 
 	cmap_handle = instance->cmap_handle;
 
@@ -309,6 +311,21 @@ qdevice_net_instance_init_from_cmap(struct qdevice_instance *instance)
 		free(str);
 	}
 
+	if (cmap_get_string(cmap_handle, "quorum.device.net.force_ip_version", &str) != CS_OK) {
+		force_ip_version = 0;
+	} else {
+		li = strtol(str, &ep, 10);
+		if ((li != 0 && li != 4 && li != 6) || *ep != '\0') {
+			qdevice_log(LOG_ERR, "force_ip_version must be one of 0|4|6");
+			free(str);
+			goto error_free_cluster_name;
+		}
+
+		force_ip_version = li;
+
+		free(str);
+	}
+
 	/*
 	 * Really initialize instance
 	 */
@@ -319,6 +336,7 @@ qdevice_net_instance_init_from_cmap(struct qdevice_instance *instance)
 	    tls_supported, decision_algorithm,
 	    heartbeat_interval, sync_heartbeat_interval, cast_vote_timer_interval,
 	    host_addr, host_port, cluster_name, &tie_breaker, connect_timeout,
+	    force_ip_version,
 	    instance->cmap_poll_fd, instance->votequorum_poll_fd) == -1) {
 		qdevice_log(LOG_ERR, "Can't initialize qdevice-net instance");
 		goto error_free_instance;

+ 2 - 1
qdevices/qdevice-net-instance.h

@@ -101,6 +101,7 @@ struct qdevice_net_instance {
 	struct qdevice_instance *qdevice_instance_ptr;
 	struct nss_sock_non_blocking_client non_blocking_client;
 	struct timer_list_entry *connect_timer;
+	int force_ip_version;
 };
 
 extern int		qdevice_net_instance_init(struct qdevice_net_instance *instance,
@@ -110,7 +111,7 @@ extern int		qdevice_net_instance_init(struct qdevice_net_instance *instance,
     enum tlv_decision_algorithm_type decision_algorithm, uint32_t heartbeat_interval,
     uint32_t sync_heartbeat_interval, uint32_t cast_vote_timer_interval,
     const char *host_addr, uint16_t host_port, const char *cluster_name,
-    const struct tlv_tie_breaker *tie_breaker, uint32_t connect_timeout,
+    const struct tlv_tie_breaker *tie_breaker, uint32_t connect_timeout, int force_ip_version,
     int cmap_fd, int votequorum_fd);
 
 extern void		qdevice_net_instance_clean(struct qdevice_net_instance *instance);