diff options
| author | Miguel Gaio <miguel.gaio@renault.com> | 2018-12-04 13:55:10 +0100 |
|---|---|---|
| committer | Eric Laurent <elaurent@google.com> | 2019-04-26 10:59:31 -0700 |
| commit | 2191360f6c25eb140e6cb1085a24f9ff9a18d9c3 (patch) | |
| tree | 432fd8523556ed1037461e5e9180a5770603f9aa | |
| parent | f7bf29332b17034e1a2d32d1f527ad170a0c46ad (diff) | |
| download | platform_external_parameter-framework-2191360f6c25eb140e6cb1085a24f9ff9a18d9c3.tar.gz platform_external_parameter-framework-2191360f6c25eb140e6cb1085a24f9ff9a18d9c3.tar.bz2 platform_external_parameter-framework-2191360f6c25eb140e6cb1085a24f9ff9a18d9c3.zip | |
AF_UNIX socket enablement: allow path URI to bind address
remote-process CLI is update to
$ remote-process <hostname:port|path> <command> [args..]
Bug: 130284799
Test: make
Change-Id: I834199e3c4e27be6a727ecc93b7ca18ee44ab824
Signed-off-by: Miguel Gaio <miguel.gaio@renault.com>
| -rw-r--r-- | upstream/remote-process/main.cpp | 110 | ||||
| -rw-r--r-- | upstream/remote-processor/RemoteProcessorServer.cpp | 47 | ||||
| -rw-r--r-- | upstream/schemas/ParameterFrameworkConfiguration.xsd | 2 | ||||
| -rw-r--r-- | upstream/schemas/README.md | 2 | ||||
| -rw-r--r-- | upstream/test/test-platform/main.cpp | 12 |
5 files changed, 141 insertions, 32 deletions
diff --git a/upstream/remote-process/main.cpp b/upstream/remote-process/main.cpp index 00fde23..ad94dc3 100644 --- a/upstream/remote-process/main.cpp +++ b/upstream/remote-process/main.cpp @@ -37,6 +37,7 @@ #include "RequestMessage.h" #include "AnswerMessage.h" #include "Socket.h" +#include "convert.hpp" using namespace std; @@ -73,42 +74,111 @@ bool sendAndDisplayCommand(asio::generic::stream_protocol::socket &socket, return true; } -// hostname port command [argument[s]] +int usage(const std::string &command, const std::string &error) +{ + if (not error.empty()) { + cerr << error << endl; + } + cerr << "Usage: " << endl; + cerr << "Send a single command:" << endl; + cerr << "\t" << command + << " <hostname port|<protocol>://<host:port|port_name>> <command> [argument[s]]" << endl; + + return 1; +} + +// <hostname port|path> command [argument[s]] // or -// hostname port < commands +// <hostname port|path> < commands int main(int argc, char *argv[]) { - // Enough args? - if (argc < 4) { + int commandPos; - cerr << "Missing arguments" << endl; - cerr << "Usage: " << endl; - cerr << "Send a single command:" << endl; - cerr << "\t" << argv[0] << " hostname port command [argument[s]]" << endl; - - return 1; + // Enough args? + if (argc < 3) { + return usage(argv[0], "Missing arguments"); } asio::io_service io_service; - asio::ip::tcp::resolver resolver(io_service); - asio::generic::stream_protocol::socket connectionSocket(io_service); - asio::ip::tcp::socket tcpSocket(io_service); - string host{argv[1]}; - string port{argv[2]}; + bool isInet = false; + string port; + string host; try { - asio::connect(tcpSocket, resolver.resolve(asio::ip::tcp::resolver::query(host, port))); - connectionSocket = std::move(tcpSocket); + // backward compatibility: tcp port only refered by its value + uint16_t testConverter; + if (convertTo({argv[2]}, testConverter)) { + isInet = true; + port = argv[2]; + host = argv[1]; + if (argc <= 3) { + return usage(argv[0], "Missing arguments"); + } + commandPos = 3; + } else { + commandPos = 2; + string endPortArg{argv[1]}; + std::string protocol; + + const std::string tcpProtocol{"tcp"}; + const std::string unixProtocol{"unix"}; + const std::vector<std::string> supportedProtocols{ tcpProtocol, unixProtocol }; + const std::string protocolDelimiter{"://"}; + + size_t protocolDelPos = endPortArg.find(protocolDelimiter); + if (protocolDelPos == std::string::npos) { + return usage(argv[0], "Invalid socket endpoint, missing " + protocolDelimiter); + } + protocol = endPortArg.substr(0, protocolDelPos); + + if (std::find(begin(supportedProtocols), end(supportedProtocols), protocol) == + end(supportedProtocols)) { + return usage(argv[0], "Invalid socket protocol " + protocol); + } + isInet = (endPortArg.find(tcpProtocol) != std::string::npos); + if (isInet) { + size_t portDelPos = endPortArg.find(':', protocolDelPos + protocolDelimiter.size()); + if (portDelPos == std::string::npos) { + return usage(argv[0], "Invalid tcp endpoint" + endPortArg); + } + host = endPortArg.substr(protocolDelPos + protocolDelimiter.size(), + portDelPos - (protocolDelPos + protocolDelimiter.size())); + port = endPortArg.substr(portDelPos + 1); + } else { + port = endPortArg.substr(protocolDelPos + protocolDelimiter.size()); + } + } + if (isInet) { + asio::ip::tcp::resolver resolver(io_service); + asio::ip::tcp::socket tcpSocket(io_service); + + asio::connect(tcpSocket, resolver.resolve(asio::ip::tcp::resolver::query(host, port))); + connectionSocket = std::move(tcpSocket); + } else { + asio::generic::stream_protocol::socket socket(io_service); + asio::generic::stream_protocol::endpoint endpoint = + asio::local::stream_protocol::endpoint(port); + socket.connect(endpoint); + connectionSocket = std::move(socket); + } + } catch (const asio::system_error &e) { - cerr << "Connection to '" << host << ":" << port << "' failed: " << e.what() << endl; + string endpoint; + + if (isInet) { + endpoint = string("tcp://") + host + ":" + port; + } else { /* other supported protocols */ + endpoint = argv[1]; + } + cerr << "Connection to '" << endpoint << "' failed: " << e.what() << endl; return 1; } // Create command message - CRequestMessage requestMessage(argv[3]); + CRequestMessage requestMessage(argv[commandPos]); // Add arguments - for (int arg = 4; arg < argc; arg++) { + for (int arg = commandPos + 1; arg < argc; arg++) { requestMessage.addArgument(argv[arg]); } diff --git a/upstream/remote-processor/RemoteProcessorServer.cpp b/upstream/remote-processor/RemoteProcessorServer.cpp index e28bebe..de7447e 100644 --- a/upstream/remote-processor/RemoteProcessorServer.cpp +++ b/upstream/remote-processor/RemoteProcessorServer.cpp @@ -32,6 +32,7 @@ #include <memory> #include <assert.h> #include <string.h> +#include <unistd.h> #include "RequestMessage.h" #include "AnswerMessage.h" #include "RemoteCommandHandler.h" @@ -58,17 +59,61 @@ bool CRemoteProcessorServer::start(string &error) try { generic::stream_protocol::endpoint endpoint; uint16_t port; + std::string endpointName; + bool isInet; + // For backward compatibility, tcp port referred by its value only if (convertTo(_bindAddress, port)) { + isInet = true; + } else { + // required form is <protocol>://<host:port|port_name> + const std::string tcpProtocol{"tcp"}; + const std::string unixProtocol{"unix"}; + const std::vector<std::string> supportedProtocols{ tcpProtocol, unixProtocol }; + const std::string protocolDel{"://"}; + + size_t protocolDelPos = _bindAddress.find(protocolDel); + if (protocolDelPos == std::string::npos) { + error = "bindaddress " + _bindAddress + " ill formed, missing " + protocolDel; + return false; + } + std::string protocol = _bindAddress.substr(0, protocolDelPos); + + if (std::find(begin(supportedProtocols), end(supportedProtocols), protocol) == + end(supportedProtocols)) { + error = "bindaddress " + _bindAddress + " has invalid protocol " + protocol; + return false; + } + isInet = (_bindAddress.find(tcpProtocol) != std::string::npos); + if (isInet) { + size_t portDelPos = _bindAddress.find(':', protocolDelPos + protocolDel.size()); + if (portDelPos == std::string::npos) { + error = "bindaddress " + _bindAddress + " ill formed, missing " + ":"; + return false; + } + std::string portLiteral{_bindAddress.substr(portDelPos + 1)}; + if (!convertTo(portLiteral, port)) { + error = "bindaddress " + _bindAddress + " port " + portLiteral + " ill formed"; + return false; + } + } else { + endpointName = _bindAddress.substr(protocolDelPos + protocolDel.size()); + } + } + + if (isInet) { endpoint = ip::tcp::endpoint(ip::tcp::v6(), port); } else { - throw std::invalid_argument("unable to convert bind Address: " + _bindAddress); + endpoint = local::stream_protocol::endpoint(endpointName); } _acceptor.open(endpoint.protocol()); if (endpoint.protocol().protocol() == ASIO_OS_DEF(IPPROTO_TCP)) { _acceptor.set_option(ip::tcp::acceptor::reuse_address(true)); + } else if (endpoint.protocol().protocol() == AF_UNSPEC) { + // In case of reuse, remote it first + unlink(endpointName.c_str()); } _acceptor.set_option(socket_base::linger(true, 0)); _acceptor.set_option(socket_base::enable_connection_aborted(true)); diff --git a/upstream/schemas/ParameterFrameworkConfiguration.xsd b/upstream/schemas/ParameterFrameworkConfiguration.xsd index 522b806..6cc97a5 100644 --- a/upstream/schemas/ParameterFrameworkConfiguration.xsd +++ b/upstream/schemas/ParameterFrameworkConfiguration.xsd @@ -33,7 +33,7 @@ <xs:element name="SettingsConfiguration" type="SettingsConfigurationType" minOccurs="0"/> </xs:sequence> <xs:attribute name="SystemClassName" use="required" type="xs:NMTOKEN"/> - <xs:attribute name="ServerPort" use="required" type="xs:positiveInteger"/> + <xs:attribute name="ServerPort" use="required" type="xs:string"/> <xs:attribute name="TuningAllowed" use="required" type="xs:boolean"/> </xs:complexType> </xs:element> diff --git a/upstream/schemas/README.md b/upstream/schemas/README.md index f634d8c..4c1efb1 100644 --- a/upstream/schemas/README.md +++ b/upstream/schemas/README.md @@ -38,7 +38,7 @@ Attributes of `ParameterFrameworkConfiguration` are: - The `SystemClass` name (for consistency check) - `TuningAllowed` (whether the parameter-framework listens for commands) -- The `ServerPort` on which the parameter-framework listens if +- The `ServerPort` bind Address (PATH or TCP port) on which the parameter-framework listens if `TuningAllowed=true`. ## SystemClass.xsd diff --git a/upstream/test/test-platform/main.cpp b/upstream/test/test-platform/main.cpp index 58f3d04..f09fcba 100644 --- a/upstream/test/test-platform/main.cpp +++ b/upstream/test/test-platform/main.cpp @@ -45,7 +45,7 @@ static const std::string defaultBindAddress("5001"); static void showUsage() { - cerr << "test-platform [-h|--help] <file path> [port number, default " << defaultBindAddress + cerr << "test-platform [-h|--help] <file path> [bind address, default " << defaultBindAddress << "]" << endl; } @@ -86,16 +86,10 @@ int main(int argc, char *argv[]) auto filePath = options.front(); options.pop_front(); - // Handle optional port number argument + // Handle optional bind address argument auto bindAddress = defaultBindAddress; if (not options.empty()) { - uint16_t portNumber; - if (not convertTo(options.front(), portNumber)) { - showInvalidUsage("Could not convert \"" + options.front() + - "\" to a socket port number."); - return 2; - }; bindAddress = options.front(); options.pop_front(); } @@ -103,7 +97,7 @@ int main(int argc, char *argv[]) // All arguments should have been consumed if (not options.empty()) { showInvalidUsage("Unexpected extra arguments: " + utility::asString(options)); - return 3; + return 2; } string strError; |
