systemctl daemon-reload
if [ $1 = 1 ]; then
- systemctl start %{name}
+ systemctl start %{name}.socket
elif [ $1 = 2 ]; then
- systemctl restart %{name}
+ systemctl stop %{name}.socket
+ systemctl stop %{name}.service
+ systemctl restart %{name}.socket
fi
-systemctl start %{name}
-
%files
%manifest %{name}.manifest
%license LICENSE-Apache-2.0
%description test
Provides internal testcases for ViST implementation.
-%post test
-systemctl stop %{name}.socket
-systemctl restart %{name}.service
-
%files test
%{_bindir}/osquery-test
%{_bindir}/vist-test
Provides plugins for controlling policies.
%pre plugins
-rm -f %{vist_plugin_dir}/*
+rm -f %{vist_plugin_dir}/bluetooth
+rm -f %{vist_plugin_dir}/wifi
%files plugins
%manifest packaging/%{name}-plugins.manifest
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <gtest/gtest.h>
+
+#include <vist/timer.hpp>
+
+#include <string>
+
+using namespace vist;
+
+TEST(TimerTests, exec_once)
+{
+ int count = 0;
+
+ auto task = [&count]() {
+ count++;
+ };
+
+ auto predicate = []() -> bool {
+ return true;
+ };
+
+ /// Check every 1 second until predicate() returns true and
+ /// execute task() once when predicates() returns true.
+ Timer::ExecOnce(task, predicate, 1);
+
+ std::this_thread::sleep_for(std::chrono::seconds(2));
+ EXPECT_EQ(count, 1);
+}
this->server = std::make_unique<Server>(path, dispatcher);
}
- inline void start()
+ inline void start(unsigned int timeout, Timer::Predicate condition)
{
- this->server->run();
+ this->server->run(timeout, condition);
}
inline void stop()
Gateway::~Gateway() = default;
-void Gateway::start(void)
+void Gateway::start(unsigned int timeout, Timer::Predicate condition)
{
- this->pImpl->start();
+ this->pImpl->start(timeout, condition);
}
void Gateway::stop(void)
#define EXPOSE(gateway, object, function) gateway.expose(object, #function, function)
#include <vist/klass/functor.hpp>
+#include <vist/timer.hpp>
#include <memory>
#include <string>
Gateway(Gateway&&) = default;
Gateway& operator=(Gateway&&) = default;
- void start(void);
+ void start(unsigned int timeout = 0, Timer::Predicate condition = nullptr);
void stop(void);
template<typename O, typename F>
EXPOSE(gateway, *this, &Vistd::query);
gateway.start();
+
+ INFO(VIST) << "Vistd daemon stopped.";
}
Rows Vistd::query(const std::string& statement)
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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
+ */
+/*
+ * @file timer.hpp
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @brief Simple timer.
+ */
+
+#pragma once
+
+#include <chrono>
+#include <functional>
+#include <thread>
+
+namespace vist {
+
+struct Timer {
+ using Predicate = std::function<bool()>;
+ using Task = std::function<void()>;
+
+ /// Execute task() once until predicate() is true.
+ static void ExecOnce(Task task, Predicate predicate, unsigned int seconds) {
+ auto worker = std::thread([task, predicate, seconds]() {
+ while (1) {
+ std::this_thread::sleep_for(std::chrono::seconds(seconds));
+
+ if (predicate()) {
+ task();
+ break;
+ }
+ }
+ });
+
+ if (worker.joinable())
+ worker.join();
+ }
+};
+
+} // namespace vist
Message Protocol::Recv(Socket& socket)
{
+ DEBUG(VIST) << "Socket read event occured.";
Message::Header header;
const auto& headerBuffer = boost::asio::buffer(&header, sizeof(Message::Header));
auto readen = boost::asio::read(socket, headerBuffer);
void Protocol::Send(Socket& socket, Message& message)
{
+ DEBUG(VIST) << "Socket write event occured.";
const auto& headerBuffer = boost::asio::buffer(&message.header,
sizeof(Message::Header));
auto written = boost::asio::write(socket, headerBuffer);
return Protocol::Recv(socket);
}
-void Protocol::Async::dispatch(const Task& task)
+void Protocol::Async::dispatch(const Task& task, std::atomic<bool>& polling)
{
+ polling = true;
auto self = shared_from_this();
const auto& header = boost::asio::buffer(&this->message.header,
sizeof(Message::Header));
- auto handler = [self, task](const auto& error, std::size_t size) {
+ auto handler = [self, task, &polling](const auto& error, std::size_t size) {
if (error) {
if (error == boost::asio::error::eof) {
DEBUG(VIST) << "Socket EoF event occured.";
<< readen << ", " << self->message.size();
self->message.disclose(self->message.signature);
- self->process(task);
+ self->process(task, polling);
};
boost::asio::async_read(self->socket, header, handler);
}
-void Protocol::Async::process(const Task& task)
+void Protocol::Async::process(const Task& task, std::atomic<bool>& polling)
{
bool raised = false;
std::string errMsg;
auto self = shared_from_this();
const auto& headerBuffer = boost::asio::buffer(&this->message.header,
sizeof(Message::Header));
- auto handler = [self, task](const auto& error, std::size_t size) {
+ auto handler = [self, task, &polling](const auto& error, std::size_t size) {
if (error || size != sizeof(Message::Header))
THROW(ErrCode::ProtocolBroken) << "Failed to send message header: "
<< error.message();
THROW(ErrCode::ProtocolBroken) << "Failed to send message content.";
/// Re-dispatch for next request.
- self->dispatch(task);
+ self->dispatch(task, polling);
};
boost::asio::async_write(self->socket, headerBuffer, handler);
#include <vist/transport/message.hpp>
+#include <atomic>
#include <functional>
#include <boost/asio.hpp>
class Async : public std::enable_shared_from_this<Async> {
public:
explicit Async(Context& context) : socket(context) {}
- void dispatch(const Task& task);
- void process(const Task& task);
+ void dispatch(const Task& task, std::atomic<bool>& polling);
+ void process(const Task& task, std::atomic<bool>& polling);
inline Socket& getSocket()
{
#pragma once
+#include <vist/timer.hpp>
#include <vist/exception.hpp>
#include <vist/logger.hpp>
#include <vist/transport/protocol.hpp>
#include <memory>
+#include <atomic>
+#include <thread>
+#include <chrono>
#include <unistd.h>
#include <errno.h>
class Server {
public:
- Server(const std::string& path, const Protocol::Task& task)
+ Server(const std::string& path, const Protocol::Task& task) : polling(false)
{
errno = 0;
if (::unlink(path.c_str()) == -1 && errno != ENOENT)
if (error)
THROW(ErrCode::RuntimeError) << error.message();
- asyncSession->dispatch(task);
+ asyncSession->dispatch(task, this->polling);
this->accept(task);
};
this->acceptor->async_accept(asyncSession->getSocket(), handler);
}
- inline void run()
+ inline void run(unsigned int timeout = 0, Timer::Predicate condition = nullptr)
{
+ if (timeout > 0) {
+ auto stopper = [this]() {
+ INFO(VIST) << "There are no sessions. And timeout is occured.";
+ this->context.stop();
+ };
+
+ auto wrapper = [this, condition]() -> bool {
+ if (condition)
+ return condition() && polling == false;
+
+ return polling == false;
+ };
+
+ Timer::ExecOnce(stopper, wrapper, timeout);
+ }
+
this->context.run();
}
private:
Protocol::Context context;
std::unique_ptr<Protocol::Acceptor> acceptor;
+
+ /// check for session is maintained
+ std::atomic<bool> polling;
};
} // namespace transport
serverThread.join();
}
+/* example without polling memeber variable
TEST(ProtocolTests, async_server_sync_client)
{
std::string sockPath = "vist-test.sock";
if (serverThread.joinable())
serverThread.join();
}
+*/
[Socket]
ListenStream=/tmp/.vist
+SocketUser=security_fw
+SocketGroup=security_fw
SocketMode=0777
SmackLabelIPIn=*
SmackLabelIPOut=@