| /* |
| * Copyright (C) 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <errno.h> |
| #include <sys/socket.h> |
| #include <unistd.h> |
| |
| #include <linux/vm_sockets.h> |
| |
| #include <cstdlib> |
| #include <cstring> |
| #include <iostream> |
| |
| static constexpr const char LOG_TAG[] = "VsockTest: "; |
| static constexpr int VSOCK_TEST_PORT = 4455; |
| static constexpr const char VSOCK_TEST_MSG[] = "VsockTestMessage\n"; |
| |
| int VsockServer() { |
| int server_fd, client_fd, ret; |
| struct sockaddr_vm server_sa = (struct sockaddr_vm) { |
| .svm_family = AF_VSOCK, |
| .svm_port = VSOCK_TEST_PORT, |
| .svm_cid = VMADDR_CID_ANY, |
| }; |
| struct sockaddr_vm client_sa; |
| socklen_t socklen = sizeof(client_sa); |
| size_t sent = 0, len = strlen(VSOCK_TEST_MSG) + 1; |
| |
| server_fd = socket(AF_VSOCK, SOCK_STREAM, 0); |
| if (server_fd < 0) { |
| std::cerr << "ERROR: socket: " << strerror(errno) << std::endl; |
| return -1; |
| } |
| |
| ret = bind(server_fd, (struct sockaddr*)&server_sa, sizeof(server_sa)); |
| if (ret != 0) { |
| std::cerr << "ERROR: bind: " << strerror(errno) << std::endl; |
| close(server_fd); |
| return -1; |
| } |
| |
| std::cerr << LOG_TAG << "Waiting for a vsock connection..." << std::endl; |
| |
| ret = listen(server_fd, 1); |
| if (ret != 0) { |
| std::cerr << "ERROR: listen: " << strerror(errno) << std::endl; |
| close(server_fd); |
| return -1; |
| } |
| |
| client_fd = accept(server_fd, (struct sockaddr*)&client_sa, &socklen); |
| if (client_fd < 0) { |
| std::cerr << "ERROR: accept: " << strerror(errno) << std::endl; |
| close(server_fd); |
| return -1; |
| } |
| |
| std::cerr << LOG_TAG << "Sending message to host..." << std::endl; |
| |
| while (sent < len) { |
| ssize_t nbytes = write(client_fd, VSOCK_TEST_MSG + sent, len - sent); |
| if (nbytes > 0) { |
| sent += nbytes; |
| } else if (nbytes < 0 && errno == EAGAIN) { |
| continue; |
| } else { |
| close(client_fd); |
| return EXIT_FAILURE; |
| } |
| } |
| |
| close(client_fd); |
| return EXIT_SUCCESS; |
| } |