Commit Diff


commit - 31115dc786d9c7d6e4f7ddac7f71c7c2bea4de4f
commit + 5782b89606c55cee6380a57bde8cc04a98c0f6dc
blob - 08402b8b9e4b3b27cdcb8bf9ae0ee79028b2fd20
blob + c8cbbec19fa59779ba2a58b2ab3a36481399b23d
--- shared/transport.cc
+++ shared/transport.cc
@@ -1,20 +1,72 @@
 /** Wrap libtls for gemini protocol */
 
+#include <error.h>
 #include <transport.h>
-#include <tls.h>
 
 
 namespace vostok
 {
-namespace tls
+namespace transport
 {
+namespace
+{
 
 
+constexpr auto protocols = TLS_PROTOCOL_TLSv1_2 | TLS_PROTOCOL_TLSv1_3;
+
+
+}   // namespace <unnamed>
+
+
 bool init()
 {
-    return tls_init() != -1;
+    if (tls_init() == -1)
+    {
+        error::occurred([=](){error::g_log << "TLS initialization";}, error::no_error_code);
+        return false;
+    }
+
+    return true;
 }
 
 
-}   // namespace tls
+void create_gemini_server_ctx(context_t &ret_ctx)
+{
+    std::unique_ptr<struct tls_config, decltype(&tls_config_free)> config{tls_config_new(), tls_config_free};
+    if (!config)
+    {
+        error::occurred([=](){error::g_log << "Create TLS configuration";}, error::no_error_code);
+        return;
+    }
+
+    if (tls_config_set_protocols(config.get(), protocols) == -1)
+    {
+        error::occurred(
+            [=](){error::g_log << "Allow TLS 1.2 and TLS 1.3 protocols";},
+            error::no_error_code
+        );
+        return;
+    }
+
+    std::unique_ptr<struct tls, decltype(&tls_free)> ctx{tls_server(), tls_free};
+    if (!ctx)
+    {
+        error::occurred([=](){error::g_log << "Create TLS server context";}, [](){});
+        return;
+    }
+
+    if (tls_configure(ctx.get(), config.get()) == -1)
+    {
+        auto config_error = tls_config_error(config.get());
+        error::occurred(
+            [=](){error::g_log << "Configure TLS context";},
+            [=](){if (config_error) error::g_log << "Error: " << config_error << std::endl;}
+        );
+        return;
+    }
+
+    ctx.swap(ret_ctx);
+}
+
+}   // namespace transport
 }   // namespace vostok
blob - /dev/null
blob + 4991b214435143b06a885cc1ce776bb84fdd5b9b (mode 644)
--- /dev/null
+++ shared/error.cc
@@ -0,0 +1,16 @@
+/** Errors handling */
+
+#include <iostream>
+#include "error.h"
+
+
+namespace vostok
+{
+namespace error
+{
+
+std::ostream &g_log = std::cerr;
+
+
+}   // namespace error
+}   // namespace vostok
blob - 13e80fedbd96e3db9c53a209857df238e68df2c1
blob + 9e0cb968e5e632e339c5f3c9779a6aa590738478
--- shared/transport.h
+++ shared/transport.h
@@ -1,17 +1,27 @@
 /** Wrap libtls for gemini protocol */
 
+#include <tls.h>
+
+
 #pragma once
 
 
 namespace vostok
 {
-namespace tls
+namespace transport
 {
 
+/** `struct tls *` smart pointer */
+typedef std::unique_ptr<struct tls, decltype(&tls_free)> context_t;
 
+
 /** Per-process initialization */
 bool init();
 
 
-}   // namespace tls
+/* Create new TLS context for gemini server */
+void create_gemini_server_ctx(context_t &ctx);
+
+
+}   // namespace transport
 }   // namespace vostok
blob - /dev/null
blob + 9ed7869c985ffbc4cdcb7cd8fd6fb2a5a35a70e6 (mode 644)
--- /dev/null
+++ shared/error.h
@@ -0,0 +1,66 @@
+/** Errors handling */
+
+#include <errno.h>
+#include <string.h>
+#include <ostream>
+
+#pragma once
+
+
+namespace vostok
+{
+namespace error
+{
+
+
+/** Current output log stream (`std::err` on starup) */
+extern std::ostream &g_log;
+
+
+/** Default error code (errno) printer */
+struct print
+{
+    const int m_error;
+    explicit print(int error=errno) : m_error{error} {}
+    void operator() () const
+    {
+        g_log << "Error code: " << std::dec << m_error << ". " << strerror(m_error) << std::endl;
+    }
+};
+
+
+/** Empty error code printer */
+inline void no_error_code() {}
+
+
+/** Error handler: print action, print error, return `false` */
+template<
+    typename TPrintAction,
+    typename TPrintError
+>
+void
+occurred(
+    TPrintAction print_action,
+    TPrintError print_error
+)
+{
+    print_action();
+    g_log << " failed." << std::endl;
+    print_error();
+}
+
+
+/** Simple error handler: print action by name, print error by errno value, return `false` */
+inline
+void
+occurred(
+    const char *action,
+    const int error_code = errno
+)
+{
+    occurred([=](){g_log << action;}, print{error_code});
+}
+
+
+}   // namespace error
+}   // namespace vostok
blob - 42d0c810ae05a9ce11476bd3c6202c1a3bbf26e4
blob + 64554e180128260bb82d834022c434656af21e79
--- vostokd/Makefile
+++ vostokd/Makefile
@@ -1,11 +1,13 @@
 CXXFLAGS	= -Wall -Wextra -std=c++11
 CXXFLAGS	+= -I${.CURDIR}/../shared -I${.CURDIR}/../3party
 CXXFLAGS	+= -ltls
+
 CXXFILES	= vostokd.cc
 HXXFILES	= 
-
 CXXFILES	+= ${.PATH}../shared/transport.cc
 HXXFILES	+= ${.PATH}../shared/transport.h
+CXXFILES	+= ${.PATH}../shared/error.cc
+HXXFILES	+= ${.PATH}../shared/error.h
 
 vostokd: ${CXXFILES} ${HXXFILES}
 	${CXX} ${CXXFLAGS} ${CXXFILES} -o vostokd
blob - f91bfa178c03316d32c9f17acadb3596aac89367
blob + 60ba39c8372adbdc579637cb534d9bfefa064def
--- vostokd/vostokd.cc
+++ vostokd/vostokd.cc
@@ -1,20 +1,28 @@
 /* Gemini server */
 
+#include <error.h>
 #include <transport.h>
 
 namespace vostok
 {
 namespace
 {
+
 }   // namespace <unnamed>
 
 
+/** C++ entry point */
 bool
 main()
 {
-    if (!tls::init())
+    if (!transport::init())
         return false;
 
+    transport::context_t ctx{nullptr, tls_free};
+    transport::create_gemini_server_ctx(ctx);
+    if (!ctx)
+        return false;
+
     return true;
 }
 
@@ -25,7 +33,6 @@ extern "C"
 int
 main(int argc, char *argv[])
 {
-    (void)argc;
-    (void)argv;
+    (void)argc; (void)argv;
     return vostok::main() ? 0 : 1;
 }