Example #1
0
static int
connect_tcp(fence_req_t *req, fence_auth_type_t auth,
	    void *key, size_t key_len)
{
	int fd = -1;
	struct sockaddr_in sin;
	struct sockaddr_in6 sin6;
	char buf[128];

	switch(req->family) {
	case PF_INET:
		memset(&sin, 0, sizeof(sin));
		memcpy(&sin.sin_addr, req->address,
		       sizeof(sin.sin_addr));
		sin.sin_family = PF_INET;
		fd = ipv4_connect(&sin.sin_addr, req->port,
				  5);
		if (fd < 0) {
			printf("Failed to call back\n");
			return -1;
		}
		break;
	case PF_INET6:
		memset(&sin6, 0, sizeof(sin6));
		memcpy(&sin6.sin6_addr, req->address,
		       sizeof(sin6.sin6_addr));
		sin.sin_family = PF_INET6;
		fd = ipv6_connect(&sin6.sin6_addr, req->port,
				  5);

		memset(buf,0,sizeof(buf));
		inet_ntop(PF_INET6, &sin6.sin6_addr, buf, sizeof(buf));

		if (fd < 0) {
			printf("Failed to call back %s\n", buf);
			return -1;
		}
		break;
	default:
		printf("Family = %d\n", req->family);
		return -1;
	}

	/* Noops if auth == AUTH_NONE */
	if (tcp_response(fd, auth, key, key_len, 10) <= 0) {
		printf("Failed to respond to challenge\n");
		close(fd);
		return -1;
	}

	if (tcp_challenge(fd, auth, key, key_len, 10) <= 0) {
		printf("Remote failed challenge\n");
		close(fd);
		return -1;
	}
	return fd;
}
Example #2
0
static int
tcp_exchange(int fd, fence_auth_type_t auth, void *key,
	      size_t key_len, int timeout)
{
	fd_set rfds;
	struct timeval tv;
	char ret = 1;

	/* Ok, we're connected */
	dbg_printf(3, "Issuing TCP challenge\n");
	if (tcp_challenge(fd, auth, key, key_len, timeout) <= 0) {
		/* Challenge failed */
		printf("Invalid response to challenge\n");
		return 1;
	}

	/* Now they'll send us one, so we need to respond here */
	dbg_printf(3, "Responding to TCP challenge\n");
	if (tcp_response(fd, auth, key, key_len, timeout) <= 0) {
		printf("Invalid response to challenge\n");
		return 1;
	}

	dbg_printf(2, "TCP Exchange + Authentication done... \n");

	FD_ZERO(&rfds);
	FD_SET(fd, &rfds);
	tv.tv_sec = timeout;
	tv.tv_usec = 0;

	ret = 1;
	dbg_printf(3, "Waiting for return value from XVM host\n");
	if (_select_retry(fd + 1, &rfds, NULL, NULL, &tv) <= 0)
		return -1;

	/* Read return code */
	if (_read_retry(fd, &ret, 1, &tv) < 0)
		ret = 1;

	if (ret == (char)RESP_HOSTLIST) /* hostlist */ {
		do_read_hostlist(fd, timeout);
		ret = 0;
	}

	return ret;
}
Example #3
0
static int
do_fence_request_tcp(int fd, fence_req_t *req, tcp_info *info)
{
	char ip_addr_src[1024];
	char response = 1;
	struct tcp_hostlist_arg arg;

	/* Noops if auth == AUTH_NONE */
	if (tcp_response(fd, info->args.auth, info->key, info->key_len, 10) <= 0) {
		printf("Failed to respond to challenge\n");
		close(fd);
		return -1;
	}

	if (tcp_challenge(fd, info->args.auth, info->key, info->key_len, 10) <= 0) {
		printf("Remote failed challenge\n");
		close(fd);
		return -1;
	}

	dbg_printf(2, "Request %d seqno %d target %s\n", 
		   req->request, req->seqno, req->domain);

	switch(req->request) {
	case FENCE_NULL:
		response = info->cb->null((char *)req->domain, info->priv);
		break;
	case FENCE_ON:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->on((char *)req->domain, ip_addr_src,
					req->seqno, info->priv);
		break;
	case FENCE_OFF:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->off((char *)req->domain, ip_addr_src,
					 req->seqno, info->priv);
		break;
	case FENCE_REBOOT:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->reboot((char *)req->domain, ip_addr_src,
					    req->seqno, info->priv);
		break;
	case FENCE_STATUS:
		if (map_check(info->map, ip_addr_src,
				     (const char *)req->domain) == 0) {
			response = RESP_PERM;
			break;
		}
		response = info->cb->status((char *)req->domain, info->priv);
		break;
	case FENCE_DEVSTATUS:
		response = info->cb->devstatus(info->priv);
		break;
	case FENCE_HOSTLIST:
		arg.map = info->map;
		arg.src = ip_addr_src;
		arg.fd = fd;

		tcp_hostlist_begin(arg.fd);
		response = info->cb->hostlist(tcp_hostlist, &arg,
					      info->priv);
		tcp_hostlist_end(arg.fd);
		break;
	}

	dbg_printf(3, "Sending response to caller...\n");
	if (write(fd, &response, 1) < 0) {
		perror("write");
	}

	history_record(info->history, req);

	if (fd != -1)
		close(fd);

	return 1;
}