예제 #1
0
파일: mcast.c 프로젝트: Thermi/fence-virt
void
do_read_hostlist(int fd, int timeout)
{
	host_state_t hinfo;
	fd_set rfds;
	struct timeval tv;
	int ret;

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

		ret = _select_retry(fd+1, &rfds, NULL, NULL, &tv);
		if (ret == 0) {
			printf("Timed out!\n");
			break;
		}

		ret = _read_retry(fd, &hinfo, sizeof(hinfo), &tv);
		if (ret < sizeof(hinfo)) {
			printf("Bad read!\n");
			break;
		}

		if (strlen((char *)hinfo.uuid) == 0 &&
		    strlen((char *)hinfo.domain) == 0)
			break;

		printf("%-32s %s %s\n", hinfo.domain, hinfo.uuid,
		       (hinfo.state == 1) ? "on" : "off");

	} while (1);
}
예제 #2
0
파일: serial.c 프로젝트: zaneb/fence-virt
int
wait_for(int fd, const char *pattern, size_t size, struct timeval *tout)
{
	char *pos = (char *)pattern;
	char c;
	int n;
	struct timeval tv;
	size_t remain = size;

	if (tout) {
		memcpy(&tv, tout, sizeof(tv));
		tout = &tv;
	}

	while (remain) {
		n = _read_retry(fd, &c, 1, &tv);
		if (n < 1)
			return -1;

		if (c == *pos) {
			++pos;
			--remain;
		} else {
			pos = (char *)pattern;
			remain = size;
		}
	}

	return 0;
}
예제 #3
0
파일: mcast.c 프로젝트: Thermi/fence-virt
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;
}
예제 #4
0
static int
vsock_dispatch(listener_context_t c, struct timeval *timeout)
{
	vsock_info *info;
	fence_req_t data;
	fd_set rfds;
	int n;
	int client_fd;
    int ret;
	struct timeval tv;

    if (timeout != NULL)
    	memcpy(&tv, timeout, sizeof(tv));
    else {
        tv.tv_sec = 1;
        tv.tv_usec = 0;
    }

	info = (vsock_info *) c;
	VALIDATE(info);

	FD_ZERO(&rfds);
	FD_SET(info->listen_sock, &rfds);

	n = select(info->listen_sock + 1, &rfds, NULL, NULL, timeout);
	if (n <= 0) {
		if (errno == EINTR || errno == EAGAIN)
			n = 0;
		else
			dbg_printf(2, "select: %s\n", strerror(errno));
		return n;
	}

	
	client_fd = accept(info->listen_sock, NULL, NULL);
	if (client_fd < 0) {
		perror("accept");
		return -1;
	}

	dbg_printf(3, "Accepted vsock client...\n");

	ret = _read_retry(client_fd, &data, sizeof(data), &tv);
	if (ret != sizeof(data)) {
		dbg_printf(3, "Invalid request (read %d bytes)\n", ret);
		close(client_fd);
		return 0;
	}

	swab_fence_req_t(&data);

	if (!verify_request(&data, info->args.hash, info->key, info->key_len)) {
		printf("Key mismatch; dropping client\n");
        close(client_fd);
		return 0;
	}

	dbg_printf(3, "Request %d seqno %d domain %s\n",
		data.request, data.seqno, data.domain);

	if (history_check(info->history, &data) == 1) {
		printf("We just did this request; dropping client\n");
        close(client_fd);
		return 0;
	}
		
	switch(info->args.auth) {
	case AUTH_NONE:
	case AUTH_SHA1:
	case AUTH_SHA256:
	case AUTH_SHA512:
		printf("VSOCK request\n");
		do_fence_request_vsock(client_fd, &data, info);
		break;
	default:
		printf("XXX Unhandled authentication\n");
	}

	return 0;
}
예제 #5
0
파일: serial.c 프로젝트: zaneb/fence-virt
int
serial_fence_virt(fence_virt_args_t *args)
{
	struct in_addr ina;
	struct in6_addr in6a;
	serial_req_t req;
	int fd, ret;
	char speed[32], *flags = NULL;
	struct timeval tv;
	serial_resp_t resp;

	if (args->serial.device) {
		strncpy(speed, args->serial.speed, sizeof(speed));

		//printf("Port: %s Speed: %s\n", args->serial.device, speed);

		if ((flags = strchr(speed, ','))) {
			*flags = 0;
			flags++;
		}
	
		fd = open_port(args->serial.device, speed, flags);
		if (fd == -1) {
			perror("open_port");
			return -1;
		}

		hangup(fd, 300000);
	} else {
		fd = -1;
		if (inet_pton(PF_INET, args->serial.address, &ina)) {
			fd = ipv4_connect(&ina, args->net.port, 3);
		} else if (inet_pton(PF_INET6, args->serial.address, &in6a)) {
			fd = ipv6_connect(&in6a, args->net.port, 3);
		}

		if (fd < 0) {
			perror("vmchannel connect");
			printf("Failed to connect to %s:%d\n", args->serial.address,
			       args->net.port);
		}
	}


	memset(&req, 0, sizeof(req));
	req.magic = SERIAL_MAGIC;
	req.request = (uint8_t)args->op;
	gettimeofday(&tv, NULL);
	req.seqno = (int)tv.tv_usec;

	if (args->domain) 
		strncpy((char *)req.domain, args->domain, sizeof(req.domain));
	
	tv.tv_sec = 3;
	tv.tv_usec = 0;
	swab_serial_req_t(&req);
	ret = _write_retry(fd, &req, sizeof(req), &tv);
	if (ret < sizeof(req)) {
		if (ret < 0)
			return ret;
		printf("Failed to send request\n");
	}

	tv.tv_sec = args->timeout;
	tv.tv_usec = 0;
	resp.magic = SERIAL_MAGIC;
	do {
		if (wait_for(fd, (const char *)&resp.magic,
			     sizeof(resp.magic), &tv) == 0) {
			ret = _read_retry(fd, &resp.response, sizeof(resp.response), &tv);
		}

		swab_serial_resp_t(&resp);
	} while(resp.magic != SERIAL_MAGIC && (tv.tv_sec || tv.tv_usec));

	if (resp.magic != SERIAL_MAGIC)
		return -1;
	ret = resp.response;
	if (resp.response == RESP_HOSTLIST) /* hostlist */ {
		/* ok read hostlist */
		do_read_hostlist(fd, args->timeout);
		ret = 0;
	}

	close(fd);

	return ret;
}