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