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; }
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; }