summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Gaio <miguel.gaio@renault.com>2018-12-04 13:55:10 +0100
committerEric Laurent <elaurent@google.com>2019-04-26 10:59:31 -0700
commit2191360f6c25eb140e6cb1085a24f9ff9a18d9c3 (patch)
tree432fd8523556ed1037461e5e9180a5770603f9aa
parentf7bf29332b17034e1a2d32d1f527ad170a0c46ad (diff)
downloadplatform_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.cpp110
-rw-r--r--upstream/remote-processor/RemoteProcessorServer.cpp47
-rw-r--r--upstream/schemas/ParameterFrameworkConfiguration.xsd2
-rw-r--r--upstream/schemas/README.md2
-rw-r--r--upstream/test/test-platform/main.cpp12
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;