in nitro_enclaves/ne_ioctl_sample.c [650:764]
static int ne_start_enclave_check_booted(int enclave_fd)
{
struct sockaddr_vm client_vsock_addr = {};
int client_vsock_fd = -1;
socklen_t client_vsock_len = sizeof(client_vsock_addr);
struct ne_enclave_start_info enclave_start_info = {};
struct pollfd fds[1] = {};
int rc = -EINVAL;
unsigned char recv_buf = 0;
struct sockaddr_vm server_vsock_addr = {
.svm_family = AF_VSOCK,
.svm_cid = NE_IMAGE_LOAD_HEARTBEAT_CID,
.svm_port = NE_IMAGE_LOAD_HEARTBEAT_PORT,
};
int server_vsock_fd = -1;
server_vsock_fd = socket(AF_VSOCK, SOCK_STREAM, 0);
if (server_vsock_fd < 0) {
rc = server_vsock_fd;
printf("Error in socket [%m]\n");
return rc;
}
rc = bind(server_vsock_fd, (struct sockaddr *)&server_vsock_addr,
sizeof(server_vsock_addr));
if (rc < 0) {
printf("Error in bind [%m]\n");
goto out;
}
rc = listen(server_vsock_fd, 1);
if (rc < 0) {
printf("Error in listen [%m]\n");
goto out;
}
rc = ne_start_enclave(enclave_fd, &enclave_start_info);
if (rc < 0)
goto out;
printf("Enclave started, CID %llu\n", enclave_start_info.enclave_cid);
fds[0].fd = server_vsock_fd;
fds[0].events = POLLIN;
rc = poll(fds, 1, NE_POLL_WAIT_TIME_MS);
if (rc < 0) {
printf("Error in poll [%m]\n");
goto out;
}
if (!rc) {
printf("Poll timeout, %d seconds elapsed\n", NE_POLL_WAIT_TIME);
rc = -ETIMEDOUT;
goto out;
}
if ((fds[0].revents & POLLIN) == 0) {
printf("Poll received value %d\n", fds[0].revents);
rc = -EINVAL;
goto out;
}
rc = accept(server_vsock_fd, (struct sockaddr *)&client_vsock_addr,
&client_vsock_len);
if (rc < 0) {
printf("Error in accept [%m]\n");
goto out;
}
client_vsock_fd = rc;
/*
* Read the heartbeat value that the init process in the enclave sends
* after vsock connect.
*/
rc = read(client_vsock_fd, &recv_buf, sizeof(recv_buf));
if (rc < 0) {
printf("Error in read [%m]\n");
goto out;
}
if (rc != sizeof(recv_buf) || recv_buf != NE_IMAGE_LOAD_HEARTBEAT_VALUE) {
printf("Read %d instead of %d\n", recv_buf,
NE_IMAGE_LOAD_HEARTBEAT_VALUE);
goto out;
}
/* Write the heartbeat value back. */
rc = write(client_vsock_fd, &recv_buf, sizeof(recv_buf));
if (rc < 0) {
printf("Error in write [%m]\n");
goto out;
}
rc = 0;
out:
close(server_vsock_fd);
return rc;
}