configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/dcm_build_config.h.in
${CMAKE_CURRENT_BINARY_DIR}/dcm_build_config.h)
-configure_file(packaging/device-certificate-manager-tests.manifest.in
- ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager-tests.manifest)
-
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(shared)
-IF(ENABLE_SYSTEMD_SUPPORT)
- SET(DCM_UNIX_SOCKET_PATH "/run/device-certificate-manager.socket")
-ELSE()
- SET(DCM_UNIX_SOCKET_PATH "/tmp/device-certificate-manager.socket")
-ENDIF()
-
+SET(DCM_UNIX_SOCKET_PATH "/run/device-certificate-manager.socket")
add_definitions(-DDCM_UNIX_SOCKET_PATH="${DCM_UNIX_SOCKET_PATH}")
add_subdirectory(dcm-daemon)
dcm_server::dcm_server(boost::asio::io_service& io_service, boost::asio::local::stream_protocol::acceptor&& acceptor) :
fService(io_service),
+ fTimer(io_service),
fAcceptor(std::move(acceptor))
{
BOOST_LOG_FUNCTION();
std::shared_ptr<dcm_session> session;
try {
- session = std::make_shared<dcm_session>(fService, shared_from_this());
+ session = std::make_shared<dcm_session>(fService, fTimer, shared_from_this());
} catch(std::bad_alloc& ex) {
BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Out of memory when trying to allocate new session";
return;
}
BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Start accepting connections";
+ session->start_timer();
fAcceptor.async_accept(session->socket(),
[session, self](boost::system::error_code error_code)
});
}
-std::shared_ptr<asbtract_crypto_backend> dcm_server::crypto_backend() {
+std::shared_ptr<asbtract_crypto_backend> dcm_server::crypto_backend()
+{
std::unique_lock<std::mutex> locker(this->fLock);
return fCryptoBackend;
}
private:
boost::asio::io_service& fService;
+ boost::asio::deadline_timer fTimer;
boost::asio::local::stream_protocol::acceptor fAcceptor;
std::mutex fLock;
std::shared_ptr<asbtract_crypto_backend> fCryptoBackend;
}
#endif
-dcm_session::dcm_session(boost::asio::io_service& io_service, const std::shared_ptr<dcm_server>& server) :
+unsigned int globalSessionCounter = 0;
+
+dcm_session::dcm_session(boost::asio::io_service& io_service, boost::asio::deadline_timer& timer, const std::shared_ptr<dcm_server>& server) :
fService(io_service),
+ fTimer(timer),
fSocket(io_service),
fServer(server)
{
BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Create new session object " << this;
+ globalSessionCounter++;
}
dcm_session::~dcm_session()
int handle = fSocket.native_handle();
BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Accepted connection with socket " << fSocket.native_handle();
- std::string label;
if(verify_privileges(handle)) {
+ stop_timer();
do_receive();
} else {
BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Client privilege check failure. Disconnect";
+ start_timer();
+ }
+}
+
+void dcm_session::start_timer()
+{
+ globalSessionCounter--;
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Number of active connections: " << globalSessionCounter;
+
+ if(globalSessionCounter == 0) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "No active connections, server will be closed after few seconds";
+ fTimer.expires_from_now(boost::posix_time::seconds(10));
+ /* operation_aborted error is returned whenever we cancel the timer or we reset the timer using expires_from_now function */
+ fTimer.async_wait([this](const boost::system::error_code &error) {
+ if(error != boost::asio::error::operation_aborted) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "No active connections, server will be closed";
+ fService.stop();
+ }
+ });
}
}
+void dcm_session::stop_timer()
+{
+ globalSessionCounter++;
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Number of active connections: " << globalSessionCounter;
+
+ fTimer.cancel();
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Timer cancelled";
+}
+
void dcm_session::do_receive() noexcept
{
BOOST_LOG_FUNCTION();
} else {
BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Client disconnected: " << error;
// Connection object will be released by shared ptr
+ start_timer();
}
});
} catch(std::exception& ex) {
} catch(...) {
BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception while trying to read message : " << "unknown";
// Connection object will be released by shared ptr
- }
+ }
}
void dcm_session::decode_message() noexcept
public boost::noncopyable
{
public:
- dcm_session(boost::asio::io_service& io_service, const std::shared_ptr<dcm_server>& server);
+ dcm_session(boost::asio::io_service& io_service, boost::asio::deadline_timer& timer, const std::shared_ptr<dcm_server>& server);
~dcm_session();
void start();
+ void start_timer();
+ void stop_timer();
inline boost::asio::local::stream_protocol::socket& socket() {
return fSocket;
private:
boost::asio::io_service& fService;
+ boost::asio::deadline_timer& fTimer;
boost::asio::local::stream_protocol::socket fSocket;
protobuf_async_message_serialization fSerializer;
protobuf_async_message_deserialization fDeserializer;
+++ /dev/null
-<manifest>
- <request>
- <domain name="_" />
- </request>
-</manifest>
-
-
+++ /dev/null
-<manifest>
- <define>
- <domain name="device-certificate-managert-test" />
- <permit>
- <smack permit="system::use_internet" type="w" />
- </permit>
- <request>
- <smack request="system::use_internet" type="w" />
- </request>
- </define>
- <request>
- <domain name="device-certificate-managert-test" />
- </request>
-</manifest>
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
Source1001: device-certificate-manager.manifest
-Source1002: device-certificate-manager-devel.manifest
BuildRequires: cmake
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(libsystemd-daemon)
%global user_name security_fw
%global group_name security_fw
-%global service_name device-certificate-manager
%global smack_domain_name System
%description
-Device Certificate Manager provides cryptography services
-for the Iotivity framework.
+Device Certificate Manager provides cryptography services for the Iotivity framework.
%package -n device-certificate-manager-devel
Summary: Device Certificate Manager (development)
Requires: device-certificate-manager = %{version}-%{release}
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
+Requires: boost-test
%description -n device-certificate-manager-tests
Internal tests for Device Certificate Manager
%prep
%setup -q
cp -a %{SOURCE1001} .
-cp -a %{SOURCE1002} .
%build
%cmake . -DVERSION=%{version} \
-DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:Release} \
-DSYSTEMD_UNIT_DIR=%{_unitdir} \
- -DSERVICE_NAME=%{service_name} \
-DUSER_NAME=%{user_name} \
-DGROUP_NAME=%{group_name} \
-DSMACK_DOMAIN_NAME=%{smack_domain_name}
%install
%make_install
-%install_service multi-user.target.wants device-certificate-manager.service
-%install_service sockets.target.wants device-certificate-manager-control.socket
+%install_service sockets.target.wants device-certificate-manager.socket
%post
/sbin/ldconfig
systemctl daemon-reload
+systemctl restart device-certificate-manager.socket
systemctl restart device-certificate-manager.service
%preun
if [ $1 = 0 ]; then
# unistall
- systemctl stop device-certificate-manager.service
- systemctl stop device-certificate-manager-control.socket
+ systemctl stop device-certificate-manager.service device-certificate-manager.socket
fi
%postun
fi
%files
-%manifest device-certificate-manager.manifest
+%manifest %{name}.manifest
%license LICENSE
%{_bindir}/device-certificate-managerd
%{_libdir}/libdevice-certificate-manager.so.*
-%{_unitdir}/multi-user.target.wants/device-certificate-manager.service
%{_unitdir}/device-certificate-manager.service
-%{_unitdir}/device-certificate-manager.target
-%{_unitdir}/sockets.target.wants/device-certificate-manager-control.socket
-%{_unitdir}/device-certificate-manager-control.socket
+%{_unitdir}/sockets.target.wants/device-certificate-manager.socket
+%{_unitdir}/device-certificate-manager.socket
-%files -n device-certificate-manager-devel
-%manifest device-certificate-manager-devel.manifest
+%files devel
+%manifest %{name}.manifest
%license LICENSE
%{_libdir}/libdevice-certificate-manager.so
%{_includedir}/device-certificate-manager/*.h
%{_libdir}/pkgconfig/*.pc
-%files -n device-certificate-manager-tests
-%manifest device-certificate-manager-tests.manifest
+%files tests
+%manifest %{name}.manifest
%license LICENSE
%{_bindir}/dcm_example_client
%{_bindir}/dcm_example_capi
${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager.service
@ONLY)
-configure_file(device-certificate-manager-control.socket.in
- ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager-control.socket
+configure_file(device-certificate-manager.socket.in
+ ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager.socket
@ONLY)
IF(NOT ("${SYSTEMD_UNIT_DIR}" STREQUAL ""))
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager.service
- device-certificate-manager.target
- ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager-control.socket
+install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager.service
+ ${CMAKE_CURRENT_BINARY_DIR}/device-certificate-manager.socket
DESTINATION
${SYSTEMD_UNIT_DIR})
+++ /dev/null
-[Socket]
-ListenStream=@DCM_UNIX_SOCKET_PATH@
-SocketMode=0777
-SmackLabelIPIn=*
-SmackLabelIPOut=@
-Service=device-certificate-manager.service
-
-[Unit]
-Wants=device-certificate-manager.target
-Before=device-certificate-manager.target
-
-[Install]
-WantedBy=sockets.target
Type=notify
KillMode=process
TimeoutStopSec=3
-Restart=always
+Restart=on-abnormal
ExecStart=@CMAKE_INSTALL_FULL_BINDIR@/device-certificate-managerd
-Sockets=device-certificate-manager-control.socket
-
-[Install]
-WantedBy=multi-user.target
--- /dev/null
+[Socket]
+ListenStream=@DCM_UNIX_SOCKET_PATH@
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+[Install]
+WantedBy=sockets.target
+++ /dev/null
-[Unit]
-Description=Device Certificate Manager sockets
-DefaultDependencies=true