// // Copyright (C) 2022 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 #include "common/frontend/socket_vsock_proxy/server.h" #include "common/libs/utils/contains.h" namespace cuttlefish { namespace socket_proxy { namespace { bool socketErrorIsRecoverable(int error) { std::set unrecoverable{EACCES, EAFNOSUPPORT, EINVAL, EPROTONOSUPPORT}; return !Contains(unrecoverable, error); } [[noreturn]] static void SleepForever() { while (true) { sleep(std::numeric_limits::max()); } } } TcpServer::TcpServer(int port) : port_(port) {} SharedFD TcpServer::Start() { SharedFD server; server = SharedFD::SocketLocalServer(port_, SOCK_STREAM); CHECK(server->IsOpen()) << "Could not start server on " << port_; return server; } std::string TcpServer::Describe() const { return fmt::format("tcp: {}", port_); } VsockServer::VsockServer(int port) : port_(port) {} // Intended to run in the guest SharedFD VsockServer::Start() { SharedFD server; do { server = SharedFD::VsockServer(port_, SOCK_STREAM); if (!server->IsOpen() && !socketErrorIsRecoverable(server->GetErrno())) { LOG(ERROR) << "Could not open vsock socket: " << server->StrError(); // socket_vsock_proxy will now wait forever in the guest on encountering an // "unrecoverable" errno. This is to prevent churn from being restarted by // init.vsoc.rc. SleepForever(); } } while (!server->IsOpen()); return server; } std::string VsockServer::Describe() const { return fmt::format("vsock: {}", port_); } DupServer::DupServer(int fd) : fd_(fd), sfd_(SharedFD::Dup(fd_)) { close(fd); } SharedFD DupServer::Start() { CHECK(sfd_->IsOpen()) << "Could not start duplicate server for passed fd"; return sfd_; } std::string DupServer::Describe() const { return fmt::format("fd: {}", fd_); } } }