Merge branch 'master' of ssh://askele.com/libsntl

Conflicts:
	configure.ac
v0.5.xx
Eugen Tarasov 9 years ago
commit e8c65d39ba

7
.gitignore vendored

@ -45,3 +45,10 @@ debian/tmp
debian/libsntl-dev/
debian/libsntl/
debian/source/
aclocal
coq
*.log
*.crt
lib/libsntllv2.pc
lv2sd
lv2sc

@ -8,7 +8,13 @@ else
EXAMPLES =
endif
SUBDIRS = include lib $(EXAMPLES)
if BUILD_TESTS
TESTS = tests
else
TESTS =
endif
SUBDIRS = include lib man $(EXAMPLES) $(TESTS)
libsntldocdir = ${prefix}/doc/libsntl
libsntldoc_DATA = \

@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(libsntl, 0.2.1)
AC_INIT(libsntl, 0.3.0)
AC_CONFIG_MACRO_DIR(['/tmp/aclocal'])
@ -10,8 +10,6 @@ AM_INIT_AUTOMAKE([1.11])
AM_SILENT_RULES([yes])
CC=${CC-/opt/windows_64/bin/x86_64-w64-mingw32-g++.exe}
AC_PROG_CC
LT_INIT
@ -31,7 +29,6 @@ AM_CONDITIONAL(BUILD_EXAMPLES, test "x$enable_build_examples" = "xyes")
AC_DEFINE([BUILD_WIN32], 1, [build for win32])
dnl PKG_CHECK_MODULES(LIBUUID, [uuid])
PKG_CHECK_MODULES(OPENSSL, [openssl])
@ -47,4 +44,6 @@ Makefile
lib/libsntl.pc
lib/Makefile
include/Makefile
examples/Makefile])
man/Makefile
examples/Makefile
tests/Makefile])

10
debian/changelog vendored

@ -1,3 +1,13 @@
libsntl (0.3.0) stable; urgency=high
* New improved architecture
* Performance tricks
* Long messages
* Extended API
* It's incompatible with 0.2.xx and below by protocol
-- Alexander Vdolainen <vdo@askele.com> Thu, 16 Jul 2015 22:50:32 +0200
libsntl (0.2.1) stable; urgency=low
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>

4
debian/control vendored

@ -12,12 +12,12 @@ Package: libsntl-dev
Section: libdevel
Architecture: any
Depends: libsntl (= ${binary:Version}), libsexpr-dev, libssl-dev, libtdata-dev, uuid-dev
Description: Development files for libsntl
Description: Development files for libsntl (sntllv2)
Development files for sntl library
Package: libsntl
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libsexpr (>= 1.3.1), libssl1.0.0, libtdata (>= 0.2.2), libuuid1
Description: Secure Networking Transport Layer implementation library
Description: Secure Networking Transport Layer v2 implementation library
Library used to develop secure services

@ -1,47 +0,0 @@
#! /bin/sh -e
# /usr/lib/emacsen-common/packages/install/libsntl
# Written by Jim Van Zandt <jrv@debian.org>, borrowing heavily
# from the install scripts for gettext by Santiago Vila
# <sanvila@ctv.es> and octave by Dirk Eddelbuettel <edd@debian.org>.
FLAVOR=$1
PACKAGE=libsntl
if [ ${FLAVOR} = emacs ]; then exit 0; fi
echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR}
#FLAVORTEST=`echo $FLAVOR | cut -c-6`
#if [ ${FLAVORTEST} = xemacs ] ; then
# SITEFLAG="-no-site-file"
#else
# SITEFLAG="--no-site-file"
#fi
FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile"
ELDIR=/usr/share/emacs/site-lisp/${PACKAGE}
ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE}
ELRELDIR=../../../emacs/site-lisp/${PACKAGE}
# Install-info-altdir does not actually exist.
# Maybe somebody will write it.
if test -x /usr/sbin/install-info-altdir; then
echo install/${PACKAGE}: install Info links for ${FLAVOR}
install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/share/info/${PACKAGE}.info.gz
fi
install -m 755 -d ${ELCDIR}
cd ${ELDIR}
FILES=`echo *.el`
cd ${ELCDIR}
ln -sf ${ELRELDIR}/*.el .
cat << EOF > path.el
(debian-pkg-add-load-path-item ".")
(setq byte-compile-warnings nil)
EOF
${FLAVOR} ${FLAGS} ${FILES}
rm -f path.el
exit 0

@ -1,15 +0,0 @@
#!/bin/sh -e
# /usr/lib/emacsen-common/packages/remove/libsntl
FLAVOR=$1
PACKAGE=libsntl
if [ ${FLAVOR} != emacs ]; then
if test -x /usr/sbin/install-info-altdir; then
echo remove/${PACKAGE}: removing Info links for ${FLAVOR}
install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/share/info/libsntl.info.gz
fi
echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR}
rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE}
fi

@ -1,27 +0,0 @@
;; -*-emacs-lisp-*-
;;
;; Emacs startup file, e.g. /etc/emacs/site-start.d/50libsntl.el
;; for the Debian libsntl package
;;
;; Originally contributed by Nils Naumann <naumann@unileoben.ac.at>
;; Modified by Dirk Eddelbuettel <edd@debian.org>
;; Adapted for dh-make by Jim Van Zandt <jrv@debian.org>
;; The libsntl package follows the Debian/GNU Linux 'emacsen' policy and
;; byte-compiles its elisp files for each 'emacs flavor' (emacs19,
;; xemacs19, emacs20, xemacs20...). The compiled code is then
;; installed in a subdirectory of the respective site-lisp directory.
;; We have to add this to the load-path:
(let ((package-dir (concat "/usr/share/"
(symbol-name debian-emacs-flavor)
"/site-lisp/libsntl")))
;; If package-dir does not exist, the libsntl package must have
;; removed but not purged, and we should skip the setup.
(when (file-directory-p package-dir)
(if (fboundp 'debian-pkg-add-load-path-item)
(debian-pkg-add-load-path-item package-dir)
(setq load-path (cons package-dir load-path)))
(autoload 'libsntl-mode "libsntl-mode"
"Major mode for editing libsntl files." t)
(add-to-list 'auto-mode-alist '("\\.libsntl$" . libsntl-mode))))

4
debian/files vendored

@ -1,2 +1,2 @@
libsntl-dev_0.2.1_amd64.deb libdevel extra
libsntl_0.2.1_amd64.deb libs extra
libsntl-dev_0.3.0_amd64.deb libdevel extra
libsntl_0.3.0_amd64.deb libs extra

@ -1,2 +1,4 @@
usr/lib
usr/include
usr/share/man
usr/share/man/man3

@ -2,3 +2,4 @@ usr/include/*
usr/lib/lib*.a
usr/lib/lib*.so
usr/lib/pkgconfig/*
usr/share/man/man3/*

@ -0,0 +1,10 @@
man/sxmsg_rreply.3
man/connections_create.3
man/connections_destroy.3
man/connections_free.3
man/connections_init.3
man/sntl_init.3
man/connections_setsslserts.3
man/connections_set_priv.3
man/connections_get_priv.3
man/connections_set_ondestroy.3

@ -1,2 +1,2 @@
shlibs:Depends=libc6 (>= 2.3.2), libsexpr, libssl1.0.0 (>= 1.0.1), libtdata, libuuid1 (>= 2.20.1)
shlibs:Depends=libc6 (>= 2.2.5), libsexpr, libssl1.0.0 (>= 1.0.1), libtdata, libuuid1 (>= 2.20.1)
misc:Depends=

@ -1,56 +0,0 @@
.\" Hey, EMACS: -*- nroff -*-
.\" (C) Copyright 2014 Alexander Vdolainen <vdo@daze>,
.\"
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH LIBSNTL SECTION "November 24, 2014"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
libsntl \- program to do something
.SH SYNOPSIS
.B libsntl
.RI [ options ] " files" ...
.br
.B bar
.RI [ options ] " files" ...
.SH DESCRIPTION
This manual page documents briefly the
.B libsntl
and
.B bar
commands.
.PP
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
.\" respectively.
\fBlibsntl\fP is a program that...
.SH OPTIONS
These programs follow the usual GNU command line syntax, with long
options starting with two dashes (`-').
A summary of options is included below.
For a complete description, see the Info files.
.TP
.B \-h, \-\-help
Show summary of options.
.TP
.B \-v, \-\-version
Show version of program.
.SH SEE ALSO
.BR bar (1),
.BR baz (1).
.br
The programs are documented fully by
.IR "The Rise and Fall of a Fooish Bar" ,
available via the Info system.

@ -1,154 +0,0 @@
<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
<!-- Process this file with docbook-to-man to generate an nroff manual
page: `docbook-to-man manpage.sgml > manpage.1'. You may view
the manual page with: `docbook-to-man manpage.sgml | nroff -man |
less'. A typical entry in a Makefile or Makefile.am is:
manpage.1: manpage.sgml
docbook-to-man $< > $@
The docbook-to-man binary is found in the docbook-to-man package.
Please remember that if you create the nroff version in one of the
debian/rules file targets (such as build), you will need to include
docbook-to-man in your Build-Depends control field.
-->
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
<!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
<!ENTITY dhsurname "<surname>SURNAME</surname>">
<!-- Please adjust the date whenever revising the manpage. -->
<!ENTITY dhdate "<date>November 24, 2014</date>">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1). -->
<!ENTITY dhsection "<manvolnum>SECTION</manvolnum>">
<!ENTITY dhemail "<email>vdo@daze</email>">
<!ENTITY dhusername "Alexander Vdolainen">
<!ENTITY dhucpackage "<refentrytitle>LIBSEXPR</refentrytitle>">
<!ENTITY dhpackage "libsntl">
<!ENTITY debian "<productname>Debian</productname>">
<!ENTITY gnu "<acronym>GNU</acronym>">
<!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
]>
<refentry>
<refentryinfo>
<address>
&dhemail;
</address>
<author>
&dhfirstname;
&dhsurname;
</author>
<copyright>
<year>2003</year>
<holder>&dhusername;</holder>
</copyright>
&dhdate;
</refentryinfo>
<refmeta>
&dhucpackage;
&dhsection;
</refmeta>
<refnamediv>
<refname>&dhpackage;</refname>
<refpurpose>program to do something</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&dhpackage;</command>
<arg><option>-e <replaceable>this</replaceable></option></arg>
<arg><option>--example <replaceable>that</replaceable></option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>This manual page documents briefly the
<command>&dhpackage;</command> and <command>bar</command>
commands.</para>
<para>This manual page was written for the &debian; distribution
because the original program does not have a manual page.
Instead, it has documentation in the &gnu;
<application>Info</application> format; see below.</para>
<para><command>&dhpackage;</command> is a program that...</para>
</refsect1>
<refsect1>
<title>OPTIONS</title>
<para>These programs follow the usual &gnu; command line syntax,
with long options starting with two dashes (`-'). A summary of
options is included below. For a complete description, see the
<application>Info</application> files.</para>
<variablelist>
<varlistentry>
<term><option>-h</option>
<option>--help</option>
</term>
<listitem>
<para>Show summary of options.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option>
<option>--version</option>
</term>
<listitem>
<para>Show version of program.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>SEE ALSO</title>
<para>bar (1), baz (1).</para>
<para>The programs are documented fully by <citetitle>The Rise and
Fall of a Fooish Bar</citetitle> available via the
<application>Info</application> system.</para>
</refsect1>
<refsect1>
<title>AUTHOR</title>
<para>This manual page was written by &dhusername; &dhemail; for
the &debian; system (and may be used by others). Permission is
granted to copy, distribute and/or modify this document under
the terms of the &gnu; General Public License, Version 2 any
later version published by the Free Software Foundation.
</para>
<para>
On Debian systems, the complete text of the GNU General Public
License can be found in /usr/share/common-licenses/GPL.
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->

@ -1,291 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!--
`xsltproc -''-nonet \
-''-param man.charmap.use.subset "0" \
-''-param make.year.ranges "1" \
-''-param make.single.year.ranges "1" \
/usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl \
manpage.xml'
A manual page <package>.<section> will be generated. You may view the
manual page with: nroff -man <package>.<section> | less'. A typical entry
in a Makefile or Makefile.am is:
DB2MAN = /usr/share/sgml/docbook/stylesheet/xsl/docbook-xsl/manpages/docbook.xsl
XP = xsltproc -''-nonet -''-param man.charmap.use.subset "0"
manpage.1: manpage.xml
$(XP) $(DB2MAN) $<
The xsltproc binary is found in the xsltproc package. The XSL files are in
docbook-xsl. A description of the parameters you can use can be found in the
docbook-xsl-doc-* packages. Please remember that if you create the nroff
version in one of the debian/rules file targets (such as build), you will need
to include xsltproc and docbook-xsl in your Build-Depends control field.
Alternatively use the xmlto command/package. That will also automatically
pull in xsltproc and docbook-xsl.
Notes for using docbook2x: docbook2x-man does not automatically create the
AUTHOR(S) and COPYRIGHT sections. In this case, please add them manually as
<refsect1> ... </refsect1>.
To disable the automatic creation of the AUTHOR(S) and COPYRIGHT sections
read /usr/share/doc/docbook-xsl/doc/manpages/authors.html. This file can be
found in the docbook-xsl-doc-html package.
Validation can be done using: `xmllint -''-noout -''-valid manpage.xml`
General documentation about man-pages and man-page-formatting:
man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
-->
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
<!ENTITY dhfirstname "FIRSTNAME">
<!ENTITY dhsurname "SURNAME">
<!-- dhusername could also be set to "&dhfirstname; &dhsurname;". -->
<!ENTITY dhusername "Alexander Vdolainen">
<!ENTITY dhemail "vdo@daze">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1) and
http://www.tldp.org/HOWTO/Man-Page/q2.html. -->
<!ENTITY dhsection "SECTION">
<!-- TITLE should be something like "User commands" or similar (see
http://www.tldp.org/HOWTO/Man-Page/q2.html). -->
<!ENTITY dhtitle "libsntl User Manual">
<!ENTITY dhucpackage "LIBSEXPR">
<!ENTITY dhpackage "libsntl">
]>
<refentry>
<refentryinfo>
<title>&dhtitle;</title>
<productname>&dhpackage;</productname>
<authorgroup>
<author>
<firstname>&dhfirstname;</firstname>
<surname>&dhsurname;</surname>
<contrib>Wrote this manpage for the Debian system.</contrib>
<address>
<email>&dhemail;</email>
</address>
</author>
</authorgroup>
<copyright>
<year>2007</year>
<holder>&dhusername;</holder>
</copyright>
<legalnotice>
<para>This manual page was written for the Debian system
(and may be used by others).</para>
<para>Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License,
Version 2 or (at your option) any later version published by
the Free Software Foundation.</para>
<para>On Debian systems, the complete text of the GNU General Public
License can be found in
<filename>/usr/share/common-licenses/GPL</filename>.</para>
</legalnotice>
</refentryinfo>
<refmeta>
<refentrytitle>&dhucpackage;</refentrytitle>
<manvolnum>&dhsection;</manvolnum>
</refmeta>
<refnamediv>
<refname>&dhpackage;</refname>
<refpurpose>program to do something</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&dhpackage;</command>
<!-- These are several examples, how syntaxes could look -->
<arg choice="plain"><option>-e <replaceable>this</replaceable></option></arg>
<arg choice="opt"><option>--example=<parameter>that</parameter></option></arg>
<arg choice="opt">
<group choice="req">
<arg choice="plain"><option>-e</option></arg>
<arg choice="plain"><option>--example</option></arg>
</group>
<replaceable class="option">this</replaceable>
</arg>
<arg choice="opt">
<group choice="req">
<arg choice="plain"><option>-e</option></arg>
<arg choice="plain"><option>--example</option></arg>
</group>
<group choice="req">
<arg choice="plain"><replaceable>this</replaceable></arg>
<arg choice="plain"><replaceable>that</replaceable></arg>
</group>
</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>&dhpackage;</command>
<!-- Normally the help and version options make the programs stop
right after outputting the requested information. -->
<group choice="opt">
<arg choice="plain">
<group choice="req">
<arg choice="plain"><option>-h</option></arg>
<arg choice="plain"><option>--help</option></arg>
</group>
</arg>
<arg choice="plain">
<group choice="req">
<arg choice="plain"><option>-v</option></arg>
<arg choice="plain"><option>--version</option></arg>
</group>
</arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id="description">
<title>DESCRIPTION</title>
<para>This manual page documents briefly the
<command>&dhpackage;</command> and <command>bar</command>
commands.</para>
<para>This manual page was written for the Debian distribution
because the original program does not have a manual page.
Instead, it has documentation in the GNU <citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> format; see below.</para>
<para><command>&dhpackage;</command> is a program that...</para>
</refsect1>
<refsect1 id="options">
<title>OPTIONS</title>
<para>The program follows the usual GNU command line syntax,
with long options starting with two dashes (`-'). A summary of
options is included below. For a complete description, see the
<citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> files.</para>
<variablelist>
<!-- Use the variablelist.term.separator and the
variablelist.term.break.after parameters to
control the term elements. -->
<varlistentry>
<term><option>-e <replaceable>this</replaceable></option></term>
<term><option>--example=<replaceable>that</replaceable></option></term>
<listitem>
<para>Does this and that.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-h</option></term>
<term><option>--help</option></term>
<listitem>
<para>Show summary of options.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option></term>
<term><option>--version</option></term>
<listitem>
<para>Show version of program.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="files">
<title>FILES</title>
<variablelist>
<varlistentry>
<term><filename>/etc/foo.conf</filename></term>
<listitem>
<para>The system-wide configuration file to control the
behaviour of <application>&dhpackage;</application>. See
<citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for further details.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>${HOME}/.foo.conf</filename></term>
<listitem>
<para>The per-user configuration file to control the
behaviour of <application>&dhpackage;</application>. See
<citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for further details.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="environment">
<title>ENVIRONMENT</title>
<variablelist>
<varlistentry>
<term><envar>FOO_CONF</envar></term>
<listitem>
<para>If used, the defined file is used as configuration
file (see also <xref linkend="files"/>).</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="diagnostics">
<title>DIAGNOSTICS</title>
<para>The following diagnostics may be issued
on <filename class="devicefile">stderr</filename>:</para>
<variablelist>
<varlistentry>
<term><errortext>Bad configuration file. Exiting.</errortext></term>
<listitem>
<para>The configuration file seems to contain a broken configuration
line. Use the <option>--verbose</option> option, to get more info.
</para>
</listitem>
</varlistentry>
</variablelist>
<para><command>&dhpackage;</command> provides some return codes, that can
be used in scripts:</para>
<segmentedlist>
<segtitle>Code</segtitle>
<segtitle>Diagnostic</segtitle>
<seglistitem>
<seg><errorcode>0</errorcode></seg>
<seg>Program exited successfully.</seg>
</seglistitem>
<seglistitem>
<seg><errorcode>1</errorcode></seg>
<seg>The configuration file seems to be broken.</seg>
</seglistitem>
</segmentedlist>
</refsect1>
<refsect1 id="bugs">
<!-- Or use this section to tell about upstream BTS. -->
<title>BUGS</title>
<para>The program is currently limited to only work
with the <package>foobar</package> library.</para>
<para>The upstreams <acronym>BTS</acronym> can be found
at <ulink url="http://bugzilla.foo.tld"/>.</para>
</refsect1>
<refsect1 id="see_also">
<title>SEE ALSO</title>
<!-- In alpabetical order. -->
<para><citerefentry>
<refentrytitle>bar</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>, <citerefentry>
<refentrytitle>baz</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>, <citerefentry>
<refentrytitle>foo.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry></para>
<para>The programs are documented fully by <citetitle>The Rise and
Fall of a Fooish Bar</citetitle> available via the <citerefentry>
<refentrytitle>info</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> system.</para>
</refsect1>
</refentry>

2
debian/menu.ex vendored

@ -1,2 +0,0 @@
?package(libsntl):needs="X11|text|vc|wm" section="Applications/see-menu-manual"\
title="libsntl" command="/usr/bin/libsntl"

@ -1 +1 @@
libsntl 0.2.0 libsntl (>> 0.2.0), libsntl (<< 0.2.99)
libsntl 0.3.0 libsntl (>> 0.3.0), libsntl (<< 0.3.99)

@ -1 +1 @@
nobase_include_HEADERS = sntl/pth_queue.h sntl/connection.h
nobase_include_HEADERS = sntl/sntllv2.h sntl/errno.h sntl/limits.h

@ -1,312 +0,0 @@
/*
* File: connection.h
* Author: vdo
*
* Created on September 24, 2014, 2:36 AM
*/
#ifndef __ESXC_CONNECTION_H_
#define __ESXC_CONNECTION_H_
#include <stdint.h>
#include <time.h>
#include <sys/types.h>
#include <pthread.h>
#include <openssl/ssl.h>
#include <tdata/usrtc.h>
#include <tdata/idx_allocator.h>
#include <sexpr/sexp.h>
#include <sexpr/faststack.h>
#include <sntl/pth_queue.h>
/* error codes */
#define ESXOREPLYREQ 44 /* protocol require reply with expression,
* or expression return for the request */
#define ESXOTIMEDOUT 45 /* timedout */
#define ESXRCBADPROT 46 /* invalid protocol */
#define ESXNOCONNECT 47 /* connection is lost */
#define ESXNOCHANSUP 48
#define ESXRAPIDREPLY 49
#define VERIFY_DEPTH 1 /* FIXME: */
#define MAX_CONNECTIONS 32768
#define MAX_CHANNELS 4096
#define MAX_RPC_LIST 2048
#define MAX_MULTI 12
#define MAX_PENDINGMSG 16384
#define MAX_MSGINDEX ((MAX_PENDINGMSG) * (MAX_MULTI))
typedef struct __perm_context_type {
char *login;
char *passwd;
ulong_t certid;
ulong_t uid;
ulong_t gid;
ulong_t *gids;
int n_gids;
int p_attr;
struct in_addr *addr;
void *priv;
} perm_ctx_t;
#define CXCONN_MASTER (1 << 1)
#define CXCONN_SLAVE (1 << 2)
#define CXCONN_ESTABL (1 << 3)
#define CXCONN_BROKEN (1 << 4)
struct __connections_subsys_type;
/*
* älä jätä kommentteja omalla kielellä! yksinkertaisia englanti sijaan!
* i found somebody who write comments and messages in non-english,
* itäs a fucking practice - forget it.
*/
typedef struct __connection_t {
struct __connections_subsys_type *ssys; /* < connections subsystem */
char *uuid; /** < uuid of the connection */
idx_allocator_t *idx_ch; /** < index allocation for channels */
usrtc_t *chnl_tree; /** < search tree of all channels */
usrtc_t *rpc_list; /** < search tree of possible RPC typed lists */
SSL_CTX *ctx; /** < SSL context */
SSL *ssl; /** < SSL connection */
int ssl_data_index; /** < SSL index for the custom data */
perm_ctx_t *pctx; /** < higher layer authentification context */
pthread_t cthread; /** < thread for listening the connection socket */
pthread_t rmsgthread; /** < thread for message queue (1) */
pthread_t msgthread; /** < thread for message queue (2) */
pth_queue_t *mqueue; /** < message queue (2) */
pth_queue_t *rqueue; /** < message queue (1) */
pth_dqtpoll_t *tpoll; /** < thread poll for rpc requests */
pthread_mutex_t oplock; /** < mutex used to sync operations on connection */
pthread_rwlock_t chnl_lock; /** < rwlock used to sync ops with channels */
int flags; /** < flags of the connection */
usrtc_node_t csnode; /** < node to store the connection within list */
} conn_t;
struct __connection_rpc_list_type;
struct __message_t;
#define ESXCHAN_PENDING (1 << 1)
#define ESXCHAN_CLOSURE (1 << 2)
typedef struct __channel_t {
ulong_t cid; /** < ID of the channel */
char *uuid; /** < UUID of the channel, used in advanced implementation
* of the complex distributed systems */
conn_t *connection; /** < pointer to the parent connection */
idx_allocator_t *idx_msg; /** < index allocation for messages */
usrtc_t *msgs_tree; /** < search tree of the existing messages */
struct __message_t *sysmsg; /** < system message used to operate with channel */
struct __connection_rpc_list_type *rpc_list; /** < rpc functions list */
pthread_mutex_t oplock; /** < operation ops lock */
pthread_rwlock_t msglock; /** < rwlock used to operate with messages */
usrtc_node_t node; /** < node for connection search tree */
int use_count; /** < use count */
int flags; /** < flags of the channel */
} chnl_t;
typedef struct __sexp_payload_t {
char *cstr;
sexp_t *sx;
} sxpayload_t;
#define ESX_SYSMSG_SIZE 512
#define ESXMSG_SYS (1 << 1)
#define ESXMSG_USR (1 << 2)
#define ESXMSG_PENDING (1 << 3)
#define ESXMSG_NOWAY (1 << 4)
#define ESXMSG_TIMEDOUT (1 << 5)
#define ESXMSG_PULSE (1 << 6) /* obsolete flag */
#define ESXMSG_NOWAIT (1 << 7)
#define ESXMSG_ISREPLY (1 << 8)
#define ESXMSG_CLOSURE (1 << 9)
#define ESXMSG_RMONRETR (1 << 10)
#define ESXMSG_KILLTHRD (1 << 11)
#define ESXMSG_ISRAPID (1 << 12)
/**
* \brief Message used in sntl message passing
*
* This structure used to manage a message within a channel
* of the sntl structure stack.
*/
typedef struct __message_t {
chnl_t *pch; /** < channel of the message(if applicable) */
ulong_t mid; /** < unique ID within connection context */
char *uuid; /** < UUID of the message, used for special messages */
usrtc_node_t pendingq_node; /** < node for the pending queue */
pthread_mutex_t wait; /** < special wait mutex, used for sync */
void *payload; /** < payload */
sexp_t *initial_sx;
int opcode; /** < opcode for system and pulse messages */
int flags; /** < flags of the message (type, state etc ...)*/
int use_count; /** < use count */
} sxmsg_t;
typedef struct __connection_rpc_entry_type {
char *name;
int (*rpcf)(void *, sexp_t *);
usrtc_node_t node;
} cx_rpc_t;
typedef struct __connection_rpc_list_type {
usrtc_t *rpc_tree; /** < search tree for the rpc lookup */
char *opt_version; /** < reserved for future implementations */
} cx_rpc_list_t;
/**
* \brief Connection subsystem structure.
*
* This structure used for management and control a set of a
* determined connections with the same RPC lists and the same
* mode (server, client).
*
*/
typedef struct __connections_subsys_type {
usrtc_t *connections;
pth_queue_t *ioq; /** < general messages queue */
pth_queue_t *ioqueue; /** < system messages queue */
/* system threads */
pthread_t iog_thread; /** < general io queue */
pthread_t ios_thread; /** < system io queue */
pthread_rwlock_t rwlock;
char *rootca, *certpem, *certkey; /* path name to the certificates */
cx_rpc_list_t *system_rpc;
/* special functions pointers */
int (*validate_sslpem)(conn_t *); /** < this function used to validate SSL certificate while SSL handshake */
int (*secure_check)(conn_t *); /** < this function authorize user to login,
* and also should check SSL cert and user, and already made sessions */
usrtc_t* (*get_rpc_typed_list_tree)(conn_t *); /** < this function is used to set RPC list of the functions */
int (*set_typed_list_callback)(conn_t *, int, char *); /** < this function is a callback
* during setting up a typed channel */
void (*on_destroy)(conn_t *); /** < callback on connection destroy */
void *priv;
} conn_sys_t;
typedef struct __rpc_typed_list_type {
int type_id;
char *description;
cx_rpc_list_t *rpc_list;
usrtc_node_t lnode;
} rpc_typed_list_t;
/* General API */
/* subsystem */
extern conn_sys_t *conn_sys; /* an old obsolete method */
/* old API from 0.1.xx */
#define connections_subsystem_init() { conn_sys = (conn_sys_t *)malloc(sizeof(conn_sys_t)); connections_init(conn_sys); }
#define connections_subsystem_setsslserts(a, b, c) connections_setsslserts(conn_sys, a, b, c)
#define connections_subsystem_setrpclist_function(a) connections_setrpclist_function(conn_sys, a)
#define connections_set_priv(c, p) (c)->priv = (void *)p
#define connections_get_priv(c) (c)->priv
#ifdef __cplusplus
extern "C" {
#endif
/** call this function before use sntl related functions */
int sntl_init(void);
/* new */
int connections_init(conn_sys_t *ssys);
int connections_setsslserts(conn_sys_t *ssys, const char *rootca,
const char *certpem, const char *certkey);
int connections_setrpclist_function(conn_sys_t *ssys,
usrtc_t* (*get_rpc_typed_list_tree)(conn_t *));
#ifdef __cplusplus
}
#endif
#define connections_subsystem_set_securecheck(c, fuu) (c)->secure_check = fuu
#define connections_subsystem_set_sslvalidator(c, fuu) (c)->validate_sslpem = fuu
#define connections_subsystem_set_rpctlist_call(c, fuu) (c)->set_typed_list_callback = fuu
#define connections_subsystem_set_on_destroy(c, fuu) (c)->on_destroy = fuu
/* connection - compatibility (old versions) macros */
#define connection_create(c, s) connection_create_fapi((c), (s), NULL)
#define connection_initiate(c, h, p, s, p1) connection_initiate_m(conn_sys, c, h, p, s, p1)
#define connection_create_fapi(c, s, a) connection_create_fapi_m(conn_sys, c, s, a)
#ifdef __cplusplus
extern "C" {
#endif
/* new */
int connection_initiate_m(conn_sys_t *ssys, conn_t *co, const char *host,
int port, const char *SSL_cert, perm_ctx_t *pctx);
int connection_create_fapi_m(conn_sys_t *ssys, conn_t *co, int sck,
struct in_addr *addr);
int connection_close(conn_t *co);
/* channels */
int channel_open(conn_t *co, chnl_t **ch, int type);
int channel_close(chnl_t *chnl);
/* message passing */
int msg_send(chnl_t *ch, sexp_t *sx, sxmsg_t **msg);
int msg_send_timed(chnl_t *ch, sexp_t *sx, sxmsg_t **msg, struct timespec *tio);
int msg_return(sxmsg_t *msg, int opcode);
int msg_reply(sxmsg_t *msg, sexp_t *sx);
int msg_reply_timed(sxmsg_t *msg, sexp_t *sx, struct timespec *tio);
/* reply with S expression without confirmation of delivery and applying */
int msg_reply_rapid(sxmsg_t *msg, sexp_t *sx);
/* this is required to clean the message in case if it's a rapid message */
int msg_rapid_clean(sxmsg_t *msg);
#ifdef __cplusplus
}
#endif
/* additional functions */
#define sntl_msg_get_secctx(m) (m)->pch->connection->pctx
/* RPC List API */
#define SNTL_FILTER_INC 0xa
#define SNTL_FILTER_EXC 0xb
#define SNTL_FILTER_END -1
#ifdef __cplusplus
extern "C" {
#endif
int sntl_rpclist_init(usrtc_t *tree);
int sntl_rpclist_add(usrtc_t *tree, int type, const char *description,
const char *version);
int sntl_rpclist_add_function(usrtc_t *tree, int type, const char *fu_name,
int (*rpcf)(void *, sexp_t *));
int sntl_rpclist_filter(usrtc_t *source, usrtc_t **dest, int flag, int *filter);
#ifdef __cplusplus
}
#endif
/* for DEBUG purposes */
#define __DBGLINE fprintf(stderr, "%s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__)
#endif /* __ESXC_CONNECTION_H_ */

@ -0,0 +1,54 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#ifndef __SNTL_ERRNO_H__
#define __SNTL_ERRNO_H__
#define __SNTL_EPREFIX 200
#define SNE_SUCCESS 200
#define SNE_FAILED 201
#define SNE_ENOMEM 202
#define SNE_BADPROTO 203
#define SNE_ENORPC 204
#define SNE_EPERM 205
#define SNE_TOOLONG 206
#define SNE_EBUSY 207
#define SNE_WOULDBLOCK 208
#define SNE_LINKERROR 209
#define SNE_NOSUCHMSG 210
#define SNE_NOSUCHCHAN 211
#define SNE_ETIMEDOUT 212
#define SNE_IGNORED 213
#define SNE_REPLYREQ 214
#define SNE_RAPIDMSG 215
#define SNE_ESSL 216
#define SNE_NOCHANNELS 217
#define SNE_MCHANNELS 218
#define SNE_MMESSAGES 219
#define SNE_LINKBROKEN 220
#define SNE_INVALINDEX 221
/* some old errors for compatibility */
#define ESXOREPLYREQ SNE_REPLYREQ /* protocol require reply with expression,
* or expression return for the request */
#define ESXOTIMEDOUT SNE_ETIMEDOUT /* timedout */
#define ESXRCBADPROT SNE_BADPROTO /* invalid protocol */
#define ESXNOCONNECT SNE_LINKERROR /* connection is lost */
#define ESXNOCHANSUP SNE_NOSUCHCHAN
#define ESXRAPIDREPLY SNE_RAPIDMSG
const char *sntll_errno2cstr(int);
#endif /* __SNTL_ERRNO_H__ */

@ -0,0 +1,21 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#ifndef __SNTL_LIMITS_H__
#define __SNTL_LIMITS_H__
#define MAX_RPC_LIST 512
#define MAX_RBBUF_LEN (65536 - sizeof(sntllv2_head_t))
#endif /* __SNTL_LIMITS_H__ */

@ -1,117 +0,0 @@
/*
* This is a proprietary software. See COPYING for further details.
*
* (c) 2013 Copyright Askele, inc. <http://askele.com>
* (c) 2013 Copyright Askele Ingria, inc. <http://askele-ingria.com>
* (c) 2014 Copyright Confident, inc. (granted permission to use in commercial software)
*/
/**
* @file pth_queue.h
* @author Alexander Vdolainen
* @date 4 Nov 2013, 20 Dec 2014 (dynamic polls)
* @brief queue implementation for threads intercommunication
*
*/
#ifndef __PTH_QUEUE_H__
#define __PTH_QUEUE_H__
#include <pthread.h>
#include <tdata/idx_allocator.h>
/* possible message types, ones with POLL_ prefix valid on for pth_dqtpoll_* */
#define SYS_MSG 0x0f0affee
#define USR_MSG 0x0afeeffe
#define POLL_DECREASE 0x0afafafe
#define POLL_INCREASE 0x0afaffff
#define NIL_MSG 0x0
#define END_MSG 0xdead0000
/* max amount of threads within the poll */
#define MAX_POLL_VALUE 32
typedef struct pth_msg_s {
void *data; /** < message payload */
unsigned int msgtype; /** < message type ID */
unsigned int qlength; /** < current queue length (actual on add moment),
* it makes no sense with few readers */
usrtc_node_t node;
} pth_msg_t;
typedef struct pth_queue_s {
unsigned int length;
/* sync */
pthread_mutex_t mutex;
pthread_cond_t cond;
/* queue data */
usrtc_t qtree;
/* cache */
usrtc_t msgcache;
} pth_queue_t;
int pth_queue_init(pth_queue_t *queue);
int pth_queue_add(pth_queue_t *queue, void *data, unsigned int msgtype);
int pth_queue_get(pth_queue_t *queue, const struct timespec *timeout,
pth_msg_t *msg);
unsigned int pth_queue_length(pth_queue_t *queue);
int pth_queue_destroy(pth_queue_t *queue, int freedata,
void (*free_msg)(void *));
/* dynamic queue thread poll ... bbrrr .... ok, ok with beer
* Dynamic queue thread poll is a queue like pth_queue,
* but also it has itäs own mamagement for threads - that's
* why dynamic.
* Ideally, the model is trying to achieve the following:
* 1. one thread in queue while no or very small amount of jobs in the queue
* 2. grow until max threads is reached while too many requests
* 3. gently slide down volume of threads after job heat
* 4. minimal additional drawbacks (i hate something periodically running,
* it's bad practice)
* The model is quite simple, we should make spurious wakeups equal to zero,
* if no - decrease poll value, and, if we don't have thread available -
* create it.
*/
typedef struct pth_dqtpoll_s {
pth_queue_t *queue; /** < Job queue */
pthread_t *poll; /** < Thread descriptors */
int (*jobdata_callback)(void *); /** < Callback to have a deal with data */
int flags; /** < Flags */
idx_allocator_t *idx; /** < index allocator for the poll threads */
pthread_rwlock_t stats_lock; /** < rwlock for stats data */
unsigned long spurious_wakeups; /** < amount of spurios wakeups */
int poll_value; /** < value of the poll (totally) */
struct timeval sched_time;
int msgop;
} pth_dqtpoll_t;
/* flags for poll */
#define DQTPOLL_RUNNING (1 << 1) /* poll is running */
#define DQTPOLL_DEADSTAGE (1 << 2) /* poll in the stage of destroy */
/* keep it stupid */
#define DQTPOLL_DELTAMS 500000
#define DQTPOLL_DELTASE 0
/* init poll, structure must be allocated */
int pth_dqtpoll_init(pth_dqtpoll_t*, int (*jobdata_callback)(void *));
/* run poll: poll */
int pth_dqtpoll_run(pth_dqtpoll_t*);
/* add the job to the queue: poll, job data, message type */
int pth_dqtpoll_add(pth_dqtpoll_t*, void*, unsigned int);
/* destroy the poll: poll, force flag
* if force flag is set (!= 0), give up
* about jobs, if no, do the job, but don't
* accept the new ones, and destroy all poll
* with last thread.
*/
int pth_dqtpoll_destroy(pth_dqtpoll_t*, int);
#endif /* __PTH_QUEUE_H__ */

@ -0,0 +1,274 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#ifndef __SNTL_SNTLLV2_H__
#define __SNTL_SNTLLV2_H__
#include <stdint.h>
#include <time.h>
#include <sys/types.h>
#include <pthread.h>
#include <openssl/ssl.h>
#include <tdata/usrtc.h>
#include <tdata/idx_allocator.h>
#include <tdata/list.h>
#include <sexpr/sexp.h>
#include <sexpr/faststack.h>
#include <sntl/errno.h>
#define VERIFY_DEPTH 1 /* FIXME: */
typedef struct __perm_context_type {
char *login;
char *passwd;
uint64_t certid;
struct in_addr *addr;
void *priv;
} perm_ctx_t;
/* 8 byte header */
typedef struct __sntllv2_head_type {
uint16_t msgid;
uint16_t payload_length;
uint8_t attr;
uint8_t opcode;
uint16_t reserve;
}__attribute__((packed)) sntllv2_head_t;
struct __connections_subsys_type;
struct __channel_t;
struct __message_t;
/* flags for the connection link */
#define SNSX_BATCHMODE (1 << 1)
#define SNSX_MESSAGINGMODE (1 << 2)
#define SNSX_ALIVE (1 << 3)
#define SNSX_CLOSED (1 << 4)
/*
* älä jätä kommentteja omalla kielellä! yksinkertaisia englanti sijaan!
* i found somebody who write comments and messages in non-english,
* it's a fucking practice - forget it.
*/
typedef struct __connection_t {
/* General section */
struct __connections_subsys_type *ssys; /* < connections subsystem */
char *uuid; /** < uuid of the connection */
/* Channels section */
idx_allocator_t idx_ch; /** < index allocation for channels */
pthread_mutex_t idx_ch_lock; /** < mutex for allocating and deallocating channels */
struct __channel_t **channels; /** < channels O(1) storage */
/* RPC section */
usrtc_t *rpc_list; /** < search tree of possible RPC typed lists */
/* SSL related section */
SSL_CTX *ctx; /** < SSL context */
SSL *ssl; /** < SSL connection */
int ssl_data_index; /** < SSL index for the custom data */
pthread_mutex_t sslinout[2]; /** < SSL related locks for in and out */
/* Security section */
perm_ctx_t *pctx; /** < higher layer authentification context */
/* Messages section */
struct __message_t **messages; /** < messages O(1) storage */
idx_allocator_t idx_msg;
pthread_mutex_t idx_msg_lock;
list_head_t write_pending; /** < list of messages waiting for write */
pthread_mutex_t write_pending_lock;
volatile uint8_t pending_messages; /** < pending message count */
/* Other stuff */
pthread_t thrd_poll[8];
volatile uint8_t flags; /** < flags of the connection */
volatile uint8_t usecount;
usrtc_node_t csnode; /** < node to store the connection within list */
} conn_t;
struct __connection_rpc_list_type;
struct __message_t;
typedef struct __pp_msg_type {
struct __message_t *msg;
list_node_t node;
} ppmsg_t;
typedef struct __channel_t {
uint16_t cid; /** < ID of the channel */
conn_t *connection; /** < pointer to the parent connection */
struct __connection_rpc_list_type *rpc_list; /** < rpc functions list */
int flags; /** < flags of the channel */
} chnl_t;
/* message flags */
#define SXMSG_OPEN (1 << 1)
#define SXMSG_CLOSED (1 << 2)
#define SXMSG_PROTO (1 << 3)
#define SXMSG_LINK (1 << 4)
#define SXMSG_REPLYREQ (1 << 5)
#define SXMSG_PULSE (1 << 6)
#define SXMSG_TIMEDOUT (1 << 7)
/**
* \brief Message used in sntl message passing
*
* This structure used to manage a message within a channel
* of the sntl structure stack.
*/
typedef struct __message_t {
chnl_t *pch; /** < channel of the message(if applicable) */
pthread_mutex_t wait; /** < special wait mutex, used for pending list and sync */
sntllv2_head_t mhead;
void *payload; /** < payload */
} sxmsg_t;
#define sxmsg_payload(m) (m)->payload
#define sxmsg_datalen(m) (m)->mhead.payload_length
#define sxmsg_rapidbuf(m) (m)->payload
#define sxmsg_retcode(m) (m)->mhead.opcode
#define sxmsg_waitlock(m) pthread_mutex_lock(&((m)->wait))
#define sxmsg_waitunlock(m) pthread_mutex_unlock(&((m)->wait))
typedef struct __connection_rpc_entry_type {
char *name;
int (*rpcf)(void *, sexp_t *);
usrtc_node_t node;
} cx_rpc_t;
typedef struct __connection_rpc_list_type {
usrtc_t *rpc_tree; /** < search tree for the rpc lookup */
char *opt_version; /** < reserved for future implementations */
} cx_rpc_list_t;
#define MAX_CONNECTIONS 32768
/**
* \brief Connection subsystem structure.
*
* This structure used for management and control a set of a
* determined connections with the same RPC lists and the same
* mode (server, client).
*
*/
typedef struct __connections_subsys_type {
usrtc_t *connections;
pthread_rwlock_t rwlock;
char *rootca, *certpem, *certkey; /* path name to the certificates */
cx_rpc_list_t *system_rpc;
/* special functions pointers */
int (*validate_sslpem)(conn_t *); /** < this function used to validate SSL certificate while SSL handshake */
int (*secure_check)(conn_t *); /** < this function authorize user to login,
* and also should check SSL cert and user, and already made sessions */
usrtc_t* (*get_rpc_typed_list_tree)(conn_t *); /** < this function is used to set RPC list of the functions */
int (*set_typed_list_callback)(conn_t *, int, char *); /** < this function is a callback
* during setting up a typed channel */
void (*on_destroy)(conn_t *); /** < callback on connection destroy */
void (*on_pulse)(conn_t *, sexp_t *); /** < callback on pulse emit */
void *priv;
} conn_sys_t;
#define connections_set_sslvalidate(c, f) (c)->validate_sslpem = (f)
#define connections_set_authcheck(c, f) (c)->secure_check = (f)
#define connections_set_rpcvalidator(c, f) (c)->get_rpc_typed_list_tree = (f)
#define connections_set_channelcall(c, f) (c)->set_typed_list_callback = (f)
#define connections_set_ondestroy(c, f) (c)->on_destroy = (f)
#define connections_set_onpulse(c, f) (c)->on_pulse = (f)
#define connections_set_priv(c, p) (c)->priv = (p)
#define connections_get_priv(c) (c)->priv
typedef struct __rpc_typed_list_type {
int type_id;
char *description;
cx_rpc_list_t *rpc_list;
usrtc_node_t lnode;
} rpc_typed_list_t;
#ifdef __cplusplus
extern "C" {
#endif
/* API */
int sntl_init(void);
int connections_init(conn_sys_t *ssys);
conn_sys_t *connections_create(void);
int connections_destroy(conn_sys_t *ssys);
int connections_free(conn_sys_t *ssys);
int connections_setsslserts(conn_sys_t *ssys, const char *rootca,
const char *certpem, const char *certkey);
/* create links */
conn_t *connection_master_link(conn_sys_t *ssys, int sck, struct in_addr *addr);
conn_t *connection_link(conn_sys_t *ssys, const char *host,
int port, const char *SSL_cert, const char *login,
const char *passwd);
int connection_close(conn_t *co);
/* channels */
chnl_t *sxchannel_open(conn_t *co, int type);
int sxchannel_close(chnl_t *channel);
/* messages */
/*
* creates a message with a payload.
* Will return a error code, and, if applicable, pointer to message
*/
int sxmsg_send(chnl_t *channel, const char *data, size_t datalen, sxmsg_t **msg);
/* the same - postponed message i.e. will be written to the queue - not to write immendatly */
int sxmsg_send_pp(chnl_t *channel, const char *data, size_t datalen, sxmsg_t **msg);
/* send a pulse message */
int sxmsg_pulse(conn_t *co, const char *data, size_t datalen);
int sxmsg_reply(sxmsg_t *msg, const char *data, size_t datalen);
int sxmsg_reply_pp(sxmsg_t *msg, const char *data, size_t datalen);
int sxmsg_rreply(sxmsg_t *msg, size_t datalen);
int sxmsg_return(sxmsg_t *msg, int opcode);
int sxmsg_return_pp(sxmsg_t *msg, int opcode);
void sxmsg_clean(sxmsg_t *msg);
#ifdef __cplusplus
}
#endif
/* RPC List API */
#define SNTL_FILTER_INC 0xa
#define SNTL_FILTER_EXC 0xb
#define SNTL_FILTER_END -1
#ifdef __cplusplus
extern "C" {
#endif
int sntl_rpclist_init(usrtc_t *tree);
int sntl_rpclist_add(usrtc_t *tree, int type, const char *description,
const char *version);
int sntl_rpclist_add_function(usrtc_t *tree, int type, const char *fu_name,
int (*rpcf)(void *, sexp_t *));
int sntl_rpclist_filter(usrtc_t *source, usrtc_t **dest, int flag, int *filter);
#ifdef __cplusplus
}
#endif
#define blub(txt) fprintf(stderr, "%s:%d in %s > %s\n", __FILE__, __LINE__, __FUNCTION__, txt)
#define dumphead(head) fprintf(stderr, "id: %d, opcode: %d, attr: %d, len = %d\n", head->msgid, head->opcode, head->attr, head->payload_length)
#endif /* __SNTL_SNTLLV2_H__ */

@ -16,7 +16,7 @@ lib_LTLIBRARIES = libsntl.la
libsntl_la_SOURCES = \
support.c queue.c rpclist.c message.c channel.c connection.c
connex.c sntllv2.c chansx.c messagesx.c rpclist.c uuid.c
libsntl_la_LDFLAGS =

@ -1,316 +0,0 @@
/*
* Secure Network Transport Layer Library implementation.
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef WIN32
#include <Winsock2.h>
#else
#include <sys/select.h>
#include <netdb.h>
#include <unistd.h>
#include <uuid/uuid.h>
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/connection.h>
extern char *__generate_uuid(void);
extern void __destroy_msg(sxmsg_t *msg);
extern int __create_sys_msg(sxmsg_t **msg, char *uuid, chnl_t *ch,
sxpayload_t *data);
static long __cmp_ulong(const void *a, const void *b)
{
return (long)(*(ulong_t *)a - *(ulong_t *)b);
}
int __alloc_channel(ulong_t cid, conn_t *co, rpc_typed_list_t *rlist, chnl_t **channel)
{
int r = 0;
chnl_t *ch = malloc(sizeof(chnl_t));
usrtc_t *msg_tree = malloc(sizeof(usrtc_t));
idx_allocator_t *idx_msg = malloc(sizeof(idx_allocator_t));
if(!idx_msg) goto __fin_enomem;
else if(idx_allocator_init(idx_msg, MAX_MSGINDEX, 0)) goto __fin_enomem;
if(!ch || !msg_tree) {
__fin_up2:
idx_allocator_destroy(idx_msg);
__fin_enomem:
r = ENOMEM;
goto __fin_up;
} else {
usrtc_init(msg_tree, USRTC_REDBLACK, MAX_PENDINGMSG, __cmp_ulong);
ch->cid = cid;
ch->flags = ch->use_count = 0;
ch->uuid = NULL;
usrtc_node_init(&ch->node, ch);
if(rlist) ch->rpc_list = rlist->rpc_list;
else ch->rpc_list = NULL;
/* init locks */
if(pthread_rwlock_init(&(ch->msglock), NULL)) {
r = ENOMEM;
goto __fin_up2;
}
if(pthread_mutex_init(&(ch->oplock), NULL)) {
pthread_rwlock_destroy(&(ch->msglock));
r = ENOMEM;
goto __fin_up2;
}
/* assign all the stuff */
ch->idx_msg = idx_msg;
ch->msgs_tree = msg_tree;
ch->connection = co;
}
__fin_up:
if(r) {
if(idx_msg) free(idx_msg);
if(ch) free(ch);
if(msg_tree) free(msg_tree);
return r;
} else {
*channel = ch;
return 0;
}
}
/* channels */
int channel_open(conn_t *co, chnl_t **ch, int type)
{
chnl_t *nch = NULL;
conn_sys_t *ssys = co->ssys;
int r = 0;
char *uuid_;
sxpayload_t *pl;
ulong_t cid;
rpc_typed_list_t *rpclist = NULL;
usrtc_node_t *node = NULL;
sxmsg_t *sms;
if(!(co->flags & CXCONN_ESTABL)) {
return ESXNOCONNECT;
}
uuid_ = __generate_uuid();
pl = malloc(sizeof(sxpayload_t));
node = usrtc_lookup(co->rpc_list, &type);
if(node) rpclist = (rpc_typed_list_t *)usrtc_node_getdata(node);
if(!uuid_) {
if(pl) free(pl);
return ENOMEM;
}
if(!pl) {
__ffail:
if(uuid_) free(uuid_);
return ENOMEM;
} else {
pl->sx = NULL;
if(!(pl->cstr = malloc(sizeof(char)*ESX_SYSMSG_SIZE))) {
free(pl); goto __ffail;
} else memset(pl->cstr, 0, sizeof(char)*ESX_SYSMSG_SIZE);
}
pthread_rwlock_wrlock(&(co->chnl_lock));
cid = idx_allocate(co->idx_ch);
pthread_rwlock_unlock(&(co->chnl_lock));
if(cid == IDX_INVAL) {
r = ENOMEM;
goto __fini_op;
}
if((r = __alloc_channel(cid, co, rpclist, &nch))) {
goto __fini_op;
} else nch->flags |= ESXCHAN_PENDING;
nch->uuid = uuid_;
/* ok now we're ready to create a message and push channel to the list */
if((r = __create_sys_msg(&sms, uuid_, nch, pl))) {
__fail_chan:
/* destroy the channel*/
goto __fini_op;
} else {
/* put the channel to the channels search tree */
pthread_rwlock_wrlock(&(co->chnl_lock));
//printf("inserting cid = %d\n", nch->cid);
usrtc_insert(co->chnl_tree, &nch->node, &nch->cid);
pthread_rwlock_unlock(&(co->chnl_lock));
/* put system message to the run queue */
/* first form the message */
snprintf(pl->cstr, sizeof(char)*ESX_SYSMSG_SIZE,
"(ch-open ((:id %ld)(:uuid %s)(:type %d)))", nch->cid, nch->uuid, type);
nch->sysmsg = sms; /* assign system message to the channel */
/* put it */
if((r = pth_queue_add(ssys->ioqueue, (void *)sms, SYS_MSG))) {
__fail_chan_r:
/* remove it from the search tree */
pthread_rwlock_wrlock(&(co->chnl_lock));
usrtc_delete(co->chnl_tree, &nch->node);
pthread_rwlock_unlock(&(co->chnl_lock));
goto __fail_chan;
}
if(!(sms->flags & ESXMSG_PENDING)) {
/* was processed too fast */
goto __process_smsg;
} else pthread_mutex_lock(&(sms->wait)); /* will sleep until got a reply */
__process_smsg:
if(sms->opcode) {
r = sms->opcode;
goto __fail_chan_r;
} else r = 0;
nch->flags &= ~ESXCHAN_PENDING; /* mark it as established */
free(pl->cstr);
free(pl);
__destroy_msg(nch->sysmsg);
}
__fini_op:
if(r) {
if(uuid_) free(uuid_);
if(pl) {
if(pl->cstr) free(pl->cstr);
free(pl);
}
pthread_rwlock_wrlock(&(co->chnl_lock));
idx_free(co->idx_ch, nch->cid);
pthread_rwlock_unlock(&(co->chnl_lock));
idx_allocator_destroy(nch->idx_msg);
free(nch->idx_msg);
free(nch->msgs_tree);
pthread_mutex_destroy(&(nch->oplock));
pthread_rwlock_destroy(&(nch->msglock));
free(nch);
} else *ch = nch;
return r;
}
int channel_close(chnl_t *chnl)
{
char *uuid_;
usrtc_node_t *node = NULL;
int r = 0;
conn_t *co = chnl->connection;
conn_sys_t *ssys = co->ssys;
sxmsg_t *sms;
sxpayload_t *pl;
if(!(co->flags & CXCONN_ESTABL)) {
return ESXNOCONNECT;
}
pthread_rwlock_rdlock(&(co->chnl_lock));
node = usrtc_lookup(co->chnl_tree, &chnl->cid);
pthread_rwlock_unlock(&(co->chnl_lock));
if(!node) {
return ENOENT;
}
pthread_rwlock_wrlock(&(chnl->msglock));
/* check unprocessed messages */
if(!usrtc_isempty(chnl->msgs_tree)) { /* messages on the queue */
pthread_rwlock_unlock(&(chnl->msglock));
return EBUSY;
}
uuid_ = __generate_uuid();
pl = malloc(sizeof(sxpayload_t));
if(!pl || !uuid_) {
pthread_rwlock_unlock(&(chnl->msglock));
if(pl) free(pl);
if(uuid_) free(uuid_);
return ENOMEM;
}
if(__create_sys_msg(&sms, uuid_, chnl, pl)) {
pthread_rwlock_unlock(&(chnl->msglock));
free(pl);
free(uuid_);
return ENOMEM;
}
pl->sx = NULL;
if(!(pl->cstr = malloc(sizeof(char) * ESX_SYSMSG_SIZE))) {
pthread_rwlock_unlock(&(chnl->msglock));
free(pl);
free(uuid_);
return ENOMEM;
}
memset(pl->cstr, 0, sizeof(char) * ESX_SYSMSG_SIZE);
/* put system message to the run queue */
/* first form the message */
snprintf(pl->cstr, sizeof(char) * ESX_SYSMSG_SIZE,
"(ch-close (:id %ld))", chnl->cid);
chnl->sysmsg = sms; /* assign system message to the channel */
/* put it */
if((r = pth_queue_add(ssys->ioqueue, (void *)sms, SYS_MSG))) {
pthread_rwlock_unlock(&(chnl->msglock));
return r;
}
if(!(sms->flags & ESXMSG_PENDING)) {
/* was processed too fast */
goto __process_smsg;
} else pthread_mutex_lock(&(sms->wait)); /* will sleep until got a reply */
__process_smsg:
if(sms->opcode) {
pthread_rwlock_unlock(&(chnl->msglock));
r = sms->opcode;
return r;
} else r = 0;
chnl->flags &= ~ESXCHAN_PENDING; /* mark it as established */
/* remove channel from the search tree */
pthread_rwlock_wrlock(&(chnl->connection->chnl_lock));
usrtc_delete(chnl->connection->chnl_tree, &chnl->node);
/* free index */
idx_free(co->idx_ch, chnl->cid);
pthread_rwlock_unlock(&(chnl->connection->chnl_lock));
pthread_rwlock_unlock(&(chnl->msglock));
__destroy_msg(chnl->sysmsg);
free(uuid_);
free(pl->cstr);
free(pl);
free(chnl->uuid);
idx_allocator_destroy(chnl->idx_msg);
free(chnl->idx_msg);
free(chnl->msgs_tree);
pthread_mutex_destroy(&(chnl->oplock));
pthread_rwlock_destroy(&(chnl->msglock));
free(chnl);
return 0;
}

@ -0,0 +1,259 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef WIN32
#include <Winsock2.h>
#define EBADE 1
#define NETDB_SUCCESS 0
#else
#include <sys/select.h>
#include <netdb.h>
#include <unistd.h>
#include <uuid/uuid.h>
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/sntllv2.h>
#include "internal.h"
/* locally used functions */
uint8_t _channel_open(conn_t *co, uint16_t *chid)
{
chnl_t *chan;
int typeid = *chid; /* our type */
uint16_t chidx;
usrtc_t *rpc_list = co->rpc_list;
usrtc_node_t *node;
rpc_typed_list_t *rlist;
cx_rpc_list_t *rpclist;
node = usrtc_lookup(rpc_list, &typeid);
if(!node) return SNE_EPERM;
else rlist = (rpc_typed_list_t *)usrtc_node_getdata(node);
if(rlist) rpclist = rlist->rpc_list;
else return SNE_FAILED;
chan = malloc(sizeof(chnl_t));
if(!chan) return SNE_ENOMEM;
/* init channel */
chan->connection = co;
chan->rpc_list = rpclist;
chan->flags = 0;
pthread_mutex_lock(&co->idx_ch_lock);
chidx = idx_allocate(&co->idx_ch);
pthread_mutex_unlock(&co->idx_ch_lock);
if(chidx == IDX_INVAL) {
free(chan);
return SNE_MCHANNELS;
}
chan->cid = chidx;
co->channels[chidx] = chan;
*chid = chidx;
return SNE_SUCCESS;
}
uint8_t _channel_close(conn_t *co, uint16_t chid)
{
chnl_t *chan;
ulong_t chidx = chid;
if(chid > 512) return SNE_INVALINDEX;
else chan = co->channels[chidx];
if(!chan) return SNE_NOSUCHCHAN;
pthread_mutex_lock(&co->idx_ch_lock);
idx_free(&co->idx_ch, chidx);
co->channels[chidx] = NULL;
pthread_mutex_unlock(&co->idx_ch_lock);
free(chan);
return SNE_SUCCESS;
}
chnl_t *sxchannel_open(conn_t *co, int type)
{
chnl_t *chan = NULL;
sxmsg_t *msg = NULL;
sntllv2_head_t *head;
int msgidx, r, ccid;
if(!co) {
r = SNE_FAILED;
goto __reterr;
}
if(!(chan = malloc(sizeof(chnl_t)))) {
__enomem:
if(chan) free(chan);
r = SNE_ENOMEM;
goto __reterr;
}
if(!(msg = malloc(sizeof(sxmsg_t)))) goto __enomem;
/* early init for the channel */
chan->connection = co;
chan->flags = 0;
/* early init for the message */
pthread_mutex_init(&msg->wait, NULL);
pthread_mutex_lock(&msg->wait);
msg->pch = chan;
msg->payload = NULL;
memset(&msg->mhead, 0, sizeof(sntllv2_head_t));
head = &msg->mhead;
/* form a header */
head->attr = SXMSG_PROTO | SXMSG_REPLYREQ | SXMSG_OPEN;
head->payload_length = 0;
head->reserve = (uint16_t)type;
/* try to alloc a message */
pthread_mutex_lock(&co->idx_msg_lock);
msgidx = idx_allocate(&co->idx_msg);
if(msgidx != IDX_INVAL) co->messages[msgidx] = msg;
pthread_mutex_unlock(&co->idx_msg_lock);
if(msgidx == IDX_INVAL) { r = SNE_MMESSAGES; goto __reterr2; }
else head->msgid = msgidx;
/* now we're ready to write it */
r = _sntll_writemsg(co, msg);
if(r == SNE_SUCCESS) pthread_mutex_lock(&msg->wait);
else goto __reterr3;
/* we will wakeup on return */
if(msg->mhead.opcode != SNE_SUCCESS) { r = msg->mhead.opcode; goto __reterr3; }
/* ok all is fine */
chan->cid = msg->mhead.reserve;
ccid = chan->cid;
pthread_mutex_lock(&co->idx_ch_lock);
idx_reserve(&co->idx_ch, ccid);
co->channels[ccid] = chan;
pthread_mutex_unlock(&co->idx_ch_lock);
/* destroy a message */
pthread_mutex_lock(&co->idx_msg_lock);
idx_free(&co->idx_msg, msgidx);
co->messages[msgidx] = NULL;
pthread_mutex_unlock(&co->idx_msg_lock);
/* free allocated resources */
pthread_mutex_unlock(&msg->wait);
pthread_mutex_destroy(&msg->wait);
free(msg);
return chan;
__reterr3:
pthread_mutex_lock(&co->idx_msg_lock);
idx_free(&co->idx_msg, msgidx);
co->messages[msgidx] = NULL;
pthread_mutex_unlock(&co->idx_msg_lock);
__reterr2:
pthread_mutex_unlock(&msg->wait);
pthread_mutex_destroy(&msg->wait);
__reterr:
if(chan) free(chan);
if(msg) free(msg);
errno = r;
return NULL;
}
int sxchannel_close(chnl_t *channel)
{
int r = SNE_SUCCESS;
sxmsg_t *msg;
sntllv2_head_t *head;
conn_t *co;
int msgidx = 0, chidx = 0;
/* check channel validity */
if(!channel) return SNE_FAILED;
else if(!(co = channel->connection)) return SNE_FAILED;
if(channel->cid > 512) return SNE_IGNORED;
else chidx = channel->cid;
if(channel != co->channels[chidx]) return SNE_IGNORED;
if(!(msg = malloc(sizeof(sxmsg_t)))) return SNE_ENOMEM;
head = &msg->mhead;
memset(head, 0, sizeof(sntllv2_head_t));
/* setup head */
head->attr = SXMSG_PROTO | SXMSG_REPLYREQ; /* close channel */
head->reserve = channel->cid;
/* setup message */
pthread_mutex_init(&msg->wait, NULL);
pthread_mutex_lock(&msg->wait);
msg->pch = channel;
/* allocate it */
pthread_mutex_lock(&co->idx_msg_lock);
msgidx = idx_allocate(&co->idx_msg);
if(msgidx != IDX_INVAL) co->messages[msgidx] = msg;
pthread_mutex_unlock(&co->idx_msg_lock);
if(msgidx == IDX_INVAL) { r = SNE_MMESSAGES; goto __reterr2; }
else head->msgid = msgidx;
r = _sntll_writemsg(co, msg);
if(r == SNE_SUCCESS) {
pthread_mutex_lock(&msg->wait);
r = head->opcode;
/* we will free this anyway */
pthread_mutex_lock(&co->idx_ch_lock);
idx_free(&co->idx_ch, chidx);
co->channels[chidx] = NULL;
pthread_mutex_unlock(&co->idx_ch_lock);
free(channel);
}
pthread_mutex_lock(&co->idx_msg_lock);
idx_free(&co->idx_msg, msgidx);
co->messages[msgidx] = NULL;
pthread_mutex_unlock(&co->idx_msg_lock);
__reterr2:
pthread_mutex_unlock(&msg->wait);
pthread_mutex_destroy(&msg->wait);
free(msg);
return r;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,291 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef WIN32
#include <Winsock2.h>
#define EBADE 1
#define NETDB_SUCCESS 0
#else
#include <sys/select.h>
#include <netdb.h>
#include <unistd.h>
#include <uuid/uuid.h>
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/sntllv2.h>
static int __insert_rpc_function(usrtc_t *tree, const char *name, int (*rpcf)(void *, sexp_t *))
{
cx_rpc_t *ent = malloc(sizeof(cx_rpc_t));
usrtc_node_t *node;
if(!ent) return ENOMEM;
else node = &ent->node;
if(!(ent->name = strdup(name))) {
free(ent);
return ENOMEM;
} else ent->rpcf = rpcf;
usrtc_node_init(node, ent);
usrtc_insert(tree, node, ent->name);
return 0;
}
static void __destroy_rpc_list_tree(usrtc_t *tree)
{
usrtc_node_t *node;
cx_rpc_t *ent;
for(node = usrtc_first(tree); node != NULL; node = usrtc_first(tree)) {
ent = (cx_rpc_t *)usrtc_node_getdata(node);
usrtc_delete(tree, node);
free(ent->name);
free(ent);
}
return;
}
/* negotiation functions */
/**
* Proto: (auth-set-credentials "<login>" "<password>")
* Return - message return; opcode as a return of this function.
* in batch mode message with 0 index used always
*/
static int __set_credentials(void *cctx, sexp_t *sx)
{
register int idx;
conn_t *co = (conn_t *)cctx;
conn_sys_t *ssys = co->ssys;
sexp_t *isx;
char *login = NULL;
char *passwd = NULL;
/* take a deal with S-exp */
SEXP_ITERATE_LIST(sx, isx, idx) {
if(isx->ty == SEXP_LIST) return SNE_BADPROTO;
if(idx > 0 && isx->aty != SEXP_DQUOTE) return SNE_BADPROTO;
if(idx == 1) login = isx->val;
else if(idx == 2) passwd = isx->val;
else if(idx > 2) return SNE_BADPROTO;
}
if(!login || !passwd) return SNE_BADPROTO;
co->pctx->login = strdup(login);
co->pctx->passwd = strdup(passwd);
if(!co->pctx->login || !co->pctx->passwd) {
if(co->pctx->login) free(co->pctx->login);
if(co->pctx->passwd) free(co->pctx->passwd);
return SNE_ENOMEM;
}
if(ssys->secure_check) return ssys->secure_check(co);
else return SNE_SUCCESS;
}
static int __get_channels_list(void *cctx, sexp_t *sx)
{
conn_t *co = (conn_t *)cctx;
conn_sys_t *ssys = co->ssys;
sxmsg_t *msg = co->messages[0];
char *buf = msg->payload;
usrtc_node_t *node;
rpc_typed_list_t *list_ent;
size_t maxlen = 65535 - sizeof(sntllv2_head_t);
size_t ulen = 0;
/* we will avoid S-exp scanning here */
/* call the function */
if(ssys->get_rpc_typed_list_tree)
co->rpc_list = ssys->get_rpc_typed_list_tree(co);
if(!co->rpc_list) return SNE_EPERM;
//buf += sizeof(sntllv2_head_t);
ulen += snprintf(buf + ulen, maxlen - ulen, "(set-channels-list ");
for(node = usrtc_first(co->rpc_list); node != NULL;
node = usrtc_next(co->rpc_list, node)) { /* fill the list */
list_ent = (rpc_typed_list_t *)usrtc_node_getdata(node);
ulen += snprintf(buf + ulen, maxlen - ulen, "(:%d \"%s\")",
list_ent->type_id, list_ent->description);
}
ulen += snprintf(buf + ulen, maxlen - ulen, ")");
msg->mhead.payload_length = ulen + sizeof(sntllv2_head_t);
/* we're ready for messaging mode */
co->flags |= SNSX_MESSAGINGMODE;
return SNE_SUCCESS;
}
static int __set_channels_list(void *cctx, sexp_t *sx)
{
register int idx;
conn_t *co = (conn_t *)cctx;
conn_sys_t *ssys = co->ssys;
sexp_t *isx, *iisx;
int id, r;
SEXP_ITERATE_LIST(sx, isx, idx) {
if(!idx) continue;
if(isx->ty != SEXP_LIST) return SNE_BADPROTO;
if(sexp_list_length(isx) != 2) return SNE_BADPROTO;
/* get id */
sexp_list_car(isx, &iisx);
if(iisx->ty == SEXP_LIST) return SNE_BADPROTO;
if(iisx->aty != SEXP_BASIC) return SNE_BADPROTO;
if(iisx->val[0] != ':') return SNE_BADPROTO;
id = atoi(iisx->val + sizeof(char));
/* get short description */
sexp_list_cdr(isx, &iisx);
if(iisx->ty == SEXP_LIST) return SNE_BADPROTO;
if(iisx->aty != SEXP_DQUOTE) return SNE_BADPROTO;
/* ok, here we go */
if(ssys->set_typed_list_callback) {
r = ssys->set_typed_list_callback(co, id, iisx->val);
if(r != SNE_SUCCESS) return r;
}
}
/* we're ready for messaging mode */
co->flags |= SNSX_MESSAGINGMODE;
co->flags &= ~SNSX_BATCHMODE;
return SNE_SUCCESS;
}
static int __init_systemrpc_tree(usrtc_t *rtree)
{
/* batch mode negotiation context functions */
if(__insert_rpc_function(rtree, "auth-set-credentials", __set_credentials)) goto __fail;
if(__insert_rpc_function(rtree, "get-channels-list", __get_channels_list)) goto __fail;
if(__insert_rpc_function(rtree, "set-channels-list", __set_channels_list)) goto __fail;
return 0;
__fail:
__destroy_rpc_list_tree(rtree);
return ENOMEM;
}
static long __cmp_cstr(const void *a, const void *b)
{
return (long)strcmp((const char *)a, (const char *)b);
}
int connections_init(conn_sys_t *ssys)
{
int r = 0;
if(!ssys) return EINVAL;
else memset(ssys, 0, sizeof(conn_sys_t));
if(!(ssys->connections = malloc(sizeof(usrtc_t)))) return ENOMEM;
/* init connections list */
usrtc_init(ssys->connections, USRTC_REDBLACK, MAX_CONNECTIONS,
__cmp_cstr);
if((r = pthread_rwlock_init(&(ssys->rwlock), NULL)))
goto __fini;
/* init RPC list related functions */
if(!(ssys->system_rpc = malloc(sizeof(cx_rpc_list_t)))) {
r = ENOMEM;
goto __lfini;
} else {
if(!(ssys->system_rpc->rpc_tree = malloc(sizeof(usrtc_t)))) {
r = ENOMEM;
goto __lfini;
}
usrtc_init(ssys->system_rpc->rpc_tree, USRTC_SPLAY, 256, __cmp_cstr);
r = __init_systemrpc_tree(ssys->system_rpc->rpc_tree);
if(r) {
free(ssys->system_rpc->rpc_tree);
goto __lfini;
}
}
return 0;
__lfini:
if(ssys->system_rpc) free(ssys->system_rpc);
pthread_rwlock_destroy(&(ssys->rwlock));
__fini:
if(ssys->connections) free(ssys->connections);
return r;
}
conn_sys_t *connections_create(void)
{
int r = 0;
conn_sys_t *nsys = malloc(sizeof(conn_sys_t));
if(!nsys) {
errno = ENOMEM;
return NULL;
}
r = connections_init(nsys);
if(r) {
errno = r;
free(nsys);
return NULL;
}
return nsys;
}
int connections_setsslserts(conn_sys_t *ssys, const char *rootca,
const char *certpem, const char *certkey)
{
int r = ENOMEM;
if(!ssys) return EINVAL;
/* simply copying */
if(!(ssys->rootca = strdup(rootca))) return ENOMEM;
if(!(ssys->certkey = strdup(certkey))) goto __fail;
if(!(ssys->certpem = strdup(certpem))) goto __fail;
r = 0;
return 0;
__fail:
if(ssys->rootca) free(ssys->rootca);
if(ssys->certkey) free(ssys->certkey);
if(ssys->certpem) free(ssys->certpem);
return r;
}

@ -0,0 +1,14 @@
#ifndef __SNTLL_INTERNAL_H__
#define __SNTLL_INTERNAL_H__
/* link related */
int _sntll_writemsg(conn_t *co, sxmsg_t *msg);
/* channel operations */
uint8_t _channel_open(conn_t *co, uint16_t *chid);
uint8_t _channel_close(conn_t *co, uint16_t chid);
/* messages */
void _message_process(sxmsg_t *msg);
#endif /* __SNTLL_INTERNAL_H__ */

@ -5,7 +5,7 @@ datarootdir=@datarootdir@
datadir=@datadir@
includedir=@includedir@
Name: libsntl
Name: libsntllv2
Description: Secure Network Transport Layer library implementation
Version: @VERSION@
Requires:

@ -1,286 +0,0 @@
/*
* Secure Network Transport Layer Library implementation.
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef WIN32
#include <Winsock2.h>
#else
#include <sys/select.h>
#include <netdb.h>
#include <unistd.h>
#include <uuid/uuid.h>
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/connection.h>
void __destroy_msg(sxmsg_t *msg)
{
chnl_t *ch = msg->pch;
if(msg->flags & ESXMSG_USR) {
pthread_mutex_lock(&(ch->oplock));
idx_free(ch->idx_msg, msg->mid);
pthread_mutex_unlock(&(ch->oplock));
} else if(msg->flags & ESXMSG_SYS) {
//if(msg->uuid) free(msg->uuid);
}
pthread_mutex_unlock(&(msg->wait));
pthread_mutex_destroy(&(msg->wait));
free(msg);
return;
}
sxmsg_t *__allocate_msg(int *res)
{
sxmsg_t *msg = malloc(sizeof(sxmsg_t));
int r = 0;
if(!msg) {
*res = ENOMEM;
return NULL;
} else {
memset(msg, 0, sizeof(sxmsg_t));
if((r = pthread_mutex_init(&(msg->wait), NULL))) {
free(msg);
*res = r;
return NULL;
}
usrtc_node_init(&(msg->pendingq_node), msg);
}
*res = 0;
return msg;
}
int __create_reg_msg(sxmsg_t **msg, chnl_t *ch)
{
int r = 0;
sxmsg_t *sm = __allocate_msg(&r);
if(r) return r;
else {
sm->pch = ch;
sm->flags = (ESXMSG_USR | ESXMSG_PENDING);
/* ok allocate message ID */
pthread_mutex_lock(&(ch->oplock));
sm->mid = idx_allocate(ch->idx_msg);
pthread_mutex_unlock(&(ch->oplock));
pthread_mutex_lock(&(sm->wait));
*msg = sm;
}
return 0;
}
int __create_sys_msg(sxmsg_t **msg, char *uuid, chnl_t *ch, sxpayload_t *data)
{
int r = 0;
sxmsg_t *m = __allocate_msg(&r);
if(r) return r;
else {
/* fill values */
m->pch = ch;
m->uuid = uuid;
m->payload = data;
/* set the right flags */
m->flags = (ESXMSG_SYS | ESXMSG_PENDING);
/* we need to lock the wait mutex */
pthread_mutex_lock(&(m->wait));
*msg = m;
}
return 0;
}
/* message passing */
/*
* How message sending works:
* 1. Create a message structure assigned to the channel,
* 2. Put S-expression context to it
* 3. Put the message to the queue
* 4. expect the result waiting on the lock mutex
*/
static int __message_send(chnl_t *ch, sexp_t *sx, sxmsg_t **msg, struct timespec *tio)
{
int r = 0;
sxmsg_t *m = NULL;
conn_t *co = ch->connection;
if(!(co->flags & CXCONN_ESTABL)) {
destroy_sexp(sx);
return ESXNOCONNECT;
}
*msg = NULL;
r = __create_reg_msg(&m, ch);
if(r) return r;
else {
/* put the message to the search tree */
pthread_rwlock_wrlock(&(ch->msglock));
usrtc_insert(ch->msgs_tree, &(m->pendingq_node), &(m->mid));
pthread_rwlock_unlock(&(ch->msglock));
/* message assign */
m->opcode = 0;
m->payload = (void *)sx;
/* assign initial sx */
m->initial_sx = sx;
/* put the message to the run queue */
r = pth_queue_add(co->mqueue, (void *)m, USR_MSG);
if(r) return r; /* FIXME: better give up */
if(m->flags & ESXMSG_PENDING) {
if(!tio) pthread_mutex_lock(&(m->wait));
else pthread_mutex_timedlock(&(m->wait), tio);
}
if(tio && (m->flags & ESXMSG_PENDING))
return ESXOTIMEDOUT;
if(!m->payload) {
r = m->opcode;
/* first remove the message from tree */
pthread_rwlock_wrlock(&(ch->msglock));
usrtc_delete(ch->msgs_tree, &(m->pendingq_node));
pthread_rwlock_unlock(&(ch->msglock));
/* destroy s expression */
destroy_sexp(m->initial_sx);
/* destroy */
__destroy_msg(m);
} else {
*msg = m;
if(m->opcode == ESXNOCONNECT || m->opcode == ESXRAPIDREPLY)
r = m->opcode;
else r = ESXOREPLYREQ;
/* FIXME: remove ugly code */
if(m->opcode == ESXRAPIDREPLY) {
/* first remove the message from tree */
pthread_rwlock_wrlock(&(ch->msglock));
usrtc_delete(ch->msgs_tree, &(m->pendingq_node));
pthread_rwlock_unlock(&(ch->msglock));
}
}
}
return r;
}
int msg_send(chnl_t *ch, sexp_t *sx, sxmsg_t **msg)
{
return __message_send(ch, sx, msg, NULL);
}
int msg_send_timed(chnl_t *ch, sexp_t *sx, sxmsg_t **msg, struct timespec *tio)
{
return __message_send(ch, sx, msg, tio);
}
static int __msg_reply(sxmsg_t *msg, sexp_t *sx, struct timespec *tio, int opcode,
int israpid)
{
int r = 0;
chnl_t *ch = msg->pch;
conn_t *co = ch->connection;
if(!(co->flags & CXCONN_ESTABL)) {
destroy_sexp(sx);
return ESXNOCONNECT;
}
if(msg->flags & ESXMSG_ISREPLY)
destroy_sexp((sexp_t *)msg->payload);
msg->payload = sx;
msg->opcode = opcode;
msg->flags |= ESXMSG_PENDING; /* pending */
msg->flags |= ESXMSG_ISREPLY; /* this is a reply */
if(israpid) msg->flags |= ESXMSG_ISRAPID; /* message is a rapid message */
if(!sx || israpid) msg->flags &= ~ESXMSG_PENDING;
else msg->flags |= ESXMSG_RMONRETR;
/* put the message to the queue */
r = pth_queue_add(co->mqueue, (void *)msg, USR_MSG);
if(r) return r; /* FIXME: better give up */
if(!sx || israpid) {
/* wait for write */
//pthread_mutex_lock(&(msg->wait));
return 0;
}
if(msg->flags & ESXMSG_PENDING) {
if(!tio) pthread_mutex_lock(&(msg->wait));
else pthread_mutex_timedlock(&(msg->wait), tio);
}
if(tio && (msg->flags & ESXMSG_PENDING)) {
msg->flags &= ~ESXMSG_PENDING; /* we will not wait for it */
return ESXOTIMEDOUT;
}
r = msg->opcode;
if(msg->flags & ESXMSG_CLOSURE) {
__destroy_msg(msg);
}
return r;
}
int msg_return(sxmsg_t *msg, int opcode)
{
return __msg_reply(msg, NULL, NULL, opcode, 0);
}
int msg_reply(sxmsg_t *msg, sexp_t *sx)
{
return __msg_reply(msg, sx, NULL, 0, 0);
}
int msg_reply_timed(sxmsg_t *msg, sexp_t *sx, struct timespec *tio)
{
return __msg_reply(msg, sx, tio, 0, 0);
}
int msg_reply_rapid(sxmsg_t *msg, sexp_t *sx)
{
return __msg_reply(msg, sx, NULL, 0, 1);
}
int msg_rapid_clean(sxmsg_t *msg)
{
destroy_sexp(msg->initial_sx);
if(msg->payload) destroy_sexp(msg->payload);
__destroy_msg(msg);
return 0;
}

@ -0,0 +1,340 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <tdata/usrtc.h>
#include <tdata/list.h>
#include <sexpr/sexp.h>
#include <sntl/sntllv2.h>
#include "internal.h"
void _message_process(sxmsg_t *msg)
{
chnl_t *chan = msg->pch;
sexp_t *sx, *isx;
usrtc_t *listrpc = chan->rpc_list->rpc_tree;
usrtc_node_t *node;
cx_rpc_t *rpcc;
int r;
sx = parse_sexp(msg->payload, msg->mhead.payload_length);
if(!sx) sxmsg_return(msg, SNE_BADPROTO);
sexp_list_car(sx, &isx);
if(!isx) { r = SNE_BADPROTO; goto __return_err; }
if(isx->ty == SEXP_LIST) { r = SNE_BADPROTO; goto __return_err; }
if(isx->aty != SEXP_BASIC) { r = SNE_BADPROTO; goto __return_err; }
node = usrtc_lookup(listrpc, (void *)isx->val);
if(!node) { r = SNE_ENORPC; goto __return_err; }
else rpcc = (cx_rpc_t *)usrtc_node_getdata(node);
rpcc->rpcf((void *)msg, sx);
destroy_sexp(sx);
return;
__return_err:
destroy_sexp(sx);
sxmsg_return(msg, r);
return;
}
static inline int __sxmsg_send(chnl_t *channel, const char *data, size_t datalen,
sxmsg_t **omsg, int pp)
{
conn_t *co;
sxmsg_t *msg;
sntllv2_head_t *head;
ppmsg_t *ppm;
int msgidx, r;
if(!channel) return SNE_FAILED;
if(!data || !datalen) return SNE_FAILED;
if(!(msg = malloc(sizeof(sxmsg_t)))) return SNE_ENOMEM;
else memset(msg, 0, sizeof(sxmsg_t));
co = channel->connection;
head = &msg->mhead;
/* form a head */
head->attr = SXMSG_OPEN | SXMSG_REPLYREQ;
head->reserve = channel->cid;
head->payload_length = datalen;
/* init message itself */
pthread_mutex_init(&msg->wait, NULL);
pthread_mutex_lock(&msg->wait);
msg->pch = channel;
msg->payload = (void *)data;
pthread_mutex_lock(&co->idx_msg_lock);
msgidx = idx_allocate(&co->idx_msg);
if(msgidx != IDX_INVAL) co->messages[msgidx] = msg;
pthread_mutex_unlock(&co->idx_msg_lock);
if(msgidx == IDX_INVAL) { r = SNE_MMESSAGES; goto __freemsg; }
else head->msgid = (uint16_t)msgidx;
/* ready to send it */
if(!pp) {
r = _sntll_writemsg(co, msg);
if(r != SNE_SUCCESS) goto __closemsg;
} else { /* postponed */
if(!(ppm = malloc(sizeof(ppmsg_t)))) { r = SNE_ENOMEM; goto __closemsg; }
list_init_node(&ppm->node);
ppm->msg = msg;
/* under locking here */
pthread_mutex_lock(&co->write_pending_lock);
co->pending_messages++;
list_add2tail(&co->write_pending, &ppm->node); /* push it to the FIFO */
pthread_mutex_unlock(&co->write_pending_lock);
}
pthread_mutex_lock(&msg->wait); /* we will sleep here */
if(head->payload_length) {
*omsg = msg;
return head->opcode;
} else r = head->opcode;
__closemsg:
pthread_mutex_lock(&co->idx_msg_lock);
idx_free(&co->idx_msg, msgidx);
co->messages[msgidx] = NULL;
pthread_mutex_unlock(&co->idx_msg_lock);
__freemsg:
/* free resources for message */
pthread_mutex_unlock(&msg->wait);
pthread_mutex_destroy(&msg->wait);
free(msg);
return r;
}
int sxmsg_send(chnl_t *channel, const char *data, size_t datalen, sxmsg_t **omsg)
{
return __sxmsg_send(channel, data, datalen, omsg, 0);
}
/* the same - postponed message i.e. will be written to the queue - not to write immendatly */
int sxmsg_send_pp(chnl_t *channel, const char *data, size_t datalen, sxmsg_t **omsg)
{
return __sxmsg_send(channel, data, datalen, omsg, 1);
}
/* send a pulse message */
int sxmsg_pulse(conn_t *co, const char *data, size_t datalen)
{
sxmsg_t *msg = malloc(sizeof(sxmsg_t));
sntllv2_head_t *head;
int r;
/* a little bit of paranoid tests */
if(!msg) return SNE_ENOMEM;
else memset(msg, 0, sizeof(sxmsg_t));
/* prepare it */
head = &msg->mhead;
head->attr = 0;
head->attr = SXMSG_PULSE | SXMSG_LINK;
head->opcode = SNE_RAPIDMSG;
head->payload_length = datalen;
msg->payload = (void *)data;
r = _sntll_writemsg(co, msg);
free(msg);
return r;
}
static inline int __sxmsg_reply(sxmsg_t *msg, const char *data,
size_t datalen, int pp)
{
chnl_t *ch;
conn_t *co;
sntllv2_head_t *head;
ppmsg_t *ppm;
int r, i;
pthread_t self = pthread_self();
/* a little bit of paranoid tests */
if(!msg) return SNE_FAILED;
if(!(ch = msg->pch)) return SNE_FAILED;
if(!(co = ch->connection)) return SNE_FAILED;
/* test for blocking */
for(i = 0; i < 8; i++)
if(pthread_equal(self, co->thrd_poll[i])) return SNE_WOULDBLOCK;
/* prepare it */
head = &msg->mhead;
head->attr = 0;
head->attr |= SXMSG_REPLYREQ;
head->opcode = SNE_REPLYREQ;
head->payload_length = datalen;
msg->payload = (void *)data;
if(!pp) {
r = _sntll_writemsg(co, msg);
if(r != SNE_SUCCESS) return r;
} else {
if(!(ppm = malloc(sizeof(ppmsg_t)))) return SNE_ENOMEM;
list_init_node(&ppm->node);
ppm->msg = msg;
/* under locking here */
pthread_mutex_lock(&co->write_pending_lock);
co->pending_messages++;
list_add2tail(&co->write_pending, &ppm->node); /* push it to the FIFO */
pthread_mutex_unlock(&co->write_pending_lock);
}
pthread_mutex_lock(&msg->wait); /* wait */
r = head->opcode;
if((head->attr & SXMSG_CLOSED) && !head->payload_length) { /* dialog closed and no data exists */
pthread_mutex_unlock(&msg->wait); /* we able to invalidate it */
pthread_mutex_destroy(&msg->wait);
free(msg);
}
return r;
}
int sxmsg_reply(sxmsg_t *msg, const char *data, size_t datalen)
{
return __sxmsg_reply(msg, data, datalen, 0);
}
int sxmsg_reply_pp(sxmsg_t *msg, const char *data, size_t datalen)
{
return __sxmsg_reply(msg, data, datalen, 1);
}
int sxmsg_rreply(sxmsg_t *msg, size_t datalen)
{
chnl_t *ch;
conn_t *co;
sntllv2_head_t *head;
int r, mid;
/* a little bit of paranoid tests */
if(!msg) return SNE_FAILED;
if(!(ch = msg->pch)) return SNE_FAILED;
if(!(co = ch->connection)) return SNE_FAILED;
/* prepare it */
head = &msg->mhead;
head->attr = 0;
head->attr |= SXMSG_CLOSED;
head->opcode = SNE_RAPIDMSG;
head->payload_length = datalen;
mid = head->msgid;
pthread_mutex_lock(&co->idx_msg_lock);
idx_free(&co->idx_msg, mid);
co->messages[mid] = NULL;
pthread_mutex_unlock(&co->idx_msg_lock);
r = _sntll_writemsg(co, msg);
pthread_mutex_unlock(&msg->wait); /* we able to invalidate it */
pthread_mutex_destroy(&msg->wait);
free(msg);
return r;
}
static inline int __sxmsg_return(sxmsg_t *msg, int opcode, int pp)
{
chnl_t *ch;
conn_t *co;
sntllv2_head_t *head;
ppmsg_t *ppm;
int r, mid;
/* a little bit of paranoid tests */
if(!msg) return SNE_FAILED;
if(!(ch = msg->pch)) return SNE_FAILED;
if(!(co = ch->connection)) return SNE_FAILED;
head = &msg->mhead;
head->attr = 0;
head->attr |= SXMSG_CLOSED;
head->opcode = opcode;
head->payload_length = 0;
mid = head->msgid;
if(!pp) {
/* free index */
pthread_mutex_lock(&co->idx_msg_lock);
idx_free(&co->idx_msg, mid);
co->messages[mid] = NULL;
pthread_mutex_unlock(&co->idx_msg_lock);
r = _sntll_writemsg(co, msg);
} else {
if(!(ppm = malloc(sizeof(ppmsg_t)))) return SNE_ENOMEM;
else { /* remove it */
pthread_mutex_lock(&co->idx_msg_lock);
idx_free(&co->idx_msg, mid);
co->messages[mid] = NULL;
pthread_mutex_unlock(&co->idx_msg_lock);
}
list_init_node(&ppm->node);
ppm->msg = msg;
/* under locking here */
pthread_mutex_lock(&co->write_pending_lock);
co->pending_messages++;
list_add2tail(&co->write_pending, &ppm->node); /* push it to the FIFO */
pthread_mutex_unlock(&co->write_pending_lock);
r = SNE_SUCCESS;
}
return r;
}
int sxmsg_return(sxmsg_t *msg, int opcode)
{
return __sxmsg_return(msg, opcode, 0);
}
int sxmsg_return_pp(sxmsg_t *msg, int opcode)
{
return __sxmsg_return(msg, opcode, 1);
}
void sxmsg_clean(sxmsg_t *msg)
{
free(msg->payload);
free(msg);
return;
}

@ -1,465 +0,0 @@
/*
* This is a proprietary software. See COPYING for further details.
*
*
*
* (c) Askele Group 2013-2015 <http://askele.com>
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <errno.h>
/**/
#ifdef WIN32
#include <Winsock2.h>
#else
#include <unistd.h>
#endif
/**/
// #include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <tdata/usrtc.h>
#include <sntl/pth_queue.h>
#define MAX_QUEUE_SIZE 4096
#define MAX_QUEUE_POOL 256
static long __cmp_uint(const void *a, const void *b)
{
return (long)(*(unsigned int *)a - *(unsigned int *)b);
}
static inline pth_msg_t *__get_newmsg(pth_queue_t *queue)
{
usrtc_t *tree = &queue->msgcache;
usrtc_node_t *node;
pth_msg_t *tmp;
if(usrtc_count(tree)) {
node = usrtc_first(tree);
tmp = (pth_msg_t *)usrtc_node_getdata(node);
usrtc_delete(tree, node);
} else {
tmp = malloc(sizeof(pth_msg_t));
tree = &queue->qtree;
node = &tmp->node;
usrtc_node_init(node, tmp);
}
/* insert it */
tree = &queue->qtree;
tmp->qlength = usrtc_count(tree);
usrtc_insert(tree, node, (void *)(&tmp->qlength));
return tmp;
}
static inline void __release_msg(pth_queue_t *queue, pth_msg_t *msg)
{
usrtc_node_t *node = &msg->node;
usrtc_t *tree = &queue->qtree;
tree = &queue->qtree; /* remove from queue */
usrtc_delete(tree, node);
tree = &queue->msgcache;
if(usrtc_count(tree) >= MAX_QUEUE_POOL)
free(msg);
else {
msg->data = NULL;
msg->msgtype = NIL_MSG;
usrtc_insert(tree, node, (void *)&msg->qlength);
}
return;
}
int pth_queue_init(pth_queue_t *queue)
{
int r = 0;
memset(queue, 0, sizeof(pth_queue_t));
if((r = pthread_cond_init(&queue->cond, NULL)))
return r;
if((r = pthread_mutex_init(&queue->mutex, NULL))) {
pthread_cond_destroy(&queue->cond);
return r;
}
usrtc_init(&queue->qtree, USRTC_AVL, MAX_QUEUE_SIZE, __cmp_uint);
usrtc_init(&queue->msgcache, USRTC_AVL, MAX_QUEUE_POOL, __cmp_uint);
return r;
}
int pth_queue_add(pth_queue_t *queue, void *data, unsigned int msgtype)
{
pth_msg_t *newmsg;
pthread_mutex_lock(&queue->mutex);
newmsg = __get_newmsg(queue);
if (newmsg == NULL) {
pthread_mutex_unlock(&queue->mutex);
return ENOMEM;
}
newmsg->data = data;
newmsg->msgtype = msgtype;
if(queue->length == 0)
pthread_cond_broadcast(&queue->cond);
queue->length++;
pthread_mutex_unlock(&queue->mutex);
return 0;
}
int pth_queue_get(pth_queue_t *queue, const struct timespec *timeout, pth_msg_t *msg)
{
usrtc_t *tree;
usrtc_node_t *node = NULL;
pth_msg_t *tmp;
int r = 0;
struct timespec abstimeout;
if (queue == NULL || msg == NULL)
return EINVAL;
else
tree = &queue->qtree;
if (timeout) { /* setup timeout */
struct timeval now;
gettimeofday(&now, NULL);
abstimeout.tv_sec = now.tv_sec + timeout->tv_sec;
abstimeout.tv_nsec = (now.tv_usec * 1000) + timeout->tv_nsec;
if (abstimeout.tv_nsec >= 1000000000) {
abstimeout.tv_sec++;
abstimeout.tv_nsec -= 1000000000;
}
}
pthread_mutex_lock(&queue->mutex);
/* Will wait until awakened by a signal or broadcast */
while ((node = usrtc_first(tree)) == NULL && r != ETIMEDOUT) { /* Need to loop to handle spurious wakeups */
if (timeout)
r = pthread_cond_timedwait(&queue->cond, &queue->mutex, &abstimeout);
else
pthread_cond_wait(&queue->cond, &queue->mutex);
}
if (r == ETIMEDOUT) {
pthread_mutex_unlock(&queue->mutex);
return r;
}
tmp = (pth_msg_t *)usrtc_node_getdata(node);
queue->length--;
msg->data = tmp->data;
msg->msgtype = tmp->msgtype;
msg->qlength = tmp->qlength; /* we will hold the msg id instead of size here */
__release_msg(queue, tmp);
pthread_mutex_unlock(&queue->mutex);
return 0;
}
int pth_queue_destroy(pth_queue_t *queue, int freedata, void (*free_msg)(void *))
{
int r = 0;
usrtc_t *tree = &queue->qtree;
usrtc_node_t *node = NULL;
pth_msg_t *msg;
if (queue == NULL) return EINVAL;
pthread_mutex_lock(&queue->mutex);
for (node = usrtc_first(tree); node != NULL; node = usrtc_first(tree)) {
usrtc_delete(tree, node);
msg = (pth_msg_t *)usrtc_node_getdata(node);
if(freedata) free(msg->data);
else if(free_msg) free_msg(msg->data);
free(msg);
}
/* free cache */
tree = &queue->msgcache;
for (node = usrtc_first(tree); node != NULL; node = usrtc_first(tree)) {
usrtc_delete(tree, node);
free(usrtc_node_getdata(node));
}
pthread_mutex_unlock(&queue->mutex);
r = pthread_mutex_destroy(&queue->mutex);
pthread_cond_destroy(&queue->cond);
return r;
}
unsigned int pth_queue_length(pth_queue_t *queue)
{
unsigned int c;
pthread_mutex_lock(&queue->mutex);
c = queue->length;
pthread_mutex_unlock(&queue->mutex);
return c;
}
/* dynamic queue thread poll */
struct __pthrd_data {
pth_dqtpoll_t *pthrd;
int myid;
};
static void *__poll_thread(void *poll)
{
int r = 0;
struct __pthrd_data *thrdata = (struct __pthrd_data *)poll;
struct __pthrd_data *npoll = NULL;
pth_msg_t msgbuf, sysbuf;
pth_dqtpoll_t *p = thrdata->pthrd;
pth_queue_t *q = p->queue;
ulong_t myid = thrdata->myid;
struct timeval now;
int resched = 0;
long tusec, si, mdrate;
while(1) {
resched = 0;
r = pth_queue_get(q, NULL, &msgbuf);
pthread_rwlock_wrlock(&(p->stats_lock));
if(p->flags & DQTPOLL_DEADSTAGE) { /* poll going to be killed */
pthread_rwlock_unlock(&(p->stats_lock));
idx_free(p->idx, myid);
p->poll_value--;
return NULL;
}
/* now get the time */
gettimeofday(&now, NULL);
if((now.tv_sec >= p->sched_time.tv_sec) &&
(now.tv_usec >= p->sched_time.tv_usec)) {
resched = 1;
/* set the new schedule time */
si = 0;
tusec = DQTPOLL_DELTAMS + now.tv_usec;
if(tusec > 1000000) {
tusec -= 1000000;
si++;
}
p->sched_time.tv_sec += si + DQTPOLL_DELTASE;
p->sched_time.tv_usec = tusec;
}
if(resched) { /* ok now we need to resched and descrease/increase thread poll volume */
if(p->msgop) mdrate = ((DQTPOLL_DELTASE*1000000) + DQTPOLL_DELTAMS)/p->msgop;
else mdrate = 0;
if((mdrate > p->poll_value) && (p->poll_value < MAX_POLL_VALUE)) { /* increase ! */
if((npoll = malloc(sizeof(struct __pthrd_data)))) {
npoll->myid = idx_allocate(p->idx);
npoll->pthrd = p;
p->poll_value++;
/* create thread here */
if(pthread_create(&(p->poll[npoll->myid]), NULL, __poll_thread, npoll)) {
idx_free(p->idx, npoll->myid);
p->poll_value--;
free(npoll);
}
}
} else if((p->poll_value > 2) && (mdrate < p->poll_value)) /* decrease */ {
memset(&sysbuf, 0, sizeof(pth_msg_t));
pth_queue_add(p->queue, &sysbuf, POLL_DECREASE);
}
/* init all other stuff */
p->msgop = 0;
}
if(r) {
pthread_rwlock_unlock(&(p->stats_lock));
continue;
} else p->msgop++;
pthread_rwlock_unlock(&(p->stats_lock));
switch(msgbuf.msgtype) {
case USR_MSG:
/* do the job */
p->jobdata_callback(msgbuf.data);
break;
case POLL_DECREASE:
pthread_rwlock_rdlock(&(p->stats_lock));
if(p->poll_value > 2) r = 1; /* exit now */
pthread_rwlock_unlock(&(p->stats_lock));
if(r) {
pthread_rwlock_wrlock(&(p->stats_lock));
idx_free(p->idx, myid);
p->poll_value--;
pthread_rwlock_unlock(&(p->stats_lock));
free(poll);
return NULL;
}
break;
default:
/* TODO: do something ... */
break;
}
}
return NULL;
}
/* init poll, structure must be allocated */
int pth_dqtpoll_init(pth_dqtpoll_t *tpoll, int (*jobdata_callback)(void *))
{
int r = 0;
pth_queue_t *queue = malloc(sizeof(pth_queue_t));
pthread_t *poll = malloc(sizeof(pthread_t)*MAX_POLL_VALUE);
idx_allocator_t *idx = malloc(sizeof(idx_allocator_t));
struct __pthrd_data *ndata = malloc(sizeof(struct __pthrd_data));
/* check it for allocation */
if(!ndata) goto __enomem;
if(!idx) goto __enomem;
if(!queue) goto __enomem;
if(!poll) goto __enomem;
/* init all the stuff */
if(idx_allocator_init(idx, MAX_POLL_VALUE*16, 0)) {
__enomem:
r = ENOMEM;
goto __finish;
}
if(pth_queue_init(queue)) goto __enomem; /* init queue */
if(pthread_rwlock_init(&(tpoll->stats_lock), NULL)) goto __enomem;
/* set parameters */
memset(poll, 0, sizeof(pthread_t)*MAX_POLL_VALUE);
tpoll->flags = 0;
tpoll->idx = idx;
tpoll->poll = poll;
tpoll->queue = queue;
tpoll->poll_value = 2;
tpoll->spurious_wakeups = 0;
tpoll->msgop = 0;
tpoll->jobdata_callback = jobdata_callback;
/* first thread initiation */
idx_reserve(idx, 0);
ndata->myid = 0;
ndata->pthrd = tpoll;
if(pthread_create(&(poll[0]), NULL, __poll_thread, ndata)) {
__eadd:
pthread_rwlock_destroy(&(tpoll->stats_lock));
goto __enomem;
}
/* second thread initiation */
ndata = malloc(sizeof(struct __pthrd_data));
if(!ndata) goto __eadd;
idx_reserve(idx, 1);
ndata->myid = 1;
ndata->pthrd = tpoll;
if(pthread_create(&(poll[1]), NULL, __poll_thread, ndata)) {
pthread_rwlock_destroy(&(tpoll->stats_lock));
goto __enomem;
}
gettimeofday(&(tpoll->sched_time), NULL);
__finish:
if(r) {
if(ndata) free(ndata);
if(idx) free(idx);
if(queue) {
pth_queue_destroy(queue, 0, NULL);
free(queue);
}
if(poll) free(poll);
}
return r;
}
/* run poll: poll */
int pth_dqtpoll_run(pth_dqtpoll_t *tpoll)
{
int r = 0;
pthread_rwlock_wrlock(&(tpoll->stats_lock));
if((tpoll->flags & DQTPOLL_RUNNING) || (tpoll->flags & DQTPOLL_DEADSTAGE)) r = EINVAL;
else {
tpoll->flags |= DQTPOLL_RUNNING;
}
pthread_rwlock_unlock(&(tpoll->stats_lock));
return r;
}
/* add the job to the queue: poll, job data, message type */
int pth_dqtpoll_add(pth_dqtpoll_t *tpoll, void *job, unsigned int type)
{
int r = 0;
r = pth_queue_add(tpoll->queue, job, type);
return r;
}
/* destroy the poll: poll, force flag
* if force flag is set (!= 0), give up
* about jobs, if no, do the job, but don't
* accept the new ones, and destroy all poll
* with last thread.
*/
int pth_dqtpoll_destroy(pth_dqtpoll_t *tpoll, int force)
{
int r = 0;
pth_msg_t tmpmsg;
pthread_rwlock_wrlock(&(tpoll->stats_lock));
tpoll->flags |= DQTPOLL_DEADSTAGE;
pthread_rwlock_unlock(&(tpoll->stats_lock));
/* now we need to wait */
while(1) {
pthread_rwlock_rdlock(&(tpoll->stats_lock));
if(!tpoll->poll_value) {
pthread_rwlock_unlock(&(tpoll->stats_lock));
break;
} else {
pthread_rwlock_unlock(&(tpoll->stats_lock));
pth_queue_add(tpoll->queue, &tmpmsg, 0); /* spurious */
}
usleep(100); /* just to sleep and free timeslice to others */
}
/* free all */
pth_queue_destroy(tpoll->queue, 0, NULL);
idx_allocator_destroy(tpoll->idx);
pthread_rwlock_destroy(&(tpoll->stats_lock));
free(tpoll->poll);
free(tpoll->queue);
free(tpoll->idx);
return r;
}

@ -10,29 +10,14 @@
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#ifdef WIN32
#include <Winsock2.h>
#else
#include <sys/select.h>
#include <netdb.h>
#include <unistd.h>
#include <uuid/uuid.h>
#endif
#include <fcntl.h>
#include <openssl/ssl.h>
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/connection.h>
#include <sntl/sntllv2.h>
#include <sntl/limits.h>
static long __cmp_int(const void *a, const void *b)
{

File diff suppressed because it is too large Load Diff

@ -31,14 +31,6 @@
#include <fcntl.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/connection.h>
#ifdef WIN32
#define UUID_T_LENGTH 16
@ -101,25 +93,3 @@ char *__generate_uuid(void)
#endif
}
/* networking helpers */
#ifndef WIN32
int __resolvehost(const char *hostname, char *buf, int buf_len,
struct hostent **rhp)
{
struct hostent *hostbuf ;//= malloc(sizeof(struct hostent));
struct hostent *hp = *rhp = NULL;
int herr = 0, hres = 0;
hostbuf = malloc(sizeof(struct hostent));
if(!hostbuf) return NO_ADDRESS;
hres = gethostbyname_r(hostname, hostbuf,
buf, buf_len, &hp, &herr);
if(hres) return NO_ADDRESS;
*rhp = hp;
return NETDB_SUCCESS;
}
#endif

@ -0,0 +1,3 @@
man_MANS = sxmsg_rreply.3 connections_create.3 connections_init.3 connections_destroy.3 connections_free.3 \
sntl_init.3 connections_setsslserts.3 connections_set_priv.3 connections_get_priv.3 \
connections_set_ondestroy.3

@ -0,0 +1,80 @@
.TH CONNECTIONS_CREATE 3 "20 July 2015" "SNTLLv2" "SNTL Library Manual"
.SH NAME
connections_create \- Allocate and initialize connections system
.br
connections_init \- Initialize connections system
.br
connections_destroy \- Destroy connections system
.br
connections_free \- Free all stuff allocated for connections system
.SH SYNOPSIS
.B #include <sntl/sntllv2.h>
.sp
conn_sys_t *connections_create(void);
int connections_init(conn_sys_t *ssys);
int connections_destroy(conn_sys_t *ssys);
int connections_free(conn_sys_t *ssys);
.br
.sp
.SH DESCRIPTION
.B connections_create
will create a separate connections set used for handling creation and initialization of the connection links.
.B connections_init
will do the same, but it will take an already preallocated pointer.
.br
.B connections_destroy
will deallocate all related to the connections set, include pointer
.BI ssys
, but
.B connections_free
will not free this pointer consider it will be deallocated by user.
.br
.SH RETURN VALUE
Upon successful completion, the function
.B connections_create
will return a valid pointer to the connections set.
.B connections_init
will return
.B 0
.br
Otherwise NULL will be returned and errno will be set, or error will be returned, in case of
.B connections_init
use.
.SH ERRORS
.B connections_init
will return,
.B connection_create will set
.B errno
to:
.br
.B ENOMEM
Not enough memory to allocate all required stuff.
.br
.B EINVAL
Returned if invalid pointer given.
.br
.SH BUGS
Not known yet.
.SH EXAMPLE
None.
.SH APPLICATION USAGE
None.
.SH RATIONALE
Connection link destroy function might be used carefully, the logic of there functions is a
send a special link layer message that will close the connection link on the master side.
The reason to care about is a delivery of all messages, channels and other stuff, because
when this functions called all pending messages are drops.
.SH SEE ALSO
.BI connections_setsslserts(3)
,
.BI sntl_init(3)
.SH COPYRIGHT
This is a proprietary software. See COPYING for further details.
.br
(c) Askele Group 2013-2015 <http://askele.com>
.SH AUTHOR
Alexander Vdolainen (vdo@askele.com)

@ -0,0 +1 @@
connections_create.3

@ -0,0 +1 @@
connections_create.3

@ -0,0 +1 @@
connections_set_priv.3

@ -0,0 +1 @@
connections_create.3

@ -0,0 +1,48 @@
.TH CONNECTIONS_ON_DESTROY 3 "20 July 2015" "SNTLLv2" "SNTL Library Manual"
.SH NAME
connections_on_destroy \- Set callback for the connection links based on the connections set, called in case of link destroying
.br
.SH SYNOPSIS
.B #include <sntl/sntllv2.h>
.sp
#define connections_set_ondestroy(c, f)
.br
.sp
.SH DESCRIPTION
This macro should be used if you want to setup callback function fired upon a connection is closed or broken.
.br
This macro will set on
.B c
connections link set callback
.B f
which is a function pointer of the type:
.br
.sp
.B typedef void (*ondestroy_t)(conn_t *);
.br
.sp
This function will be called if connection link failed, broken etc. It will pass a pointer to the failed connection.
.SH RETURN VALUE
None.
.SH ERRORS
None.
.SH BUGS
None known yet.
.SH EXAMPLE
None.
.SH APPLICATION USAGE
None.
.SH RATIONALE
None.
.SH SEE ALSO
.BI connections_set_priv(3)
,
.BI connections_get_priv(3)
.SH COPYRIGHT
This is a proprietary software. See COPYING for further details.
.br
(c) Askele Group 2013-2015 <http://askele.com>
.SH AUTHOR
Alexander Vdolainen (vdo@askele.com)

@ -0,0 +1,58 @@
.TH CONNECTIONS_SET_PRIV 3 "20 July 2015" "SNTLLv2" "SNTL Library Manual"
.SH NAME
connections_set_priv \- Set a private pointer to the connection links set
.br
connections_get_priv \- Get a private pointer of the connection links set
.br
.SH SYNOPSIS
.B #include <sntl/sntllv2.h>
.sp
#define connections_set_priv(c, p)
.br
#define connections_get_priv(c)
.br
.sp
.SH DESCRIPTION
There macros should be used in case if you want set and get back your private pointer for something.
.br
Pointer is a
.B void*
i.e. it might be anything you pointed in the memory.
.br
.B connections_set_priv
will set a pointer
.B p
to connections set
.B c
.br
.B connections_get_priv
will return your pointer set to
.B c
connection set.
.br
.SH RETURN VALUE
None in case of
.B connections_set_priv
, a private pointer set in case of
.B connections_get_priv
.br
.SH ERRORS
None.
.br
.SH BUGS
None known yet.
.SH EXAMPLE
None.
.SH APPLICATION USAGE
None.
.SH RATIONALE
None.
.SH SEE ALSO
.BI connections_set_ondestroy(3)
.SH COPYRIGHT
This is a proprietary software. See COPYING for further details.
.br
(c) Askele Group 2013-2015 <http://askele.com>
.SH AUTHOR
Alexander Vdolainen (vdo@askele.com)

@ -0,0 +1,63 @@
.TH CONNECTIONS_SETSSLSERTS 3 "20 July 2015" "SNTLLv2" "SNTL Library Manual"
.SH NAME
connections_setsslserts \- Setup root public certificate to check up, and also setups key and public certificate used for connections set
.br
.SH SYNOPSIS
.B #include <sntl/sntllv2.h>
.sp
int connections_setsslserts(conn_sys_t *ssys, const char *rootca,
const char *certpem, const char *certkey);
.br
.sp
.SH DESCRIPTION
.B connections_setsslserts
will setup root public certificate and private key and public certificate used to run connections set.
This is required always, see below for more information.
.br
.sp
This function just set a pathname of the certificates for
.BI ssys
where
.BI rootca
is a pathname to the public X.509 certificate
.BI certpem
is a your own X.509 certificate and
.BI certkey
is a your own key for this certificate. Therefore,
.BI certpem
and
.BI certkey
might be a single file.
.br
.SH RETURN VALUE
Will return 0 on success or errors below.
.br
.SH ERRORS
.B EINVAL
Invalid pointer given.
.br
.B ENOMEM
There are no available memory for operation.
.br
.SH BUGS
None known yet, but name is historically wrong it should be called connections_setsslcerts, btw there are many
code was written with this mistake.
.SH EXAMPLE
None.
.SH APPLICATION USAGE
Call this function *always* before linking a connection. Non master link will always avoid non-root certificate and key,
since you will required to pass it via call.
.SH RATIONALE
None.
.SH SEE ALSO
.BI connection_link(3)
,
.BI connection_link_master(3)
.SH COPYRIGHT
This is a proprietary software. See COPYING for further details.
.br
(c) Askele Group 2013-2015 <http://askele.com>
.SH AUTHOR
Alexander Vdolainen (vdo@askele.com)

@ -0,0 +1,45 @@
.TH SNTL_INIT 3 "20 July 2015" "SNTLLv2" "SNTL Library Manual"
.SH NAME
sntl_init \- Initialize all required globals to run sntl library functions
.br
.SH SYNOPSIS
.B #include <sntl/sntllv2.h>
.sp
int *sntl_init(void);
.br
.sp
.SH DESCRIPTION
.B sntl_init
will initialize all globals required to run sntl related functions, it mostly about
openssl library initialization.
.br
.SH RETURN VALUE
Always returns
.B 0
since we cannot track openssl global initialization routines.
.br
.SH ERRORS
None errors might be returned.
.SH BUGS
None known yet.
.SH EXAMPLE
None.
.SH APPLICATION USAGE
Call this function from the main thread before using sntl library. Otherwise it will not works. There are also
useful to know if you are using other openssl functionality there are no need to initialize globals for it.
.SH RATIONALE
None.
.SH SEE ALSO
.BI connections_create(3)
,
.BI connections_destroy(3)
.SH COPYRIGHT
This is a proprietary software. See COPYING for further details.
.br
(c) Askele Group 2013-2015 <http://askele.com>
.SH AUTHOR
Alexander Vdolainen (vdo@askele.com)

@ -0,0 +1,59 @@
.TH SXMSG_RREPLY 3 "20 July 2015" "SNTLLv2" "SNTL Library Manual"
.SH NAME
sxmsg_rreply \- Function used to send a rapid reply without confirmation
.SH SYNOPSIS
.B #include <sntl/sntllv2.h>
.br
.B #include <sntl/limits.h>
.sp
int sxmsg_rreply(sxmsg_t
.BI *msg
, size_t
.BI datalen
);
.br
.sp
.SH DESCRIPTION
.B sxmsg_rreply
Will reply rapidly to the message using already allocated buffer, which must be
retrieved via
.B sxmsg_rapidbuf().
This function will write desired message as soon
as possible. It will not wait any write or delivery confirmation. It will close
message dialog if message is valid.
.br
.SH RETURN VALUE
Upon successful completion, the function shall rapidly send a message reply and close
the message dialog returning
.B SNE_SUCCESS
Othrewise other error code will be returned.
.SH ERRORS
.B SNE_FAILED
returns if message has invalid index, channel or message pointer is NULL.
.br
.B SNE_ESSL
returns if write was failed i.e. connection link was broken, or SSL error occurs.
.br
.B SNE_SUCCESS
returns on success.
.br
.SH BUGS
Not known yet.
.SH EXAMPLE
.B Reply rapidly from the RPC function call.
.RS
.nf
.if t .ft CW
char *buf = sxmsg_rapidbuf(msg);
int ln = snprintf(buf, MAX_RBBUF_LEN, "(is-done)");
return sxmsg_rreply(msg, str, ln);
.SH APPLICATION USAGE
This function will be useful in RPC functions required to reply ASAP i.e. for getting some data. It RPC function takes a lot of time it's better to use other functions and postponed message processing.
.SH RATIONALE
Use for lightweight RPC functions, this method may be used only in RPC call i.e. within SNTL thread context.
.SH COPYRIGHT
This is a proprietary software. See COPYING for further details.
.br
(c) Askele Group 2013-2015 <http://askele.com>
.SH AUTHOR
Alexander Vdolainen (vdo@askele.com)

@ -0,0 +1,37 @@
## AUTOMAKE_OPTIONS = foreign
AM_CPPFLAGS = \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
-DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \
-DCNFPATH=\""$(prefix)/etc"\" \
-I../include \
-I../lib
AM_CFLAGS = -Wall -g
# where to find libsntl
libsntl = ../lib/.libs/libsntl.la
if !BUILD_WIN32
bin_PROGRAMS = lv2sd lv2sc
lv2sd_SOURCES = lv2sd.c
lv2sd_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsntl)
lv2sc_SOURCES = lv2sc.c
lv2sc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsntl)
else BUILD_WIN32
bin_PROGRAMS = lv2sc
lv2sc_SOURCES = lv2sc.c
lv2sc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsntl) -lws2_32
endif BUILD_WIN32

@ -0,0 +1,30 @@
1. lv2ftp isn's serious, just a test and benchmark of the sntllv2
2. there are few stages:
2.1 Simple v.1
This protocol is enough to donwload a directory subtree with files.
2.1.1 Directory workout
* Open directory stream: (dir-open "<dir-name>")
* Return: error, or rapidly replies with (dir-stream <id>)
* Read directory entry: (dir-read <id>)
* Return: error, or rapidly replies with the following:
* (dir-end <id>)
* (dir-entry "<filename>" "<filetype>"), where filetype the following:
* regular - regular file
* directory - directory
* block - block device
* char - char device
* fifo - named pipe
* link - symbolic link
* socket - socket
* unknown - unknown file type
* Close directory entry: (dir-close <id>)
* Return: error or SNE_SUCCESS
2.1.2 File workout
* Open file: (file-open "<file-name>")
* Return: error, or rapidly replies with (file-id <id>)
* Get simple stat: (file-stat <id>)
* Return error, or rapidle replies with (file-stat <id> <size>)
* Read file data: (file-read <id> <offset>)
* Return error, or rapidly replies with 30k(raw data, in base64 it will be more) (file-data <id> <offset> "<B64encoded data>")
* Close file: (file-close <id>)
* Return error or SNE_SUCCESS

@ -0,0 +1,19 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#include <sntl/sntllv2.h>
int main(int argc, char **argv)
{
return 0;
}

@ -0,0 +1,19 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#include <sntl/sntllv2.h>
int main(int argc, char **argv)
{
return 0;
}

@ -0,0 +1,282 @@
#include <stdio.h>
#define __USE_GNU
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdint.h>
#include <getopt.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#ifdef WIN32
#include <Winsock2.h>
#include <signal.h>
#else
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <netdb.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include <execinfo.h>
#include <netinet/in.h>
#endif
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/sntllv2.h>
#include <sntl/limits.h>
/* define a little bit */
#define DEFAULT_PORT 13133
#define CHANNEL_COUNT 200
#define CLIENT_COUNT 256
#define MESSAGES_PER_SESSION 10000
#define ITERATION_COUNT 1000
#define FAILS_ONLY
struct testdata {
int uc;
pthread_mutex_t ulock;
conn_t *co;
};
static int __init_testdata(struct testdata *t, conn_t *co)
{
t->uc = 0;
pthread_mutex_init(&t->ulock, NULL);
t->co = co;
return 0;
}
static void __wait_completion(struct testdata *t)
{
pthread_mutex_lock(&t->ulock);
if(t->uc) {
pthread_mutex_lock(&t->ulock);
}
return;
}
static int __set_typed_list_callback(conn_t *co, int ch, char *desc)
{
printf("allowed channel %d (%s)\n", ch, desc);
return SNE_SUCCESS;
}
static void *__addsthrd(void *a)
{
struct testdata *t = a;
conn_t *co = t->co;
chnl_t *mch;
sxmsg_t *msg;
char mmbuf[1024];
size_t ln;
int mr, i;
pthread_mutex_lock(&t->ulock);
t->uc++;
pthread_mutex_unlock(&t->ulock);
/* here we go */
mch = sxchannel_open(co, 12);
if(!mch) {
fprintf(stderr, "Failed to openchannel with %d\n", errno);
goto __fini;
}
for(i = 0; i < MESSAGES_PER_SESSION; i++) {
ln = snprintf(mmbuf, 1024, "(ar-add (10 10))");
mr = sxmsg_send(mch, mmbuf, ln, &msg);
switch(mr) {
case SNE_RAPIDMSG:
//fprintf(stdout, "Rapidly replied: %s\n", (char *)sxmsg_payload(msg));
sxmsg_clean(msg);
break;
case SNE_REPLYREQ:
if(sxmsg_datalen(msg)) fprintf(stdout, "Replied (confirmation required): %s\n",
(char *)sxmsg_payload(msg));
mr = sxmsg_return(msg, SNE_SUCCESS);
fprintf(stderr, "mr = %d\n", mr);
break;
case SNE_SUCCESS:
fprintf(stdout, "Success.\n");
break;
default:
fprintf(stderr, "ERROR: %d\n", mr);
break;
}
}
sxchannel_close(mch);
__fini:
t->uc--;
if(t->uc <= 1) pthread_mutex_unlock(&t->ulock);
return NULL;
}
int main(int argc, char **argv)
{
char *rootca = NULL, *cert = NULL;
int port = DEFAULT_PORT;
char *addr = NULL, *login = NULL, *password = NULL;
int opt;
conn_sys_t *ssys;
conn_t *co;
while((opt = getopt(argc, argv, "p:r:a:u:l:w:")) != -1) {
switch(opt) {
case 'p':
port = atoi(optarg);
break;
case 'r':
rootca = strdup(optarg);
break;
case 'a':
addr = strdup(optarg);
break;
case 'u':
cert = strdup(optarg);
break;
case 'l':
login = strdup(optarg);
break;
case 'w':
password = strdup(optarg);
break;
default:
fprintf(stderr, "usage: %s [-p <PORTNUM>] -r <PATH to Root CA> -a <Server ip address> -u <PATH"
" to SSL certificate> -l <User login> -w <User password>\n", argv[0]);
return EINVAL;
}
}
if(!rootca) {
fprintf(stderr, "Root CA not pointed.\n Failure.\n");
return EINVAL;
}
if(!addr) {
fprintf(stderr, "Server address not pointed.\n Failure.\n");
return EINVAL;
}
if(!cert) {
fprintf(stderr, "User certificate not pointed.\n Failure.\n");
return EINVAL;
}
if(!login) {
fprintf(stderr, "User login not pointed.\n Failure.\n");
return EINVAL;
}
if(!password) {
fprintf(stderr, "User password not pointed.\n Failure.\n");
return EINVAL;
}
sntl_init();
/* all is fine let's init connection subsystem */
ssys = connections_create();
if(!ssys) {
fprintf(stderr, "Subsystem init failed: %d\n", errno);
return errno;
}
/* set working certificates */
opt = connections_setsslserts(ssys, rootca, cert, cert);
if(opt) {
fprintf(stderr, "Subsystem init failed (set SSL x.509 pems): %d\n", opt);
return opt;
}
/* Tests */
struct timeval beg, end;
/* try to open connection */
connections_set_channelcall(ssys, __set_typed_list_callback);
gettimeofday(&beg, NULL);
co = connection_link(ssys, addr, port, cert, login, password);
if(!co) {
fprintf(stderr, "Failed to connection with %d\n", errno);
return errno;
}
gettimeofday(&end, NULL);
if((end.tv_sec - beg.tv_sec) > 0) {
printf("Seconds: %ld ", end.tv_sec - beg.tv_sec);
printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec));
} else printf("µS: %ld\n", end.tv_usec - beg.tv_usec);
/* ok now we should open a channel */
chnl_t *testchannel = sxchannel_open(co, 12);
if(!testchannel) {
fprintf(stderr, "Failed to openchannel with %d\n", errno);
return errno;
}
gettimeofday(&end, NULL);
if((end.tv_sec - beg.tv_sec) > 0) {
printf("Seconds: %ld ", end.tv_sec - beg.tv_sec);
printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec));
} else printf("µS: %ld\n", end.tv_usec - beg.tv_usec);
/* ok, send a message */
char mmbuf[1024];
sxmsg_t *msg;
size_t ln;
ln = snprintf(mmbuf, 1024, "(ar-add (10 10))");
int mr = sxmsg_send(testchannel, mmbuf, ln, &msg);
switch(mr) {
case SNE_RAPIDMSG:
fprintf(stdout, "Rapidly replied: %s\n", (char *)sxmsg_payload(msg));
sxmsg_clean(msg);
break;
case SNE_REPLYREQ:
if(sxmsg_datalen(msg)) fprintf(stdout, "Replied (confirmation required): %s\n",
(char *)sxmsg_payload(msg));
mr = sxmsg_return(msg, SNE_SUCCESS);
fprintf(stderr, "mr = %d\n", mr);
break;
case SNE_SUCCESS:
fprintf(stdout, "Success.\n");
break;
default:
fprintf(stderr, "ERROR: %d\n", mr);
break;
}
int ee = sxchannel_close(testchannel);
printf("ee = %d\n", ee);
gettimeofday(&end, NULL);
if((end.tv_sec - beg.tv_sec) > 0) {
printf("Seconds: %ld ", end.tv_sec - beg.tv_sec);
printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec));
} else printf("µS: %ld\n", end.tv_usec - beg.tv_usec);
sleep(10);
/* ok, now we need to create many threads */
struct testdata trd;
pthread_t thrd;
int i;
__init_testdata(&trd, co);
for(i = 0; i < 256; i++) pthread_create(&thrd, NULL, __addsthrd, &trd);
__wait_completion(&trd);
connection_close(co);
return 0;
}

@ -0,0 +1,276 @@
/*
* Secure Network Transport Layer Library v2 implementation.
* (sntllv2) it superseed all versions before due to the:
* - memory consumption
* - new features such as pulse emitting
* - performance optimization
*
* This is a proprietary software. See COPYING for further details.
*
* (c) Askele Group 2013-2015 <http://askele.com>
*
*/
#include <stdio.h>
#define __USE_GNU
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#ifdef WIN32
#include <Winsock2.h>
#include <signal.h>
#include <ws2tcpip.h>
#else
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <netdb.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include <execinfo.h>
#include <netinet/in.h>
#endif
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/limits.h>
#include <sntl/sntllv2.h>
#include <pthread.h>
// #include <unistd.h>
#include <stdint.h>
#include <getopt.h>
#include <errno.h>
/* helper functions */
int __openlistener(int port)
{
int sd;
struct sockaddr_in addr;
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 ) {
perror("can't bind port");
abort();
}
if ( listen(sd, 10) != 0 ) {
perror("Can't configure listening port");
abort();
}
return sd;
}
/*
* Validation of the SSL certificate
* this function must be exist.
*/
static int __validate_sslpem(conn_t *co)
{
return 0;
}
/*
* validate - authorize user with password
*/
static int __secure_check(conn_t *co)
{
return SNE_SUCCESS;
}
/*
* typed list callback
*/
static int __set_typed_list_callback(conn_t *co, int ch, char *desc)
{
printf("allowed channel %d (%s)\n", ch, desc);
return SNE_SUCCESS;
}
/* list of rpc calls functions */
usrtc_t *fulist;
/* our fake */
usrtc_t *__rettlist(conn_t *c)
{
return fulist;
}
/* RPC functions implementation */
static int __ar_add(void *m, sexp_t *sx)
{
sexp_t *lsx = NULL, *sx_iter;
sxmsg_t *msg = (sxmsg_t *)m;
char *buf;
int idx;
size_t ln = 0;
if(sexp_list_cdr(sx, &lsx)) {
printf("Invalid protocol\n");
return sxmsg_return(msg, SNE_BADPROTO);
}
long int sum = 0;
SEXP_ITERATE_LIST(lsx, sx_iter, idx) {
if(!SEXP_IS_TYPE(sx_iter, SEXP_BASIC)) {
fprintf(stderr, "Invalid value type\n");
return sxmsg_return(msg, SNE_BADPROTO);
}
sum += atoi(sx_iter->val);
}
buf = sxmsg_rapidbuf(msg);
ln = snprintf(buf, MAX_RBBUF_LEN, "(add-result %ld)", sum);
return sxmsg_rreply(msg, ln);
}
static int __ar_multiply(void *data, sexp_t *sx)
{
sexp_t *lsx = NULL;
sxmsg_t *msg = (sxmsg_t *)data;
char *buf;
int idx;
sexp_t *sx_iter;
size_t ln;
if(sexp_list_cdr(sx, &lsx)) {
printf("Invalid protocol\n");
return sxmsg_return(msg, SNE_BADPROTO);
}
long int mult = 0;
SEXP_ITERATE_LIST(lsx, sx_iter, idx) {
if(!SEXP_IS_TYPE(sx_iter, SEXP_BASIC)) {
printf("Invalid value type\n");
return sxmsg_return(msg, SNE_BADPROTO);
}
mult *= atoi(sx_iter->val);
}
buf = sxmsg_rapidbuf(msg);
ln = snprintf(buf, MAX_RBBUF_LEN, "(multiply-result %ld)", mult);
return sxmsg_rreply(msg, ln);
}
/* define a little bit */
#define DEFAULT_PORT 13133
static void sigpipe_handler(int a)
{
return;
}
int main(int argc, char **argv)
{
char *rootca = NULL, *cert = NULL;
conn_sys_t *ssys = connections_create();
int port = DEFAULT_PORT;
int opt;
signal(SIGPIPE, SIG_IGN);
while((opt = getopt(argc, argv, "p:r:u:")) != -1) {
switch(opt) {
case 'p':
port = atoi(optarg);
break;
case 'r':
rootca = strdup(optarg);
break;
case 'u':
cert = strdup(optarg);
break;
default:
fprintf(stderr, "usage: %s [-p <PORTNUM>] -r <PATH to Root CA> -u <PATH"
" to SSL certificate>\n", argv[0]);
return EINVAL;
}
}
if(!rootca) {
fprintf(stderr, "Root CA not pointed.\n Failure.\n");
return EINVAL;
}
if(!cert) {
fprintf(stderr, "User certificate not pointed.\n Failure.\n");
return EINVAL;
}
sntl_init();
/* all is fine let's init connection subsystem */
if(!ssys) {
fprintf(stderr, "Subsystem init failed: %d\n", opt);
return 2;
}
/* set wroking certificates */
opt = connections_setsslserts(ssys, rootca, cert, cert);
if(opt) {
fprintf(stderr, "Subsystem init failed (set SSL x.509 pems): %d\n", opt);
return opt;
}
/* clean up */
free(rootca);
free(cert);
/* set important callbacks to do the security checking */
connections_set_authcheck(ssys, __secure_check);
connections_set_sslvalidate(ssys, __validate_sslpem);
/* set a callback, it's optional and doesn't required in server side apps */
connections_set_channelcall(ssys, __set_typed_list_callback);
/* ok, now we need to construct RPC lists (channels) */
if(!(fulist = malloc(sizeof(usrtc_t)))) {
fprintf(stderr, "Cannot allocate memory for RPC lists\n Failure.\n");
return ENOMEM;
}
opt = sntl_rpclist_init(fulist);
if(opt) {
fprintf(stderr, "Failed to init rpc list\n Failure.\n");
return opt;
}
/* we will add one channel with type id 12 "Demo rpc list" */
opt = sntl_rpclist_add(fulist, 12, "Demo RPC list", NULL);
if(opt) {
fprintf(stderr, "Failed to add typed RPC channel\n Failure.\n");
return opt;
}
/* ok, let's add two functions */
opt = sntl_rpclist_add_function(fulist, 12, "ar-add", __ar_add);
if(opt) {
__fail:
fprintf(stderr, "Failed to add functions to typed RPC channel\n Failure.\n");
return opt;
}
opt = sntl_rpclist_add_function(fulist, 12, "ar-multiply", __ar_multiply);
if(opt) goto __fail;
/* ok, setup it */
connections_set_rpcvalidator(ssys, __rettlist);
/* now we're ready to run the listen process */
int srv = __openlistener(port);
while(1) {
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
conn_t *co;
int client = accept(srv, (struct sockaddr*)&addr, &len); /* accept connection as usual */
co = connection_master_link(ssys, client, NULL); /* create connection, that's all */
if(!co) {
fprintf(stderr, "Cannot create connetion (%d)\n", opt);
}
}
return 0;
}
Loading…
Cancel
Save